【前言】
在HDFS中,NameNode存储了整个集群的元数据信息,DataNode(下面都简称dn)负责实际数据的存储,这些数据最终持久化到磁盘中。
那么这些持久化的文件都包括哪些?分别都有什么用?某个dn节点坏了,是否直接将对应的磁盘移到另一台节点上就可以正常使用并且不会出现数据丢失呢?
带着这些问题,作者对dn持久化的文件进行了总结。
【DN的持久化文件】
dn中可以配置多个目录(通常是多块磁盘,每个磁盘挂载到一个目录,这样可以提高整体的IO性能)进行数据的存储,多个目录共同存储该dn上的block信息。
每个目录的目录树结构如下图所示:
下面针对每一项进行具体说明:
该文件的文件内容为:
$DNPID@$DNIP
其中$DNPID为dn的进程PID
$DNIP为dn所在主机的IP
文件内容(本质上是jvm的名称)是在dn启动时覆盖写入,并且会对该文件进行加锁,如果加锁失败会抛出异常并直接退出。
这样做的目录是为了防止多个dn线程并发修改这个目录。
定义了整个存储文件系统的布局,主要用于升级,具体文件内容为:
#Fri Sep 04 11:19:36 CST 2020 <-- 该文件创建的时间
storageID=DS-8aee8e5f-77c0-4aa9-904b-79cb7df84f7b <-- 存储ID, "dfs.datanode.data.dir"中指定的每个目录都具有不同的ID
clusterID=CID-c788ac91-8e7b-4972-b998-2d08cd961fb9 <-- 集群ID, 集群中的所有NN,DN具有同样的ClusterID
cTime=0 <-- namespace创建时间(格式化后为0)
datanodeUuid=3ca3bca1-65e1-4a31-aa60-1a3e7643e030 <-- Datanode的uuid, 唯一
storageType=DATA_NODE <-- 节点类型 DATA_NODE 或 NAME_NODE 或 JOURNAL_NODE
layoutVersion=-57 <-- nn或dn持久化信息在磁盘上存储信息的版本号
是一个负整数, dn或nn每增加一个特性, 版本号减1
dn启动时会遍历配置的目录列表,在内存中构造出相关的数据结构,同时会以dn的uuid作为key向namenode进行注册。
在引入Federation之后,整个集群允许存在多个BlockPool,这样同一个dn中就可能存储多个BlockPool的block,因此每个BlockPool都以各自的ID作为目录名(以BP为前缀,中间一段为BP的ID,后一段为时间戳),该目录下存储各自BlockPool中的block数据。
dn进程启动后,会定期对磁盘中的block进行扫描,用于数据完整性的校验。但由于文件数非常多,因此每次只会扫描一部分,因此scaner.cursor中就记录了当前block的扫描位置。
dfsUsed存储该BlockPool中的block数据块信息所占用的磁盘空间大小。
具体文件内容为:
$UsedSize $Timestamp
其中$UsedSize为该m兖所占用的磁盘空间大小
$Timestamp为记录时间
该文件通常是在dn停止的时候写入,在启动时读取该文件,用于汇报给nn。
和外层的VERSION文件作用是相同的。
rbw是“replica being written”的缩写,即存储该BlockPool中正在写入的block块文件。
存储该BP中已经写完的block块文件。
考虑到正在写入的block不会太多,而已经写完的block会是比较大的一个数量级,因此在rbw目录中没有再细分目录存储block文件,而在finalized中则细分两级目录存放block文件。
block存放目录位置的计算方式为:
block的ID转换为二进制,然后右移16位与0X1F进行"与"操作,得到的值为第一层subdir的ID;
同样,blockID右移8位,然后与0X1F进行"与"操作,得到的值为第二层subdir的ID。
例如,blockID为1127040185,按照上面的操作后,第一层subdir的ID为13,第二层subdir的ID为4,即该block文件存放在subdir13/subdir4目录下
[root@hncscwc finalized]# ll subdir13/subdir4/blk_1127040185
-rw-r--r-- 1 hadoop hadoop 20480 Aug 18 02:44 subdir13/subdir4/blk_1127040185
另外,BlockID从 1024*1024*1024+1=1073741825 开始
block块的具体数据。
block块对应的checksum数据。
除了上面提到的这些文件外,还有一个未列出的目录lazyPersist,该目录与rbw、finalized处于同一层级。用于支持将临时数据写入内存,然后通过懒惰持久化(lazyPersist)方式写入磁盘。只有开启该特性后才会有该目录。
【总结】
从上面的总结中,dn的持久化文件并没有与机器相关的内容,因此,一旦机器出现故障,可将对应的磁盘拨出放到其他机器上继续使用,并且数据不会丢失。