hadoop2.2.0 边角料(二)

上一篇文章忘了提了,这一组博客是我为了要做一个hdfs的项目,对hadoop学习的一组文章。并且只关注了我觉得会用到的API和相关流程,主要是了解DFSClient的工作过程,涉及到DFSClient与NN和DN的通信。以前没有用过java,只了解一些基本语法,对hadoop的了解也比较粗浅,如果有什么理解错误的地方,希望看到这个博客的人能给我指出来,先谢过了。

这次看的问题是如何从Datanode中读取一个block?

之前看过http://blog.jeoygin.org/category/technology/hadoop上的一组博客,学习了一下hadoop0.20.2的结构,但是2.2.0上很多代码结构已经有了特别大的变化。下面记录一下读取一个block的主要过程。

1.Client向DN发出读取block的请求,操作码在Op.java中定义。

2.DN的DataXceiverServer.java接到请求后,启动一个DataXceiver.java线程,处理实际请求。

3.DataXceiver.java的run() -> readOp()得到操作码。

4.run()->processOp()调用相应的函数,对于读取block调用的就是opReadBlock()

5.opReadBlock()通过protobuffer解析输入参数然后调用readBlock()

public void readBlock(final ExtendedBlock block,
    final Token<BlockTokenIdentifier> blockToken,
    final String clientName,
    final long blockOffset,
    final long length,
    final boolean sendChecksum,
    final CachingStrategy cachingStrategy) throws IOException {
    ...
    BlockSender blockSender = null;
    ...
    try {
      try {
        blockSender = new BlockSender(block, blockOffset, length,
            true, false, sendChecksum, datanode, clientTraceFmt,
            cachingStrategy);
      } catch(IOException e) {
        ...
      }
      
      // send op status
      writeSuccessWithChecksumInfo(blockSender, new DataOutputStream(getOutputStream()));

      long read = blockSender.sendBlock(out, baseStream, null); // send data

      ...
    } catch ( SocketException ignored ) {
      ...
    } 
    ...
  }

6.重点在BlockSender.java中,看的还比较粗略


1)  BlockSender发送的数据格式

  +-----------------------------------------------------------------------+

  | ChecksumHeader | Sequence of data PACKETS...     |

  +-----------------------------------------------------------------------+ 

   

 ChecksumHeader = CHECKSUM_TYPE(1 byte) + BYTES_PER_CHECKSUM(4 bytes)

 PACKET = packet header + checksum(x bytes) + data(BUFFER_SIZE bytes).


data是有chunk构成,x = data的chunk数量取上界 * CHECKSUM_SIZE

CHECKSUM_SIZE取决于checksum类型,CRC32是4bytes

client在读到LastPacketInBlock置为true的packet或者一个空packet的时候结束传输,返回OP_STATUS_CHECKSUM_OK给DN


2)   构造函数

输入参数:

  block: 读取的block

          startOffset: 开始读取的偏移值

  length: 读取的数据长度

  corruptChecksumOk:  
  verifyChecksum: 读取数据的时候是否验证校验码
  sendChecksum: 是否发送checksum给client
  datanode: block所在的datanode
  clientTraceFmt: client记录log的格式

过程:

1.cache相关,略过

2.获取block的一个replica,如果block正在被写,则等待3s,如果需要访问的部分(startOffset+length)还不能够获取,则报错

3.检验replica的时间戳和可见性

4.根据replica,得到block的checksum,meta_file不存在的时候,生成一个新的checksum,不影响传输

5.根据checksum,得到chunksize,默认值为10M

6.根据读取block的偏移,设置checksumIn和blockIn的偏移位置

3) sendBlock

过程:

1.根据是否设置transferTo,分配packet的大小

2.循环调用sendPacket发送packet

3.检查线程是否被中断,没有被中断的话,关闭out,sentEntireByteRange = true,完成。

4) sendPacket

输入参数:

  pkt  写入packet数据的缓冲区

   maxChunks 最大chunk数

   out stream to send data to

   transferTo 是否使用transferTo的传输方式

   throttler 调节传输带宽

过程:

1.按顺序写入header,checksum部分

2.如果不使用transferTo方式的话,写入data部分,需要的话,校验一下。

3.发送数据,transferTo的方式只发送header和checksum,估计是为了跳读吧。还不太清楚

 









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值