spark处理超大文件方法 spark读取hdfs文件规则( 二 )


数据倾斜
在上面的任务处理中出现了shuffle的操作 。shuffle也叫洗牌 ,  在上面讲partition和分布式计算原理的时候 , 我们知道分布式计算就是把数据划分很多个数据片存放在很多个不同的节点上 ,  然后在这些数据片上并发执行同样的计算任务来达到分布式计算的目的 , 这些任务互相是独立的 ,  比如我们执行一个count操作 ,  也就是计算这个数据的行数 。实际的操作其实是针对每个数据分片 , 也就是partition分别执行count的操作 。比如我们有3个分片分别是A,B,C ,  那执行count的时候其实是并发3个线程 , 每个线程去计算一个partition的行数 ,  他们都计算完毕后 , 再汇总到driver程序中 ,  也就是A,B,C这三个计算任务的计算过程是彼此独立互不干扰的 , 只在计算完成后进行聚合 。但并不是所有的计算任务都可以这样独立的 , 比如你要执行一个groupby的sql操作 。就像上面的图中 , 我要先把数据按单词分组 , 之后才能做其他的统计计算 ,  比如统计词频或者其他相关操作 。那么首先spark要做的是根据groupby的字段做哈希 , 相同值的数据传送到一个固定的partition上 。这样就像上图一样 , 我们把数据中拥有相同key值的数分配到一个partition ,  这样从数据分片上就把数据进行分组隔离 。然后我们要统计词频的话 , 只需要才来一个count操作就可以了 。shuffle的出现是为了计算能够高效的执行下去 ,  把相似的数据聚合到相同的partition上就可以方便之后的计算任务依然是独立隔离的并且不会触发网络IO 。这是方便后续计算的设计模式 , 也就是节省了后续一系列计算的开销 。但代价是shuffle本身的开销 , 而且很多情况下shuffle本身的开销也是很大的 。尤其是shuffle会因为数据倾斜而出现著名的长尾现象 。
根据shuffle的理论 , 相似的数据会聚合到同一个partition上 。但是如果我们的数据分布不均匀会出现什么情况呢? 比如我们要针对职业这个字段做groupby的操作 ,  但是如果100W行数据中有90W行的数据都是程序员这个职业的话 ,  会出现什么情况? 你会发现有90W行的数据都跑到了同一个partition上造成一个巨大的partition 。这样就违背了分布式计算的初衷 ,  分布式计算的初衷就是把数据切分成很多的小数据分布在不同的节点内存中 , 利用多个节点的并行计算能力来加速计算过程 。但是现在我们绝大部分的数据都汇聚到了一个partition中 , 这样就又变成了单点计算 。而且这里还有一个特别大的问题 ,  就是我们在提交任务到hadoop yarn上的时候 , 申请的资源是固定且平均分配的 。比如我申请10个container去计算这份数据 , 那这10个container的资源是相等的 , 哪个也不多 , 哪个也不少 。但是我们的数据分片的大小却是不一样的 ,  比如90W行的分片需要5个G的内存 , 但是其他的数据分片可能1个G就够了 。所以如果我们不知道有数据倾斜的情况出现而导致申请的资源教少 , 就会导致任务OOM而挂掉 。而如果我们为了巨大的数据分片为每个container都申请了5G的资源 ,  那又造成了资源浪费 。
数据倾斜和shuffle是业界经典难题 , 很难处理 。在很多大数据产品中都会有根据数据大小自动调整申请资源的功能 。而数据倾斜就是这种功能绝对的天敌 。处理不好的话 , 要不会变成申请过大资源承包集群 , 要不会申请过小资源导致任务挂掉 。而我们在测试阶段要做的 , 就是模拟出这种数据倾斜的数据 ,  然后验证ETL程序的表现 。


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: