1.通信的三个实体
NameNode(nn):维护datanode的分布和任务的调度
DataNode(dn):存储数据的地方
DFSClient:提供接口来访问namenode和datanode
三者通信都基于TCP/Scocket
2.控制信息
整体链路是Client向namenode发起请求。等datanode的heartbeat信息到了时。nn把控制信息一并作为respon发送给datanode。然后有client与某个datanode交互。这个datanode在与其他datanode交互(串行,一个接一个,传递数据)
namenode从来不会主动的发信息给datanode。
所有的控制信息都是基于RPC进行,datanode之间会建立一个RPC链接。用scoket传输数据。
datanode和client之间有两个线程,一个负责调用scoket,往里写数据,写完后执行wait()阻塞。
还有一个负责scoket的读。消息来了后执行notify()唤醒线程
3.数据信息
一个socket的RCP方式吞吐量并不大,传递控制信息可以。但是传递数据信息尚有不足。所以hdfs用了另外一种通信机制。XceiverServer
DataNode启动的时候会创建DataXceiverServer负责block读写。其工作内容为一有链接就创建DataXceiver
DataXceiver也是一个线程,它负责处理对应的一个连接,主要完成4种任务:
opReadBlock: 读取一个block
opWriteBlock: 写一个block到disk上
opCopyBlock: 读一个block,然后送到指定的目的地
opReplaceBlock: 替换一个block
DataXceiverServer对于每个链接都会创建一个DataXceiver线程。当两个datanode数据请求频繁的时候。就会建立多个链接,吞吐量up
4.总结
Xciver方式使用的是one thread per request模型。每一个请求创建一个线程。
这种模型的缺点是当请求量大时,因为并发数多,会涉及到很多context switch。
那为什么hdfs还是用这个模型呢?我们观察三个实体和三者间的交互
datanode和client的交互
在读操作中,是由多个datanode并发的给client发送数据。但是client数量不会太多,一般开发人员只是会留固定的接口。
在写操作中,一个client会向第一个datanode点对点的发送数据,后续block由第一个datanode链式传递给其他node。所以数量不多。
datanode之间的交互
datanode间不涉及读操作,读是datanode和client直接交互
写操作:只有datanode间会复制block,且一对一链式传递。