SparkSQL /DataFrame /Spark RDD谁快?
如题所示,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谁快?的更多相关文章
- spark RDD,DataFrame,DataSet 介绍
弹性分布式数据集(Resilient Distributed Dataset,RDD) RDD是Spark一开始就提供的主要API,从根本上来说,一个RDD就是你的数据的一个不可变的分布式元素集合,在 ...
- Spark大型电商项目实战-及其改良(1) 比对sparkSQL和纯RDD实现的结果
代码存在码云:https://coding.net/u/funcfans/p/sparkProject/git 代码主要学习https://blog.csdn.net/u012318074/artic ...
- Spark RDD、DataFrame原理及操作详解
RDD是什么? RDD (resilientdistributed dataset),指的是一个只读的,可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,在多次计算间重用. RDD内部可以 ...
- [Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子
[Spark][Python][RDD][DataFrame]从 RDD 构造 DataFrame 例子 from pyspark.sql.types import * schema = Struct ...
- [Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子
[Spark][Python][DataFrame][RDD]从DataFrame得到RDD的例子 $ hdfs dfs -cat people.json {"name":&quo ...
- Spark RDD、DataFrame和DataSet的区别
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 转载请标明出处:小帆的帆的专栏 RDD 优点: 编译时类型安全 编译时就能检查出类型错误 面向对象的编程风格 直接通过类 ...
- Spark SQL概念学习系列之DataFrame与RDD的区别
不多说,直接上干货! DataFrame的推出,让Spark具备了处理大规模结构化数据的能力,不仅比原有的RDD转化方式更加简单易用,而且获得了更高的计算性能.Spark能够轻松实现从MySQL到Da ...
- Spark的dataframe转rdd通用工具类
需求解决问题 当每次读取hive表或者其他数据源,获取数据,相对其进行rdd操作,遇到任何类都需要df.rdd(row>row.getstring(0))去获取,就很麻烦,所以可以实现个通用的转 ...
- 【Spark-SQL学习之二】 SparkSQL DataFrame创建和储存
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...
随机推荐
- 如何证明sleep不释放锁,而wait释放锁?
wait 加锁示例 public class WaitDemo { private static Object locker = new Object(); public static void ma ...
- 组件缓存注意事项 ---keep-alive
- docker-compose安装zabbix
在网上的很多帖子,我亲自试过,多数不行,启动后zabbix_server是退出状态,所以觉得自己亲自写一篇帖子,以作记录 1.安装docker和docker-compose yum install - ...
- shell变量子串
表达式 说明 ${parameter} 返回变量$parameter的内容 ${#parameter} 返回变量$parameter内容的长度(按字符),也适用于特殊变量 ${parameter:of ...
- dp入门例题(1)
按摩师问题 https://leetcode-cn.com/problems/the-masseuse-lcci/ (找好状态转移方程) 今天只和昨天的状态相关,依然是分类讨论: 今天不接受预约:或者 ...
- 第一章 Java快速入门
1.1.安装开发环境 第一步:打开下载地址,下载对应平台的 JDK 安装包 第二步:打开下载软件,全部默认下一步傻瓜式安装 1.2.配置环境变量 第一步:配置JAVA_HOME 第二步:配置CLASS ...
- 记node,elementui,formidable上传图片
卡了很久甚至心态爆炸,搞了半天才能成功上传图片,结果图片上传的位置也有问题.头大 https://www.jianshu.com/p/3a61318c24d1 先是参考这个来弄好大致的部署. 然后中途 ...
- matplotlib基础汇总_01
灰度化处理就是将一幅色彩图像转化为灰度图像的过程.彩色图像分为R,G,B三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色的R,G,B分量相等的过程.灰度值大的像素点比较亮(像素值最大为255,为 ...
- python基础day4_列表list
list列表 li = ['alex',[1,2,3],'hjh','nvshen '] l1= li[0] print(l1) # alex l3= li[0:3]#['alex', [1, 2, ...
- Python os.chown() 方法
概述 os.chown() 方法用于更改文件所有者,如果不修改可以设置为 -1, 你需要超级用户权限来执行权限修改操作.高佣联盟 www.cgewang.com 只支持在 Unix 下使用. 语法 c ...