将代码从 spark 1.x 移植到 spark 2.x

1. SparkSession

sparkSession可以视为sqlContexthiveContext以及StreamingContext的结合体,这些Context的API都可以通过sparkSession使用。

创建SparkSession

val spark = SparkSession.builder
    .master("local[2]")
    .appName("spark session example")
    .getOrCreate()

使用enableHiveSupport就能够支持hive,相当于hiveContext

val spark = SparkSession.builder
    .master("local[2]")
    .appName("spark session example")
    .enableHiveSupport()
    .getOrCreate()

API操作,与之前的Context基本一致

//读取csv数据
val df0 = spark.read
  .option("header","true")
  .csv("src/main/resources/test.csv")

//读取parquet数据
val df1 = spark.read.parquet("...")

//读取json数据
val df2 = spark.read.json("...")

//sql查询
val df3 = spark.sql("xxx")

Spark 2.0向后兼容,所以hiveContext以及sqlContext依旧可用,不过官方建议开发者开始使用SparkSession

2. DataSet,RDD,DataFrame

  • RDD

    类型安全,面向对象编程风格,序列化以及反序列化开销大。

  • DataFrame

    提供了查询优化器,分区剪枝,自动判断是否使用broadcast join等功能,对rdd进行了大量的优化。对spark了解不深的编程/分析人员非常友好。

    可以视为Row类型的Dataset (Dataset[Row]),非类型安全,不是面向对象编程风格。

  • DataSet

    继承了RDD和DataFrame的优点。数据以编码的二进制形式存储,将对象的schema映射为SparkSQL类型,不需要反序列化就可以进行shuffle等操作,每条记录存储的则是强类型值,类型安全,面向对象编程风格。

Dataset的创建

dataset可以从rdd,dataFrame转化,也可以从原始数据直接生成。

通过toDS方法创建

val ds1 = Seq("a","b").toDS()
ds1.show

//+-----+
//|value|
//+-----+
//|    a|
//|    b|
//+-----+

通过createDataSet创建

case class Person(name: String, age: Int)
val data = Seq(Person("lsw", 23), Person("yyy", 22))
val ds2 = spark.createDataset(data)
ds2.show

//+----+---+
//|name|age|
//+----+---+
//| lsw| 23|
//| yyy| 22|
//+----+---+

DataSet与RDD使用上的区别

Dataset 结合了 rdd 和 DataFrame 上大多数的API,所以spark 1.x基于 rdd 或 DataFrame 的代码可以很容易的改写成spark 2.x版本

  1. 数据读取

    RDDs

    sparkContext.textFile("/path/to/data.txt")
    

    Datasets

    //返回 DataFrame
    val df = spark.read.text("/path/to/data.txt")
    //返回 DataSet[String]
    val ds1 = spark.read.textFile("/path/to/data.txt")
    //或者读取成DataFram再转化成Dataset
    val ds2 = spark.read.text("/path/to/data.txt").as[String]
    
  2. 常用API

    RDDs

    //flatMap,filter
    val lines = sc.textFile("/path/to/data.txt")
    val res = lines
      .flatMap(_.split(" "))
      .filter(_ != "")
    
    //reduce
    val rdd = sc.makeRDD(Seq(1, 2, 3, 4))
    rdd.reduce((a, b) => a + b)
    

    Datasets

    //flatMap,filter
    val lines = spark.read.textFile("/path/to/data.txt")
    val res = lines
      .flatMap(_.split(" "))
      .filter(_ != "")
    
    //reduce
    val ds = Seq(1, 2, 3, 4).toDs
    ds.reduce((a, b) => a + b)
    
  3. reduceByKey

    RDDs

    val reduceCountByRDD = wordsPair
      .reduceByKey(_+_)
    

    Datasets

    val reduceCountByDs = wordsPairDs
      .mapGroups((key,values) =>(key,values.length))
    
  4. RDD,DataFrame,Dataset的相互转化

    import spark.implicits._
    //Dataset转化为RDD
    val ds2rdd = ds.rdd
    //Dataset转为DataFrame
    val ds2df = ds.toDF
    
    //RDD转化为Dataset
    val rdd2ds = rdd.toDS
    //RDD转化为DataFrame
    val rdd2df = rdd.toDF
    
    //DataFrame转化为RDD
    val df2rdd = df.rdd
    //DataFrame转化为DataSet
    val df2ds = df.as[Type]
    
    
  5. wordCount

    data.txt

    hello world
    hello spark
    

    RDDs

    val rdd = sc.textFile("src/main/resources/data.txt")
    val wordCount = rdd
      .map(word => (word,1))
      .reduceByKey(_+_)
    

    Datasets

    import spark.implicits._
    val wordCount1 = lines
      .flatMap(r => r.split(" "))
      .groupByKey(r => r)
      .mapGroups((k, v) => (k, v.length))
    wordCount1.show
    //  +-----+--------+
    //  |value|count(1)| 
    //  +-----+--------+
    //  |hello|       2|
    //  |spark|       1|
    //  |world|       1|
    //  +-----+--------+
      
    //也可以直接使用count函数
    val wordCount2 = lines
      .flatMap(r => r.split(" "))
      .groupByKey(v => v)
      .count()
    wordCount2.show
    //  +-----+---+
    //  |   _1| _2|
    //  +-----+---+
    //  |hello|  2|
    //  |spark|  1|
    //  |world|  1|
    //  +-----+---+
    

Dataset性能提升(来自官方)

这里写图片描述

这里写图片描述

这里写图片描述

3.Catalog

Spark 2.0中添加了标准的API(称为catalog)来访问Spark SQL中的元数据。这个API既可以操作Spark SQL,也可以操作Hive元数据。

获取catalog

从SparkSession中获取catalog

val catalog = spark.catalog

查询临时表和元数据中的表

返回Dataset[Table]

catalog.listTable.show
//  +----+--------+-----------+---------+-----------+
//  |name|database|description|tableType|isTemporary|
//  +----+--------+-----------+---------+-----------+
//  |table|   null|      null|TEMPORARY|        true|
//  |act | default|      null| EXTERNAL|       false|
//  +----+--------+-----------+---------+-----------+

创建临时表

使用createTempViewcreateOrReplaceTempView取代registerTempTable

例如

df.createTempView("table")
df.createOrReplaceTempView("table")
  • createTempView

    创建临时表,如果已存在同名表则报错。

  • createOrReplaceTempView

    创建临时表,如果存在则进行替换,与老版本的registerTempTable功能相同。

销毁临时表

使用dropTempView取代dropTempTable,销毁临时表的同事会清除缓存的数据。

spark.dropTempView("table")

缓存表

对数据进行缓存

//缓存表有两种方式
df.cache
catalog.cacheTable("table")

//判断数据是否缓存
catalog.isCached("table")

catalog相较于之前的API,对metadata的操作更加的简单,直观。

参考

http://blog.madhukaraphatak.com/categories/spark-two/
http://www.jianshu.com/p/c0181667daa0
https://databricks.com/blog/2016/01/04/introducing-apache-spark-datasets.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容