spark十亿数据join优化
转:https://daizuozhuo.github.io/spark-join/
最近在项目中用Spark join了几十亿的数据,在debug和不断优化性能中感觉收获良多,特此记录一下。
任务很简单,就是join两张表,表A ship有几千万行,包含每日寄出去的包裹的信息,表B item有几十亿行,包括所有商品的属性,我们需要把商品的属性信息加到每个包裹里面的商品上。
一开始我就是把它当成一个很简单的任务,不就是一个简单的left join吗?于是写下了如下代码:
Dataset<Row> shipItems = getSpark().sql("select " +"ship.*, item.* " +"from ship left join item " +"on ship.asin = item.item_asin").drop("item_asin");
shipItems.createOrReplaceTempView("ship_items");
但是一经实践就遇到一下错误:
17/07/10 02:26:14 ERROR YarnClientSchedulerBackend: Yarn application has already exited with state KILLED!
17/07/10 02:26:14 INFO SparkUI: Stopped Spark web UI at http://172.31.5.203:4040
17/07/10 02:26:14 ERROR TransportClient: Failed to send RPC 8654033690236908099 to /172.31.5.177:42830: java.nio.channels.ClosedChannelException
java.nio.channels.ClosedChannelExceptionat io.netty.channel.AbstractChannel$AbstractUnsafe.write(...)(Unknown Source)
17/07/10 02:26:14 ERROR YarnSchedulerBackend$YarnSchedulerEndpoint: Sending RequestExecutors(0,0,Map()) to AM was unsuccessful
java.io.IOException: Failed to send RPC 8654033690236908099 to /172.31.5.177:42830: java.nio.channels.ClosedChannelException
这个错误表明spark的任务在Yarn的executor中被kill了,然后在看一下Yarn executor中的log :”WARN: Received singal SIG_TERM”, 果然因为内存使用太多被Yarn kill了。
这是为什么呢?来估算一下完成这个任务需要多少计算资源吧。假设每个表大概有50字段,每个字段占用10个字符,那么当Spark将表A load进内存时需要501010^7/10^9 = 5G,而将表B load进内存时需要:501010^9/1000^9 = 500G。但是当我把整个集群的内存加到600G的时候这个错误仍然没有解决。猜测内存600G的集群仍然无法join表A和表B可能是因为在join过程中可能生成了多份数据而超过了表A和表B本来的大小,这个时候如果再继续提高集群大小就有点不划算了,所以我们开始考虑如何对程序进行优化。
此时该程序所需内存如下所示:其中深蓝色代表已经存在于集群中内存中的数据,浅蓝色代表正在生成中的数据,那么此时整个集群所需要的内存为两倍于表A和表B大小:(500 + 5) * 2 = 2010 G.
因为我们表A left join 表B 之后的结果和表A的大小是一样的,所以实际上大部分表B的数据是没有用的,那么我们可不可以先将一部分表B的数据去掉呢?我们可以确定的是只有存在于表A中物品才会出现在结果中,所以我们可以将表A中的所有商品ID取出来做成一个集合,这个集合的大小为 20 * 10^7/1000/1000 = 200 M,然后将这个集合broadcast到每一个slave节点进行filter,这样可以得到一个大大缩减版的表B。更重要的是,我们得到缩减版的表B之后,原来那个巨大的表B就可以从内存中删除了,这样可以大大减少内存的使用,最终使得程序成功运行。优化之后的代码如下:
Dataset<Row> distinctAsin = getSpark().sql("select distinct asin from ship").persist(StorageLevel.DISK_ONLY())
//only keep items appeared in shipments
Dataset<Row> filteredItems = getSpark().sql("select * from item").withColumnRenamed("asin", "item_asin").join(functions.broadcast(distinctAsin),functions.col("item_asin").equalTo(functions.c("asin")), "leftsemi").persist(StorageLevel.DISK_ONLY());
filteredItems.createOrReplaceTempView("filter_item");
Dataset<Row> shipItems = getSpark().sql("select " +"ship.*, filter_item.* " +"from ship left join filter_item " +"on ship.asin = filter_item.item_asin").drop("item_asin");
shipItems.createOrReplaceTempView("ship_items");
此时该程序所需的内存如下:其中深蓝色代表已经存在于集群中内存中的数据,浅蓝色代表正在生成中的数据,蓝色阴影代表已经处理过从内存中删除的数据,那么此时整个集群所需要的内存为两倍于表A和表C大小:(5 + 5) * 2 = 20 G.
通过gangalia监控到的集群内存使用量.
spark十亿数据join优化相关推荐
- es 仅返回单个字段 查询_ES性能优化实战,几十亿数据查询 3 秒返回!
来源:cnblogs.com/mikevictor07/p/10006553.html 在此篇幅中偏重于 ES 的优化,关于 HBase,Hadoop 的设计优化有很多文章可以参考,不再赘述. 需求说 ...
- 12、分布式搜索引擎在几十亿数据量级的场景下如何优化查询性能?
1.面试题 es在数据量很大的情况下(数十亿级别)如何提高查询效率啊? 2.面试官心里分析 问这个问题,是肯定的,说白了,就是看你有没有实际干过es,因为啥?es说白了其实性能并没有你想象中那么好的. ...
- mysql做十亿条数据查询_数据库优化:mysql数据库单机数十亿数据查询设计
很久没写文章,是不是想着写点什么东西,分享下我的数据库设计思路,主要是针对单机数十亿及以上数据查询优化技巧. 如果只是简单的查询,没有频繁的写入操作,对查询速度不要求在毫秒级别,就不需要什么大型的数据 ...
- ClickHouse留存分析工具十亿数据秒级查询方案
作者:陈璐,腾讯 CSIG 高级数据分析师 本文实践了对于千万级别的用户,操作总数达万级别,每日几十亿操作流水的留存分析工具秒级别查询的数据构建方案.同时,除了留存分析,对于用户群分析,事件分析等也可 ...
- java按秒查询数据_ClickHouse留存分析工具十亿数据秒级查询方案
作者:陈璐,腾讯 CSIG 高级数据分析师本文实践了对于千万级别的用户,操作总数达万级别,每日几十亿操作流水的留存分析工具秒级别查询的数据构建方案.同时,除了留存分析,对于用户群分析,事件分析等也可以 ...
- currenttimemillis 毫秒还是秒_Elasticsearch如何做到数十亿数据查询毫秒级响应?
如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有你想象中那么好的. 很多时候数 ...
- Elasticsearch如何做到数十亿数据查询毫秒级响应?
如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有你想象中那么好的. 很多时候数 ...
- Quick BI产品核心功能大图(四):Quick引擎加速--十亿数据亚秒级分析
简介: 随着数字化进程的深入,数据应用的价值被越来越多的企业所重视.基于数据进行决策分析是应用价值体现的重要场景,不同行业和体量的公司广泛依赖BI产品制作报表.仪表板和数据门户,以此进行决策分析. 在 ...
- es对几十亿数据能达到秒级响应吗_万亿数据下的多维实时分析系统,如何做到亚秒级响应...
导语 当业务发展到一定规模,实时数据仓库是一个必要的基础服务.从数据驱动方面考虑,多维实时数据分析系统的重要性也不言而喻.但是当数据量巨大的情况下,拿腾讯看点来说,一天上报的数据量达到万亿级的规模,要 ...
最新文章
- JavaScript工作原理(二):V8引擎和5招高效代码
- bzoj 1124 [POI2008]枪战Maf 贪心
- UVa 11636 Hello World!
- Sublime Text 3 注册码失效(被移除)解决方法
- Yum Audio Everything Bundle for Mac - Yum Audio音频插件套装
- 分享下我的 netbeans 的配色方案
- echart坐标轴添加下划线问题
- 新计算机c盘太小,Windows自带C盘扩容方法,c盘太小怎么重新分区
- Baklib每日分享|在线产品手册的制作技巧
- 模糊数学在计算机方面的应用,模糊数学理论在图像处理中的应用
- 计算机房上课安全教育内容,机房实训安全教育学生须知
- mysql数据库结构导出word_Windows导出MySQL数据库表结构到Word文档-DBExportDoc V1.0 For MySQL...
- 团队任务3每日立会(2018-10-22)
- 记录一次关于解除推特的冻结
- 查看Linux内核修改及更新记录方法
- 38条搞笑WOW下线理由。。。 达人火速添加啊
- 简易方法制作GIF图(mp4转GIF)
- Kafka| 下载与安装
- Vmware上安装Vxworks 5.5
- 构建运营商企业级云管理平台