前面文件介绍了dn的持久化文件与对应的数据结构,本文来介绍写dn的整体架构,以及dn的启动流程。
【整体架构】
如图所示,从功能逻辑上来划分,dn的架构可以分为三层。
最上层为服务层,这一层主要包括三个模块:
RpcServer
对外提供RPC服务,即来自客户端,namenode(后面均简称为nn),其他所有dn的rpc请求处理入口。
DataXceiver
数据传输服务,客户端对block的读写数据传输,以及dn与dn之间数据副本的拷贝都是通过该服务完成的。
DatanodeHttpServer
对外提供http服务,主要用于展示dn内部的一些状态。
底层为数据存储层,dn中的所有服务都是在数据存储的基础上完成的,具体可以分为两个部分:
FsDataset:抽象了dn中数据块的所有操作,可以理解为负责dn中block的创建、读、写、删除等操作与管理,详细参考《DN的存储数据结构》
DataStorage:负责管理和组织dn中的磁盘存储空间,同时也负责管理存储空间的生命周期(包括升级、回滚等操作)。
在DataStorage中,包含了一个以BlockPoolID为key,value为BlockPoolSliceStorage的map表,用于BlockPool的磁盘存储管理。
中间一层为逻辑业务层,这一层主要包含的模块有:
BlockPoolManager:
HDFS在引入联邦之后,dn会存储多个blockpool的信息,而每个blockpool位于一个命名空间中,即一个blockpool位于一个(对)nn中。
因此,BlockPoolManager模块中会包含一个BPOfferService的列表,每个BPOfferService对应于一个BP,在BPOfferService中又包含一个或一对BPServiceActor,分别负责与该BP所在的ActiveNameNode和StandbyNameNode通信,具体包括心跳上报,block全量汇报,block增量汇报,并执行心跳响应中所携带的nn下发的命令。
DirectoryScanner:
负责进行磁盘目录的扫描,检查磁盘目录中的block文件与内存中记录的block是否一致,如果不一致,会额外进行标记,并通过block汇报的时候上报nn。
BlockScanner:
负责dn中所有block数据的完整性校验。
【DN的启动流程】
了解了DN的整体框架后,来看看DN的启动流程。
依次构造DataNode、DataStorage、DataXceiver、DatanodeHttpServer对象。
构造BlockPoolManager对象,然后根据配置项构造一个或多个BPOfferService对象,在BPOfferService内部根据对应的nn地址,分别为每个nn构造一个BPServiceActor对象。
BPServiceActor内部会启动一个线程,该线程运行后首先会与nn建立连接,然后请求nn的命名空间信息。
收到nn命名空间请求的响应后(响应中会包含命名空间的信息,BP的信息等),完成FsDataset相关对象的初始化,具体包括根据配置的目录依次构建出FsVolume,读取目录下的BP目录,构造出BlockPoolSlice;然后扫描BP下rbw,finalized目录中的block文件,在内存中构造出完整的ReplicaMap(扫描文件名,但不读取具体的文件内容);最后初始化目录扫描器DirectoryScanner,并启动扫描。
完成FsDataset相关信息的构造后,BPServiceActor中的线程将继续向nn进行注册,注册需要上报dn磁盘容量等存储相关的信息。
完成注册后,BPServiceActor的线程进入循环,定期向nn发送心跳,处理nn下发的命令,同时ipcServer和DataXceiver开始正常提供服务。
本文就介绍到这里,后续将继续分享dn中的一些具体实现逻辑,敬请期待,同时也欢迎交流分享。。。