如题所示,SparkSQL /DataFrame /Spark RDD谁快?

按照官方宣传以及大部分人的理解,SparkSQL和DataFrame虽然基于RDD,但是由于对RDD做了优化,所以性能会优于RDD。

之前一直也是这么理解和操作的,直到最近遇到了一个场景,打破了这种不太准确的认识。

某些场景下,RDD要比DataFrame快,性能有天壤之别。

需求如下

以下两份数据求交集,结果输出url。

数据一,json格式,地址我们用path_json表示,大小10T,每一行数据格式:{"id":"md5字符串", "url":"https://www.thesaurus.com/","title":"sysnonyms and antonyms",xxx},大概20来个字段;

数据二,csv格式,地址我们用path_csv表示,大小50G,每一行数据格式:name url,2个字段,用\t隔开。

拿到需求后,迅速瞟了一眼数据,爽快答应需求方分分钟搞定。

此时此刻,必须得祭出宇宙Top N的IDE,结合我30多年的人生阅历和代码经验,瞬间雷光电扇,惊雷骤起,一顿操作猛如虎,天空飘过以下几行代码:

(老铁们,请自行安装python,pyspark,pycharm)

方案一


from pyspark.sql import SparkSession
def join_it():
path_json = 'hdfs://i/love/you/' # 数据大小10T, 5万分区
path_csv = 'hdfs://you/love/me' # 数据大小50G
path_save = 'hdfs://we/are/together' df1 = spark.read.json(path_json).select('url')
df2 = spark.read.option('sep', '\t').schema('name string, url string').csv(path_csv)
df1.join(df2) \
.select(df1.url)\
.coalesce(10000) \
.write \
.mode('overwrite') \
.option('sep', '\t') \
.csv(path_save) if __name__ == '__main__':
spark = SparkSession.builder.appName('pyspark').getOrCreate()
sc = spark.sparkContext
sc.setLogLevel("ERROR")
#
join_it()
#
spark.stop()

spark-submit提交任务到spark集群,参数根据自己的实际情况自行修改。

spark-submit \
--master yarn \
--deploy-mode client \
--name 'i-live-you' \
--queue 'you-love-me' \
--driver-cores \
--driver-memory 30g \
--num-executors \
--executor-memory 30g \
--executor-cores \
--archives 'hdfs://your-python-path-on-hdfs#pkg'
--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON='集群里面的python地址' \
--conf spark.sql.shuffle.partitions= \
--conf spark.default.parallelism= \
--conf spark.task.maxFailures= \
your-spark-script.py

如果需要在本机调试代码,spark的生成需要替换成如下,然后直接运行。调试通过后,仍然需要按照上述方式spark-submit提交任务到集群运行,由于数据量很大,需要在集群运行才能看出性能差异。

spark = SparkSession.builder.appName('pyspark').master('local[*]').getOrCreate()

又是一顿猛操作,提交任务后,嗡嗡叫的肚子提醒我,要去厕所烧一根香,拜拜佛,佛祖保佑无bug。

深圳的夏天,依旧不负众望的燥热。热情似火的太阳,伴着她最爱的紫外线和电磁波,循着外太空固定的轨道,迈着30万公里/秒的矫健步伐,到达这颗承载70亿人的蓝色星球,穿透层层蓝天白云,无私的照亮着广袤的深圳大地。

酷暑让人思想活跃,思绪万千。扯得有点远了,重来不重来了,接着写bug。

作为一个谨记厕所文化的人,蹲坑5分钟,方便你我他;蹲坑半小时,痔疮等着你。我选择了后者。

半小时过去了,时间随着大A股的大跌,瞬间来到了下午的收盘时间。果不其然,又一个下跌如期而至,就在这一刻,体内的混浊之气伴着伴随着收跌的股市排出体外。收拾干净后,我带着满身厕所的芬芳,回到了座位上。

再次打开电脑屏幕,spark任务还在慢悠悠的读取json文件,半小时才读取300G左右,10T的json文件按照这个速度,全部读完的好几天。此方案不可用。

方案二

果断改成RDD,然后用intersection求交集,果然快很多,10T跟50G求交集,12000cores,5分钟出结果。Spark任务提交同方案一,不再赘述。此方案可行

屁颠屁颠的把结果交付给需求方,大佬甚是满意地流出了开心的泪水

import json
from pyspark.sql import SparkSession def join_it():
path_json = 'hdfs://i/love/you/' # 数据大小10T, 5万分区
path_csv = 'hdfs://you/love/me' # 数据大小50G
path_save = 'hdfs://we/are/together'
#
rdd1 = sc.textFile(path_json).map(lambda v: json.loads(v).get('url', '')).coalesce(50000)
rdd2 = sc.textFile(path_csv).map(lambda v: v.split('\t')[1])
rdd1.intersection(rdd2).coalesce(20000).saveAsTextFile(path_save) if __name__ == '__main__':
spark = SparkSession.builder.appName('pyspark').getOrCreate()
sc = spark.sparkContext
sc.setLogLevel("ERROR")
#
join_it()
#
spark.stop()

方案三

离下班实际还有30分钟,作为一个对技术有追求的资深码农,尝试用SparkSQL实现该功能。祭出代码,以资各位看官共享,新能跟RDD不相上下。此方案也可取。

