HDFS学习笔记【Datanode/读数据】

说明

DataTransferProtocol.readBlock给出了读操作的定义,最终实现是在DataXceiver.readBlock().

  • DataXceiver.readBlock首先给客户端一个响应,给出DN的校验方式
  • 数据块分包
  • 依次发送给客户端
  • 客户端校验
  • 失败,选择新的数据节点
  • 成功,客户端发送checkSum_OK
    在这里插入图片描述

客户端清楚的知道访问那一个DN,发送请求。DN中的DataXceiverServer接收请求,构建DataXceiver。执行readBlock方法。

DataXceiver ReadBlock

public void readBlock(block,blockToken,clientName,blockOffset,length,sendChecksum,cachingStrategy);

输入参数

  • ExtendedBlock blk
    读取的块
  • clientName
    客户端名称
  • blockOffset
    读取数据长度
  • length
    是否发送校验和
  • 缓存策略
    readahead,dropbehind
    预读取和丢弃策略

DataXceiver使用其中的ReadBlock方法进行实际的执行

ReadBlock方法

  1. getOutputStream获取客户端IO流,构建BlockSender信息。
    构造Blocksender需要客户端IO流,需要datanode节点的bp信息。
  2. BlockSender通过XX方法发送XX给客户端,通知客户端请求已经接收成功,告知数据节点校验信息
  3. BlockSender方法发送数据块给客户端
  4. BlockSender发送完所有块之后,客户端响应状态码

数据块传输格式

磁盘数据读取之后,需要一定的组织结构。BlockSender发送数据结构如下:
在这里插入图片描述
校验和包括

  • 校验类型
  • 块大小
    数据包序列
  • 包头
  • 校验数据
  • 实际数据

BlockSender实现

作用是数据块发送,包括 发送准备,发送数据块,以及清理工作。

发送准备

构造方法

  • 处理预读取数据
  • 赋值和校验
    datanode数据被读取时间戳,数据块的长度等状态
  • transferTo
    短路读相关
  • 校验信息
    Meta信息中获取
  • 计算offset和endset
    看看是不是在块的边界,如果是的话,修改下起始和中止位置。
    getInputStream时,可以指定block和offset

预读取和丢弃

manageOsCache
读取数据到操作系统缓存中
通过读取offset和lastCacheDropOffset判断是否丢弃

  • 预读条件
    开启了预读,具有资源readaheadpool资源等。

发送数据块

  • manageOsCache进行预读
  • 构造存放数据包的缓冲区(packet)
    如果是短路读的话,值缓冲校验。如果是iostream,需要缓存数据和校验和。一个packet可以包含最多X个校验块
  • 循环发送,循环预读
    使用sendpacket发送
  • 更新offset
    发送空包作为结束
    发送数据包主要是通过sendPacket方法

sendPacket

  • 校验缓冲区数据
  • 写入pkt缓存
  • 发送数据块
    零拷贝读的话,直接transferToFully(getChannel,position,len,time,transfertime)中
    outStream时,out.write(buf,XXX)
  • 调整节流器
    控制发送速率

零拷贝数据传输

读取数据时
磁盘到内核(步骤1)
内核到进程(步骤2)
跨内核推回到套接字缓冲区(步骤3)
写入网卡缓冲区 (步骤4)
需要网卡支持,调用java nio方法
transferto

节流器(throttle)

为了控制IO操作,在sendpacket最后的时候,使用了节流器控制。
他就是一个线程安全的, 多个任务线程共享的阻塞线程,满足条件放行,否则阻塞。
包含字段

  • period
  • curReserve
    等等

小结

readBlock 客户端发送请求, DataXceiverServer接收,构造工作线程DataXceiver
调用readBlock方法和客户端交互
构造BlockSender进行具体的发送准备工作(校验,分割,预读),清理工作等
调用sendpacket进行数据发送,通过节流器IO阻塞控制

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值