转: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优化相关推荐

  1. es 仅返回单个字段 查询_ES性能优化实战,几十亿数据查询 3 秒返回!

    来源:cnblogs.com/mikevictor07/p/10006553.html 在此篇幅中偏重于 ES 的优化,关于 HBase,Hadoop 的设计优化有很多文章可以参考,不再赘述. 需求说 ...

  2. 12、分布式搜索引擎在几十亿数据量级的场景下如何优化查询性能?

    1.面试题 es在数据量很大的情况下(数十亿级别)如何提高查询效率啊? 2.面试官心里分析 问这个问题,是肯定的,说白了,就是看你有没有实际干过es,因为啥?es说白了其实性能并没有你想象中那么好的. ...

  3. mysql做十亿条数据查询_数据库优化:mysql数据库单机数十亿数据查询设计

    很久没写文章,是不是想着写点什么东西,分享下我的数据库设计思路,主要是针对单机数十亿及以上数据查询优化技巧. 如果只是简单的查询,没有频繁的写入操作,对查询速度不要求在毫秒级别,就不需要什么大型的数据 ...

  4. ClickHouse留存分析工具十亿数据秒级查询方案

    作者:陈璐,腾讯 CSIG 高级数据分析师 本文实践了对于千万级别的用户,操作总数达万级别,每日几十亿操作流水的留存分析工具秒级别查询的数据构建方案.同时,除了留存分析,对于用户群分析,事件分析等也可 ...

  5. java按秒查询数据_ClickHouse留存分析工具十亿数据秒级查询方案

    作者:陈璐,腾讯 CSIG 高级数据分析师本文实践了对于千万级别的用户,操作总数达万级别,每日几十亿操作流水的留存分析工具秒级别查询的数据构建方案.同时,除了留存分析,对于用户群分析,事件分析等也可以 ...

  6. currenttimemillis 毫秒还是秒_Elasticsearch如何做到数十亿数据查询毫秒级响应?

    如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有你想象中那么好的. 很多时候数 ...

  7. Elasticsearch如何做到数十亿数据查询毫秒级响应?

    如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有你想象中那么好的. 很多时候数 ...

  8. Quick BI产品核心功能大图(四):Quick引擎加速--十亿数据亚秒级分析

    简介: 随着数字化进程的深入,数据应用的价值被越来越多的企业所重视.基于数据进行决策分析是应用价值体现的重要场景,不同行业和体量的公司广泛依赖BI产品制作报表.仪表板和数据门户,以此进行决策分析. 在 ...

  9. es对几十亿数据能达到秒级响应吗_万亿数据下的多维实时分析系统,如何做到亚秒级响应...

    导语 当业务发展到一定规模,实时数据仓库是一个必要的基础服务.从数据驱动方面考虑,多维实时数据分析系统的重要性也不言而喻.但是当数据量巨大的情况下,拿腾讯看点来说,一天上报的数据量达到万亿级的规模,要 ...

最新文章

  1. JavaScript工作原理(二):V8引擎和5招高效代码
  2. bzoj 1124 [POI2008]枪战Maf 贪心
  3. UVa 11636 Hello World!
  4. Sublime Text 3 注册码失效(被移除)解决方法
  5. Yum Audio Everything Bundle for Mac - Yum Audio音频插件套装
  6. 分享下我的 netbeans 的配色方案
  7. echart坐标轴添加下划线问题
  8. 新计算机c盘太小,Windows自带C盘扩容方法,c盘太小怎么重新分区
  9. Baklib每日分享|在线产品手册的制作技巧
  10. 模糊数学在计算机方面的应用,模糊数学理论在图像处理中的应用
  11. 计算机房上课安全教育内容,机房实训安全教育学生须知
  12. mysql数据库结构导出word_Windows导出MySQL数据库表结构到Word文档-DBExportDoc V1.0 For MySQL...
  13. 团队任务3每日立会(2018-10-22)
  14. 记录一次关于解除推特的冻结
  15. 查看Linux内核修改及更新记录方法
  16. 38条搞笑WOW下线理由。。。 达人火速添加啊
  17. 简易方法制作GIF图(mp4转GIF)
  18. Kafka| 下载与安装
  19. Vmware上安装Vxworks 5.5
  20. 构建运营商企业级云管理平台

热门文章

  1. 微信小程序商城系统源码
  2. 马上加快宽带上网速度
  3. SSLHandshake aborted:ssl... 解决方法
  4. coalesce命令 oracle,请教表空间coalesce问题
  5. android 图片闪电效果图,Android超简单实现炫酷的图片展示效果
  6. 渲染世界的OPENGL12 一些有趣的纹理着色器
  7. ShaderToy系列
  8. 在苹果系统下切换xp系统方式
  9. python匿名函数--lambda函数
  10. 浅析机顶盒的节目控制