import json
from pyspark.sql import SparkSession def join_it():
path_json = 'hdfs://i/love/you/' # 数据大小10T, 5万分区
path_csv = 'hdfs://you/love/me' # 数据大小50G
path_save = 'hdfs://we/are/together'
#
sc.textFile(path_json).map(lambda v: (json.loads(v).get('url', ''),)).toDF(['url']).createOrReplaceTempView('a')
spark.read.option('sep', '\t').schema('name string, url string').csv(path_csv).createOrReplaceTempView('b') sql = '''
SELECT
a.url
FROM
a
JOIN
b
ON
a.url=b.url
'''
spark.sql(sql).coalesce(20000).write.mode('overwrite').option('sep', '\t').csv(path_save) if __name__ == '__main__':
spark = SparkSession.builder.appName('pyspark').getOrCreate()
sc = spark.sparkContext
sc.setLogLevel("ERROR")
#
join_it()
#
spark.stop()

总结:

当遇到源数据是体量比较大的json或其他格式的时候,不要用spark.read的形式直接导入到DataFrame。

那要咋弄?可以先用RDD把源数据加载进来,然后再转化成DataFrame,后面用SparkSQL进行操作,如此可达到较好的性能效果。

SparkSQL /DataFrame /Spark RDD谁快?的更多相关文章

  1. spark RDD,DataFrame,DataSet 介绍

    弹性分布式数据集(Resilient Distributed Dataset,RDD) RDD是Spark一开始就提供的主要API,从根本上来说,一个RDD就是你的数据的一个不可变的分布式元素集合,在 ...

  2. Spark大型电商项目实战-及其改良(1) 比对sparkSQL和纯RDD实现的结果

    代码存在码云:https://coding.net/u/funcfans/p/sparkProject/git 代码主要学习https://blog.csdn.net/u012318074/artic ...

  3. Spark RDD、DataFrame原理及操作详解

    RDD是什么? RDD (resilientdistributed dataset),指的是一个只读的,可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,在多次计算间重用. RDD内部可以 ...

  4. [Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子

    [Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子 from pyspark.sql.types import * schema = Struct ...

  5. [Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子

    [Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子 $ hdfs dfs -cat people.json {"name":&quo ...

  6. Spark RDD、DataFrame和DataSet的区别

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   转载请标明出处:小帆的帆的专栏 RDD 优点: 编译时类型安全 编译时就能检查出类型错误 面向对象的编程风格 直接通过类 ...

  7. Spark SQL概念学习系列之DataFrame与RDD的区别

    不多说,直接上干货! DataFrame的推出,让Spark具备了处理大规模结构化数据的能力,不仅比原有的RDD转化方式更加简单易用,而且获得了更高的计算性能.Spark能够轻松实现从MySQL到Da ...

  8. Spark的dataframe转rdd通用工具类

    需求解决问题 当每次读取hive表或者其他数据源,获取数据,相对其进行rdd操作,遇到任何类都需要df.rdd(row>row.getstring(0))去获取,就很麻烦,所以可以实现个通用的转 ...

  9. 【Spark-SQL学习之二】 SparkSQL DataFrame创建和储存

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...

随机推荐

  1. 大型Java进阶专题(八)设计模式之适配器模式、装饰者模式和观察者模式

    前言 ​ 今天开始我们专题的第八课了.本章节将介绍:三个设计模式,适配器模式.装饰者模式和观察者模式.通过学习适配器模式,可以优雅的解决代码功能的兼容问题.另外有重构需求的人群一定需要掌握装饰者模式. ...

  2. 使用SQL语句建表,插入数据

    --选中数据库,点击新建查询,然后执行即可--这是SQL中的注释信息,使用两个减号来注释. drop table Book --删除表Book create table Book --创建表Book ...

  3. Java程序斗地主发牌代码,List、Map集合的应用

    Java集合存储的灵活运用List集合存储 54个编号 Map <key,value> key 对应的是编号 , value 是 牌的花色(红方梅黑)+ 具体的一张牌 ,比如 黑桃2 用2 ...

  4. git常用命令操作

    git常用命令 #查看配置 git config -l #查看系统config git config --system --list #查看当前用户(global)配置 git config --gl ...

  5. Microsoft Cloud App Security 微软的云应用安全

    1.概述 微软2015年收购的一家云安全创业公司 Adallom 正式推出产品,同时更名为微软 Cloud App Security.Adallom 成立于 2012年,是一家 SaaS 云安全公司, ...

  6. spring 循环依赖的一次 理解

    前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...

  7. 2-Numpy之hstack、vstack、concatenate区别

    concatenate与hstack.vstack的异同点: 都表示拼接数组,concatenate可以实现hstack和vstack的功能,只需要通过调整参数axis的值即可. 其中:v表示垂直(V ...

  8. PHP cal_from_jd() 函数

    ------------恢复内容开始------------ 实例 把儒略日计数转换为格利高里历法的日期: <?php$d=unixtojd(mktime(0,0,0,6,20,2007));p ...

  9. PHP frenchtojd() 函数

    ------------恢复内容开始------------ 实例 把法国共和历法的日期转换为儒略日计数,然后再转换回法国共和历法的日期: <?php$jd=frenchtojd(3,3,14) ...

  10. PHP preg_match_all() 函数

    preg_match_all 函数用于执行一个全局正则表达式匹配.高佣联盟 www.cgewang.com 语法 int preg_match_all ( string $pattern , stri ...