本文包含如下内容:
1、BlockSend在发送数据之前读数据文件和meta文件生成的Packet的结构。
2、BlockSender的核心方法:sendBlock和sendPacket。
前言:
BlockSender#sendBlock有几处调用场景,分别是:
1、copyBlock,用于balancing;
2、DataTransfer#run,用于pipeline恢复过程中往新datanode传输已写入数据;
3、readBlock,客户端读数据;
4、scanBlock,VolumeScanner扫描块。周期性扫描块,提前发现block checksum异常 corrupt的块。
一、关于Packet的结构
BlockSender从磁盘读一个block然后发给接收者。
class BlockSender implements java.io.Closeable {}
从BlockSender发送的数据遵循下面的格式:
Data format:
ChecksumHeader format:
1字节的CheckSum类型(CRC32, CRC32C等),4字节的一个int整数用来表示多少个字节的数据生成一个checksum。
空packet用来标记end of block以及读完成了。
Packet包含一个packet header、checksum 和 数据。
CHECKSUM_SIZE通常取决于CHECK_SUM类型,CRC32是4。
客户端会一直读数据,直到它收到了LastPacketInBlock为true或者长度为0的packet。
如果没有checksum error,客户端会给datanode响应OP_STATUS_CHECKSUM_OK。
PacketHeader的结构图:
所以一个Packet的整体结构如下: