DFSClient 写一个Block的过程

DFSClient 写一个Block的过程


 
(1) 上层应用程序往输出流(FSDataOutputStream封装)写数据,底层DFSClient把数据切分成packets(典型的是64K),一个一个packet发送出去。
Packet 格式:

     *  (H is head, C is checksum data, D is payload data)
     *
     * [HHHHHCCCCC________________DDDDDDDDDDDDDDDD___]
     *       ^    ^               ^               ^
     *       |    checksumPos     dataStart       dataPos
     *   checksumStart

Head 里面包含 pktLen(packet的长度)、 dataLen(不包含checksum)、是否是当前Block的最后一个Packet等信息。

Packet的数据又是由一些chunks组成。每个Chunk默认是512字节,对应产生4byte的checksum。
所以写数据的时候会先缓存,够一个Chunk了就往当前Packet里面写一个chunk的数据,当Packet达到了最大的chunk数目(64k/512=128)时,这个Packet就满了,就new 一个新的Packet,往新的packet里面写数据。满了的packet就会往dataQueue里面put,由线程DataStreamer写出去。前面是正常的write过程。
sync操作会强制把缓冲的数据即使没有满足一个chunk,往packet里面发送,然后把packet往dataQueue里面put,然后等到这个packet的ack返回回来。
对于hbase key=10,value=100的数据大小,往往生成的packet只有几百byte(即使hbase用了group sync)。 


(2)  DFSClient 对于建立的一个pipeline有两个线程,一个是DataStreamer,一个是ResponseProcessor。
DataStreamer线程从dataQueue队列里面获得packet,把packet数据发送出去,然后put到ackQueue队列中。
ResponseProcessor 获得DataNode1的ack,然后把packet从ackQueue中拿掉,等待sync该packet的APP就会被notify。
需要注意的是每个packet由一个Seqno,一个block的Seqno从0开始,顺序递增,这个seqno用于顺序保证的,所有的packet必须顺序被处理,如果乱序了就会抛出异常。
ackQueue.size() +  dataQueue.size() < 80     each packet 64K, total 5MB   像hbase这种sync频繁的,实际上远远不够这么多。 (1000*80=78k)



(3) DataNode 也有两个线程DataXceiver、PacketResponder。
DataXceiver主要是分析是那种请求:读、写等。写调用BlockReceiver来处理。
BlockReceiver 里面就是一个个packet进行处理,读到一个packet的数据 需要往两个地方写:一个是写一个datanode、一个是本地disk。先往下一个datanode写,后往disk写。做完之后就往 ackQueue里面写一个packet,这个packet跟DFSClient的packet不同,这个packet只记录seqno以及lastPacketInBlock(是否是本block的最后一个packet).
最后面一个。
注意在建立pipeline的时候已经DFSClient以及pipeline上面的DataNode已经知道了后续的节点(node)。


最后面一个DataNode的PacketResponder 从ackQueue里面获得一个packet往前序的DataNode发送ack。中间的DataNode只有获得后面的DataNode的ack(read an ack from downstream datanode)后才能往前序的DataNode发送ack。

在hbase的运行过程中,很多时候各个packet的处理时间不同,读写、compact相互影响。
目前社区已经实现了并行写:DFSClient像各个DataNode写数据,不在是pipeline的方式,能够降低latency,但是同时也会降低throughput,如果网络带宽不是问题可以使用。

一个Packet在这个过程的各个阶段都会产生延时,导致hbase一条记录写入产生毛刺,比如DFSClient端packet可能会在dataQueue里面停留1ms以上等。

https://issues.apache.org/jira/browse/HDFS-265

猜你喜欢

转载自bupt04406.iteye.com/blog/1590169