你好,游客 登录
背景:
阅读新闻

如何理解spark中RDD和DataFrame的结构?

[日期:2018-04-26] 来源:知乎  作者: [字体: ]

Spark RDD是分布式弹性数据集,一个比较核心的是粗粒度的分布式计算,粗粒度是指用户不用关心太多的分布式细节,用声明式的API就能完成分布式计算,比如Word Count用一行就能写完。RDD易用性很好,那Spark为啥还要有Dataframe呢?
DataFrame的从API上借鉴了R和pandas的DataFRame的概念,是业界标准结化数据处理API。DataFrame的数据抽象是命名元组,代码里是Row类型,Dataframe结合了过程化编程和声名式的API,让用户能用过程化编程的方法处理结构化数据。
Dataframe比RDD多了限制,带来了更多的优化,基于Spark Catalyst优化器,提供如列裁剪,谓词下推,map join等优化。同时,采用code generation ,动态编译表达式,提升性能,比用rdd的自定义函数性能高5倍左右。
举个例子,
rdd.map(lambda line: line.split("\t"))
   .map(lambda items: (items[0], items[1], items[2], items[3]))
   .filter(lambda items: int(items[2]) >= 19)
   .select(lambda items: (items[0], items[1]))
sqlContext.table("people")
        .filter(col("age") >= 19)
        .select("id", "name")

用rdd读结构化文本要用map函数,需要按位置获取数据,没有schema,性能和可读性都不好。
而用dataframe可以直接通过sede读取结构化数据,性能比RDD高2到3倍左右,比MR高5倍左右,同时,具有结构化的数据,可读性更好。
DataFrame具有很好的易用性,支持多种语言,在一个上下文可以写udf,具有部署一致性,以前写HQL Transform的用户可以试试Dataframe,在复杂统计分析中,有dataframe可以过程化编程,模块化会更好,可读性强。
Dataframe可以用df.rdd等方式转化为RDD,处理更多灵活的操作。

Spark2.0推出DataSet,是更加强类型的API,用了scala的泛型,能在编译是发现更多的编译问题DataFrame是DataSet〈Row〉类型,DS在接口上和DataFrame很相似。感觉是为了和structured streaming 统一做铺垫。

另外,看到Apache Beam这个google的开源项目正在用flume java的API统一google cloud api ,spark和flink这个和bigflow很像。

从用过dataframe的同事反馈,dataframe的易用性、性能都挺好。
 
 
 
 
spark 1.6又引入了dateset的概念,这三者的特点如下:

rdd的优点:
1.强大,内置很多函数操作,group,map,filter等,方便处理结构化或非结构化数据
2.面向对象编程,直接存储的java对象,类型转化也安全
rdd的缺点:
1.由于它基本和hadoop一样万能的,因此没有针对特殊场景的优化,比如对于结构化数据处理相对于sql来比非常麻烦
2.默认采用的是java序列号方式,序列化结果比较大,而且数据存储在java堆内存中,导致gc比较频繁

dataframe的优点:
1.结构化数据处理非常方便,支持Avro, CSV, elastic search, and Cassandra等kv数据,也支持HIVE tables, MySQL等传统数据表
2.有针对性的优化,由于数据结构元信息spark已经保存,序列化时不需要带上元信息,大大的减少了序列化大小,而且数据保存在堆外内存中,减少了gc次数。
3.hive兼容,支持hql,udf等
dataframe的缺点:
1.编译时不能类型转化安全检查,运行时才能确定是否有问题
2.对于对象支持不友好,rdd内部数据直接以java对象存储,dataframe内存存储的是row对象而不能是自定义对象

dataset的优点:
1.dataset整合了rdd和dataframe的优点,支持结构化和非结构化数据
2.和rdd一样,支持自定义对象存储
3.和dataframe一样,支持结构化数据的sql查询
4.采用堆外内存存储,gc友好
5.类型转化安全,代码友好
6.官方建议使用dataset
收藏 推荐 打印 | 阅读: