HDFS源码分析:客户端读写

 客户端读

hdfs客户端读会先调用open方法,open会调用先getBlockLocations来获取块信息,
然后通过openinternal生成DFSInputStream对象,通过DFSInputStream读数据。

getLocatedBlocks(String src, long start, long length)

客户端会调用getLocatedBlocks()方法获取HDFS文件指定范围内所有数据块的位置信息。这个方法的参数是HDFS文件的文件名,起始偏移和长度,返回值是文件指定范围内所有数据块的文件名以及他们的位置信息,使用LocatedBlocks对象封装。(length似乎没有用,默认都是传的128M,返回都是所有的块信息)

Proto_namenode:

rpc getBlockLocations(GetBlockLocationsRequestProto)

      returns(GetBlockLocationsResponseProto);

LocateBlocks数据结构:

DFSInputStream.read(byte[] buffer, int offset, int length)

在read方法中首先使用blockSeekTo方法定位到所要读取dn上,然后使用readBuffer方法获取数据。

blockSeekTo方法会根据LocateBlocks列表以及读的位置选择block最优的的dn(即LocateBlock对象),根据LocateBlock中locs的host:port创建socket,最后生成对应的BlockReader。HDFS有两种BlockReader,分别是BlockReaderLocal和BlockReadRemote。以下BlockReadRemote为例。

BlockReadRemote创建的时候,首先会向socket中发送一个readBlock命令。命令由三部分组成DataTransferProtocol.DATA_TRANSFER_VERSION(short,=28),opcode(1byte,read_block=81)和OpReadBlockProto(通过proto.writeDelimitedTo写入)。Dn接到请求以后,返回一个BlockOpResponseProto(通过proto.writeDelimitedTo写入)。Check返回status为ok才完成reader的初始化。

readBuffer方法主要用于读取数据,本质上其实就是BlockReadRemote.read方法。read中会调用readNextPacket方法,此方法的逻辑是会向server端不停的获取数据包,获取数据完全后,会向server端再获取一个空包,空包上会有LastPackctInBlock的标记,验证标记后,会向server端写入一个ClientReadStatusProto。

PacketReceiver.recevieNextPacket方法中记录了包的结构如下:

客户端写

在分析写数据之前,首先要理解hdfs中的block、packet、chunk。

Block

每个hdfs上的文件都是由元数据(描述数据的数据),数据块组成,而block就是数据块的意思。Hdfs上的数据块大小一般是128MB。Block都存储在Datanode上面。

Packet

Hdfs客户端与Datanode之间使用Packet来传输数据,默认大小64MB。

Chunk

组成Packet中数据的最小单位。每个chunk主要由512Byte数据和4Byte校验位组成,总长度为516Byte,64MB大小Packet能包含的126个Chunk。校验位通过CRC32算法生成。

写流程

DFSClient.create会调用DFSOutputStream.newStreamForCreate方法,此方法会向Namenode发送create请求(rpc create(CreateRequestProto)returns(CreateResponseProto))。请求完成后会创建一个DataStreamer,Datastreamer会和Datanode做数据交互。DFSOutputStream在写数据会把数据先变成一个一个chunk,然后多个chunk会组成一个packet,然后会交给DataStreamer的发送队列。DataStreamer在发送数据之前会查看有没有block,如果没有会调用DFSOutStream.addBlock先增加一个block(rpc addBlock(AddBlockRequestProto) returns(AddBlockResponseProto)),然后发送packet。

Packet(DFSPacket)的构成

DataStream与Datanode交互

未经允许禁止转载~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