最近在进行集群任务的spark任务优化,记录下心得
首先优化的部分 大多是hive任务变成spark任务 原因基本都是因为spark任务容易进行资源管控 不会出现一个任务把资源占了大半的情况
接下来重点说的是有关于如何在资源方面提升任务效率的因素
主要是两个方面 一个是集群方面的物理资源 体现为
spark.instance * cores
另一个是spark任务的逻辑资源 体现为
spark.shuffle.partitions
如果把整个场景比喻为一个办公室 ,那 spark.shuffle.partitions 就等于有几个工位,spark.shuffle.partitions就等于有几个程序员,一般设置spark.shuffle.partitions的值为spark.instance * cores的值的2-3倍,为什么不是一比一 是因为可能有的task完成的速度快 有的慢 如果设置为一比一 会造成资源的空转。
那么接下来可以细致描述下一个map reduce流程的map数量 shuffle分区数 reducer数量和上述资源的具体关系。
首先,map端会从hdfs上,也就是磁盘上拉取数据,数据以block的形式存储在磁盘上,当map端拉取数据时 会按照数据块大小进行split,一个mapper处理一个部分,因此假设有10000个hdfs分区的数据,那mapper的数量会大于10000。mapper的数量一般不需要控制。
然后进入shuffle阶段,shuffle阶段的分区数,就是之前spark.shuffle.partitions的设置的值,比如有100个分区,然后mapper来的数据根据key值进行打标签,hash后取模,分到对应的partitions上,这里会有100个分区工作 但不一定全部能并行跑,因为会受限于物理资源,比如此时有20个instance,2个core,那一共有40个工位,100个程序员,只有40个程序员可以同时开始工作,剩下60个程序员在排队pending等待,一旦之前的有人完工了 ,后面的就顶上,直到100个人的活全部干完,这也就是spark.shuffle.partitions需要合理设置的原因,设的小了,会造成资源的浪费,设置大了,没意义,因为资源就那么多 人再多也得等着
最后进入reducer端,同理,reducer的最大数目也就是设置的partition的数目,但不一定每个redcuer都会有数据进,具体得看分发的规则,比如如果是distribute by key 一共有88个key 那就是有88个reducer分发到了数据,开始排队 先有40个reducer同时跑,剩下的排队等着;如果是distribute by rand,那就100个reducer都会分发到差不多大小的数据,先有40个跑 剩下的等着(这部分内容之前的blog上已经说明过了)
大概就是这么个过程 有不对的 欢迎各位大佬指出