6

HDFS - 写数据的那些事

 3 years ago
source link: https://segmentfault.com/a/1190000040269103
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

HDFS - 写数据的那些事

发布于 今天 16:39

之前也提过,客户端需要写数据的时候,就会跟NameNode说他准备把文件上传到某个目录,NameNode就会开始进行元数据的更新。由于元数据的更新是非常重要的,所以客户端会在一定条件内重试,直至成功。
image.png
元数据更新成功后,Client就会创建两个队列,一个是dataQueue,一个是ackQueue。这两个队列的作用下文会讲。
image.png
客户端写入的时候,是一个个chunk写的,每一个chunk的大小是512byte,chunk的校验和chunksum是4byte,这个校验和是对块的内容进行校验用的,所以每写入一个chunk的大小就是516byte。
image.png
这些chunk写满后,就会存放在一个叫做packet的东东里面,这个packet有64k的大小,所以就是65535byte,相当于127个chunk。每次写满一个packet或者写满128M(就是block的大小),就会创建一个新的packet给chunk写入。
image.png
已经写满的packet,就是放在上面提到的dataQueue。
image.png
客户端有其他线程,会监控dataQueue,此时他发现了dataQueue有数据了,他就开始向NameNode申请block信息。
NameNode会根据负载均衡以及机架感知,把计算后的DataNode的信息给到客户端。
image.png
得到DataNode信息后的客户端,就开始与其中一个DataNode建立数据管道,这个DataNode又会与其他DataNode建立数据管道。
image.png
建立数据管道的作用,就是把通过socket把数据传过去,客户端这里并没有直接和三个DataNode建立数据管道,这是因为DataNode一般是同一个机房的,所以他们内部通讯的速度会比较快。
管道建立成功后,客户端就会把dataQueue队列的头部packet拿出来,通过socket传给DataNode,另外也会把packet放入到ackQueue。
image.png
放入ackQueue的原因是为了防止packet传输给DataNode失败,如果失败了,就会把packet队列的packet放回到dataQueue,这样监听dataQueue队列的线程就会重新把她拿出来进行传输。如果传输成功了,会把ackQueue的packet移除。
DataNode接收到数据后,会把数据写入ackQueue队列,然后再把packet传输给下游,最后才写入磁盘。
image.png
这个ackQueue队列的作用跟上面一样,是为了防止传输失败,如果传输成功,就会把ackQueue队列中的packet移除,如果失败,就会继续传输。
如果DataNode不是最后一个节点,那就会重复上面的操作。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK