下面是断断续续的记录,后续会出流程图,以及源码片段
一:建立数据管道 DFSOutputStream setPipeline(nextBlockOutputStream)
二: 启动了ResponseProcessor,用来监听我们一个packet发送是否成功
initDataStreaming() ->启动一个线程->run()读取下游结果->如果发送成功就把ackQueue里packet移除
dataqueue和ackqueue目的是容错。
数据以packat写到dataQueue,DataStreamer将数据写入datanode同时写到ackQueue,如果写到datanode成功了ackQueue.removeFirst()移除packet
如果写datanode失败了,ackQueue将packet放到dataQueue。
flush() 到DataxceiverServer->Dataxceiver
packet->存到ackqueue同时往下游发送->如果下游写入成功,ackQueue中将packet移除,如果写不成功,ackQueue中数据再往下游发
如果不是数据管道最后一个节点,读取下游的结果
管道如果没有创建成功,就移除block,跟申请相反的操作,然后将host放到exclude中,while循环重试,判断exclude长度,申请block将这个没成功的host排除
写数据容错分析
写数据写着写着失败了怎么办??
DataStreamer->run()->one.writeTo(blockStream)->失败了errorIndex变为0,hasError=true;->关闭各种流->ackqueue数据挪到dataQueue然后重新处理
重新建立数据管道,把出问题的node记录下来
- 如果假设我们副本有3个,写数据时候出问题了,就不能直接用剩余的节点建立新的管道,继续发送数据,所以需要构建新的数据管道
- 大多数情况 block-》hadoop1,hadoop2,hadoop3 数据管道修改为->hadoop2 hadoop3 只往hadoop2 hadoop3去写
- namenode发送指令给datanode,集群会自动发现少了副本,然后向别的机器创建副本