HDFS数据流管道二三问

HDFS通过数据流的方式写数据块。

版本:截止至2.x。

管道中的IO流

管道中的IO流

  • in:上游节点到当前节点的输入流,当前节点通过in接收上游节点的packet。
  • replyOut::当前节点到上游节点的输出流,当前节点通过replyOut向上游节点发送ack。
  • mirrorOut:当前节点到下游节点的输出流,当前节点通过mirrorOut向下游节点镜像发送packet。
  • mirrorIn:下游节点到当前节点的输入流,当前节点通过mirrorIn接收下游节点的镜像ack。

管道中的关键线程

除了客户端,管道中的每一个dn都有两个关键线程:

  1. DataXceiver线程:dn上管道流的主线程,负责接收上游的packet,并继续向下游节点管道写。(BlockReceiver#receivePacket())。
  2. PacketResponder线程:负责接收下游节点的ack,并继续向上游管道响应

作为管道的发起者,也是管道的起点,需要主动写入数据,有三个关键线程:

  1. 用户写数据的线程:用户以chunk为粒度向缓冲区写数据,写满一个packet后放入dataQueue。
  2. DataStreamer线程:客户端上管道流的主线程,负责将packet从dataQueue移动到ackQueue,并向下游节点管道写packet
  3. PacketResponder线程:负责接收下游节点的ack,并移除ackQueue中的packet

结合上图,DataXceiver线程、DataStreamer线程维护in->mirrorOut方向的packet数据流,PacketResponder线程维护mirrorIn->replyOut方向的ack数据流。

管道的整体过程

管道的整体过程

管道的生命周期分为三个阶段:

  1. 管道建立:以管道的方式向下游发送管道建立的请求,从下游接收管道建立的响应。
  2. 管道写:当客户端收到管道建立成功的ack时,才利用刚刚建立的管道开始管道写数据块的内容。
  3. 管道关闭:以管道的方式向下游发送管道关闭的请求,从下游接收管道关闭的响应。

三个过程都是管道式的。

优缺点

  • 优点:如果考虑上客户端,那么管道写的优点是网络负载比较均衡
  • 缺点:慢节点会成为带宽瓶颈,且整体上延迟更高

如何优化延迟

管道写的方式通常称为pipeline

管道写

为了优化管道写的延迟问题,业界还提出了多种写方案:

超步写

如果还使用管道写,可以支持超步写

传统的管道写方案相当于TCP中的停-等协议,可仿照TCP,维护滑动窗口支持超步写,快速重传等方案同样适用。

星型写

如果网络资源充足,可以改用星型写

星型写

如果在星型写中发生了失败,既可以选择管道写最保守的方案,中断整个写重试,也可以使用更激进的方式,如其中2个DN写成功就继续向成功节点写,而失败的节点可以在后台重试(当然,如果不低于minRep可以暂时忽略)。

显然,上述方案对于慢节点的优化效果非常显著。

Y型写

如果期望网络资源与延迟平衡,可改用Y型写

Y型写

扫描微信关注我
微信公众号二维码
本文链接:HDFS数据流管道二三问
作者:猴子007
出处:https://monkeysayhi.github.io
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名及链接。
我是猴子007,<br>一只非常特殊的动物,<br>可以从事程序的开发、维护,<br>经常因寻找香蕉或母猿而无心工作。