shuffle简介

  • MapReduce的shuffle一般是指Map输出到Reduce输入的整个过程。
  • 整个shuffle过程中伴随着大量的磁盘IO , 网络IO 。
  • shuffle性能的高低 , 直接决定了整个程序的性能高低 。
    MapReduce:详解shuffle
    shuffle的字面意思是洗牌 , 即有序 - 无序的一个过程 , 比如JDK中的shuffle , 它的作用就是随机打乱集合中的元素 。但在MapReduce中 , 则更像是狭义shuffle的逆过程。

shuffle过程

  1. map task执行 , 输入源来自HDFS的block
  2. 数据经过mapper之后 , 得到键值对
  3. 如果在map task中想做键值对的合并 , 这个过程叫做combine(需要设置Combiner)
  4. 键值对序列化为字节数组后 , 被写入缓冲区
  5. 该缓冲区默认大小限制100M , 数据量较大的情况 , 溢出到磁盘 , 这个过程叫做spill , 磁盘可存在多个spill文件
  6. 当map task完成时 , 内存缓冲区的数据会被写入spill文件 , 所以最终磁盘中至少有一个spill文件
  7. 因为最终的spill只能有一个 , 所以需要将多个spill文件归并到一起 , 这个过程叫做merge
  8. 默认由系统选择发给哪个reduce task(可通过Partitioner接口自定义)
  9. 每个reduce task不断通过RPC从JobTracker获取map task是否完成的信息 , 如果reduce task得到通知 , 某台TaskTracker上的map task执行完成 , 则shuffle进入后半段
  10. copy阶段 , reduce task启动数据线程(fetcher) , 通过http方式请求map task所在的TaskTracker获取map task的输出文件。
  11. merge阶段 , 与map阶段的merge类似 , 最终生成一个spill文件
  12. reduce执行 , 完成后将结果集放到HDFS

shuffle优化

大部分map task和reduce task执行在不同的节点上 , 所以大量job的情况下 , 集群必然耗费大量的网络资源在IO上 。还有一小部分的map task和reduce task处于同一节点中 , 磁盘IO对job完成时间影响也较可观 。数据传输到reduce task之后 , 还需要进行排序 , 这部分工作所耗费的系统资源、时间也是不容忽略的。
根据以上情况 , 优化的方向大致可以分为 :

  • 硬件层面
    • 提高磁盘IO性能(固态硬盘)
    • 提高网络IO性能(千兆网卡)
  • 软件层面
    • 合理分配资源
      • map task和reduce task数量 , 通过benchmark找到较为合理的区间
    • 减少map task传输到reduce task的数据(压缩数据)
    • 减少磁盘IO(内存缓存)
      • 配置noatime
    • 尽可能地避免排序

相关文章: