spark_shuffle方式的演进过程
spark shuffle有四种方式,分别是
- hashshuffle
- 优化后的hashshuffle
- sortshuffle
- bypass
一、hashshuffle与优化
一开始spark的shuffle方式是hashshuffle。hashshuffle有一个严重的问题,就是产生的小文件数量比较多。
我们知道,shuffle分为map端的shuffle write 和reduce端的shuffle read。
hashshuffle,每个task为下游每一个task都创建了一个文件,所以就产生了M*R的小文件数量,其中M是map的task数量,R是reduce的数量。
为了减少小文件的数量,spark随后提出了优化后的hashshuffle,即每个core处理的task文件的结果合并起来
比如:task1 write了3个小文件,里面是keyA keyB keyC,分别叫BlockA BlockB BlockC 吧
这时又来了一个task2,优化前task2 也产生三个小文件BlockA BlockB BlockC。这样就有6个小文件
但是task2 和task1是同一个core处理的,所以task2的BlockA BlockB BlockC 写入了task1 的BlockA BlockB BlockC,由于同一个文件中是同一个下游task处理的,所以只要追加写入就可以了。
该优化方法,本质上是小文件的合并(同一个core的小文件数量合并),朝着这个方向,我们可以继续优化成“同一个executor(jvm)产生的同一个下游task的小文件合并”,和同一台机器合并,不过spark并没有实现这些优化。
由于同一个stage里的map的task不分先后顺序,但是同一个core里的task是先后处理的。所以同一个jvm或者同一台机器的小文件合并,没有同一个core的合并那么简单。
spark也提出过内存共享的优化方法,跨executor(jvm)去共享一台机器上面的内存。
该优化最终将小文件数量下降了X倍,X为平均每个core处理的task数量,
- 比如,有100个map,下游是500个reduce,那原本是100*500=5w的小文件数量,现在map端分配的core是20个(每个core处理5个task),就变成了20*500=1w,缩小了5倍。
该优化方法虽然好,但是受限于机器并行的能力,如果机器并行的能力强,分配的core数量接近于map的数量,该优化就十分有限。
二、sortshuffle
为了实现更进一步的小文件合并,spark在随后提出了sortshuffle。
sortshuffle的目的,还是实现"更宽"的“共享”。
上述讲到hashshuffle对spark的小文件做了同一个core的合并,但是由于不同core的task没有先后顺序,很难合并。sortshuffle就是为了实现“每台机器上的map task小文件都合并”。
因为一台机器上的task之间执行没有顺序,所以要等待所有的task执行完成。无法有效利用并发能力。
如果按照之前的做法,为每个reduce task创建一个文件,并且同一台机器上的同一个reduce task的文件合并的话,这样最多能节省的倍数为平均一台机器处理的task数量,
- 比如,有100个map,下游是500个reduce,那原本是100*500=5w的小文件数量,现在map端分配的core是20个,20个core在5台机器上(机器是4核的),就变成了5*500=2000,缩小了20倍。
显然优化者不满足于这种程度的优化,于是优化者这次对"*500" 动手了(reduce task的数量)。如何优化"*500", 原来一个map task 会产生500个task,现在将这些都合并了。所以就没有了"*500"
- 比如,有100个map,下游是500个reduce,那原本是100*500=5w的小文件数量,现在合并了同一个map task产生的reduce task,那么文件数量就变成了100个。虽小了500倍,(由于要增加索引文件,所以实际上要除以2,是250倍)
只不过如果一个map,为500个reduce task 产生一个文件,这500个reduce task要怎么使用呢?答案是排序+索引,这就是sortshuffle的由来。
为了实现500个reduce task对一个文件的高效操作,map write的文件内部是有序的,并且还为该文件提供了一个索引文件。这样reduce task 就可以根据索引文件在该文件中找到自己对应的数据了。
该方式的map write的方式也发生了改变,类似于lsm的操作那样,每次内存写满了就一次性把内存数据进行排序,写入到磁盘生成一个文件,等到所有的数据都写入磁盘后,再对所有生成的文件进行一个归并排序。
这种shuffle的好处是大大减少了小文件的数量,且优化的力度不受限于reduce task的数量,只受限于map的数量。坏处是增加了一个排序的开销。
既然map write产生的文件都是有序的,为什么不再对同一台机器或core的的文件进行归并呢。答案是没有必要,太多的小文件会增大网络IO的开销,太少的文件对降低并发的利用率。不过,如果上游的数据量很大(map数量很多),而该key的基数(去重后的数量)比较小的话,还是可以考虑按core或jvm或机器级别进行合并的(合并还要考虑到索引的合并),不过spark没有提供这类优化。
三、bypass
bypass是sortshuffle的一种优化。上述提到,map write的文件内部做了全局排序。是为了多个reduce task能找到各自需要read的数据。但是在一个reduce task内,数据并不需要有序,而reduce task的数量一般远远小于数据行数(数据key的基数),所以这就造成了计算的浪费。
为了停止这种浪费,spark提出了新的shuffle优化bypass,即改变map write的方式,在write的时候,原来要对每一个flush到磁盘的小文件进行排序,现在不排序了,复制之前hashshuffle的做法,为每个reduce task写一个小文件。最后,将这些同一个map产生的小文件合并成一个大文件,合并的方式很简单,就直接追加就可以了,最后对结果文件增加一个索引,这样下游每一个reduce task都能找到自己要读的数据。这样既省下了排序的开销,又将小文件数量缩小到了2*M的数量(和sortshuffle一样)。可谓是兼具了hashshuffle和sortshuffle的优点。
不过该方法也有限制的地方。该shuffle不支持预聚合,map的数量也尽量要小(和最初的hashshuffle一样,map数量过大会产生过多的临时文件)
触发bypass的map数量上限可以用参数 spark.shuffle.sort.bypassMergeThreshold 设置
spark_shuffle方式的演进过程的更多相关文章
- P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...
- 阿里P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...
- Spring-cloud微服务实战【一】:微服务的概念与演进过程
本文是一个系列文章,主要讲述使用spring-cloud进行微服务开发的实战.在开始之前,我们先说一下从传统的单一部署架构到微服务的发展过程,以便让童鞋们更好的理解微服务的概念与演进过程. 1.单体架 ...
- RPC 是通信协议吗 ?→ 我们来看下它的演进过程
开心一刻 一实习小护士给我挂针,拿着针在我胳膊上扎了好几针也没找到血管 但这位小姑娘真镇定啊,表情严肃认真,势有不扎到血管不罢休的意思 十几针之后,我忍着剧痛,带着敬畏的表情问小护士:你这针法跟容嬷嬷 ...
- 框架源码系列四:手写Spring-配置(为什么要提供配置的方法、选择什么样的配置方式、配置方式的工作过程是怎样的、分步骤一个一个的去分析和设计)
一.为什么要提供配置的方法 经过前面的手写Spring IOC.手写Spring DI.手写Spring AOP,我们知道要创建一个bean对象,需要用户先定义好bean,然后注册到bean工厂才能创 ...
- 图解 Kafka 超高并发网络架构演进过程
阅读本文大约需要 30 分钟. 大家好,我是 华仔, 又跟大家见面了. 上一篇作为专题系列的第一篇,我们深度剖析了关于 Kafka 存储架构设计的实现细节,今天开启第二篇,我们来深度剖析下「Kafka ...
- Java的类演进过程
1.从面向过程到面向对象 在大家最熟悉的C语言中,如果要定义一个复杂的数据类型就用结构体(Struct)来实现,而为结构体的每个操作都定义一个函数,这个函数与结构体本身的定义没有任何关系.程序的重心集 ...
- WINDOWS硬件通知应用程序的常方法(五种方式:异步过程调用APC,事件方式VxD,消息方式,异步I/O方式,事件方式WDM)
摘要:在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口.为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,详细说明每种方法的原理和实现过程,并 ...
- 浏览器打开URL的方式和加载过程
不同浏览器的工作方式不完全一样,大体上,浏览器的核心是浏览器引擎,目前市场占有率最高的几种浏览器几乎都使用了不同的浏览器引擎:IE使用的是Trident.Firefox使用的是Gecko.Safari ...
随机推荐
- (十)VMware Harbor 日志管理
VMware Harbor 日志管理 1. 项目日志 每个项目下都有一个"日志"页签. 单击"日志"可以列出所有日志.可以按用户名或"高级搜索&quo ...
- (十五)VMware Harbor 标签管理
1. Harbor提供两种标签用来隔离各种资源(目前只有镜像): 全局级别标签: 由系统管理员管理,用于管理整个系统的镜像.它们可以添加到任何项目下的镜像中. 项目级别标签: 由项目管理员或者系统管理 ...
- 在Linux CentOS上搭建Jmeter压测环境
本文的主要内容是介绍如何在Linux CentOS 服务器上面搭建Jmeter的压测环境整个详细的流程,来满足我们日常工作中对于压力测试环境搭建.压力测试执行过程的需求. 一.首先我们要准备四个东西, ...
- Throwing cards away I UVA - 10935
Given is an ordered deck of n cards numbered 1 to n with card 1 at the top and card n at the botto ...
- mybatis的本质和原理
背景 项目需要,我们需要自己做一套mybatis,或者使用大部分mybatis的原始内容.对其改造,以适应需要.这就要求我再次学习一下mybatis,对它有更深入的了解. 是什么 MyBatis ...
- Ubuntu 20.04 简述环境配置&美化
不敢说是最好的,基本上是最全面的了~ 修改系统软件源 一开始是国外的源比较慢,建议换成国内的源,常用的有清华源.阿里源等. 清华源地址 Ubuntu 的软件源配置文件是 /etc/apt/source ...
- kubernetes 的API 介绍
在API conventions doc中描述了API的全部协议. 在API Reference文档中描述了API的端点.资源类型和示例. 在Controlling API Access doc中讨论 ...
- E - Level K Palindrome
题目大意: As a token of his gratitude, Takahashi has decided to give Snuke a level-KK palindrome. A leve ...
- 【ElasticSearch】shards,replica,index之间的关系
1.index 包含多个shard ,在创建index的时候可以自定义shards和replica的数量 例如: 新增一个index,手动指定shard和replica的数量 PUT demo_ind ...
- Spring Framework自动装配setAutowireMode和Mybatis案例的源码探究
由前文可得知, Spring Framework的自动装配有两种方式:xml配置和注解配置: 自动装配的类型有: (1)xml配置中的byType根据类型查找(@Autowired注解是默认根据类型查 ...