【概述】
在HDFS中,namenode保存了整个HDFS的元数据信息,而这些数据最终会被持久化到fsimage文件和editLog文件。换而言之,namenode的元数据信息由fsimage和editlog组成。其中,fsimage存放上次checkpoint生成的文件系统元数据,而editLog则存放文件系统的操作日志;也就是用户对目录、文件的每个写操作(包括创建、删除、写入等)都会被记录到editlog文件中。
namenode在响应客户端的文件(目录)操作请求时,会先更新在内存中记录的对应的元数据信息,然后再把这些操作记录写入到editlog文件中。
记录在editLog文件中的每个操作都是一个独立的事务,每个事务有相应的操作码,唯一的事务ID以及操作对应的数据信息等。事务ID是由namenode统一管理的,采用递增的方式,为每个操作赋予唯一的事务ID。最后一次操作的事务ID还会被写入到文件(seen_txid),namenode重启后会读取这些信息,并在最后一次事务ID上继续递增。
每个editLog文件的文件名都有固定的格式,其中当前正在写的文件名格式为edits_inprogress_TXID,TXID为该文件中记录的第一个操作的事务ID;已经写完成的editlog文件名为 edts_StartTXID_EndTXID,StartTXID为该文件中记录的第一个操作的事务ID,EndTXID为该文件中记录的最后一个操作的事务ID。实际示例如下图所示:
在单机模式下,editLog文件被保存在本地指定的目录中;而在HA的模式下,editLog文件除了保存在本地指定目录外,还会保存在指定的共享目录中。例如,共享目录设置为qjournal形式,即通过journal node保存editlog,那么namenode会将每条操作日志通过rpc的方式发送给journal node,journal node收到后再写入本地的editLog文件中。
【刷盘机制】
上面讲到了namenode响应客户端的操作后,会将操作日志写入到editLog文件中,那么editLog文件的刷盘机制是怎样的呢?也就是editLog文件中的内容什么时候会被真正写入到磁盘呢?
1) SNN触发刷盘
在配置了HA的模式下,SNN(standby namenode,后面均简称SNN)为了尽可能的保持与ANN(active namenode,后面均简称ANN)的元数据一致,因此会不断从ANN中读取editLog文件的内容,这样当ANN出现异常时,可以快速接管。
因此,在SNN中,每隔一段时间就会检测当前时间距离上一次刷盘的时间是否超过了指定的值,如果超过了则通过rpc请求触发ANN进行editLog的刷盘,然后再从ANN中读取edtiLog文件的内容。
2) ANN触发刷盘
ANN启动后,也会定时进行检测,当未刷盘的操作事务累计到一定数量后,触发进行刷盘动作。
另外,editLog文件打开时,设置了一定大小的缓存(512KB),每个操作事务都是先写入缓存,每次写完后,判断当前缓存大小是否超过了设置的指定大小,如果是则将缓存中的内容刷到磁盘上。
实际上,你还可以通过配置进行设置,每一条操作写入文件后,都立即进行刷盘,这种方式不是默认配置,也不推荐使用(毕竟有性能损耗)。
相关的配置有:
-
dfs.ha.tail-edits.period
SNN中定时检测的时间间隔,单位(秒),默认值为60
-
dfs.ha.log-roll.period
刷盘周期,即SNN的定时检测发现距离上次刷盘超过该时间值时,触发刷盘,单位(秒),默认值为120
-
dfs.namenode.checkpoint.txns
事务累计达到该值时,触发checkpoint
-
dfs.namenode.edit.log.autoroll.multipiler.threshold
触发刷盘的事务数量系数,即每当操作事务数量达到TxNum(计算方式如下)时会触发editLog的刷盘,刷盘后再重新开始计数。
TxNum = dfs.namenode.checkpoint.txns * dfs.namenode.edit.log.autoroll.multipiler.threshold
【文件格式】
editLog文件的文件格式其实很简单,如下图所示:文件开头是固定长度的版本号,然后是一个开始标识,接下来是一条一条的操作记录,最后是一个结束标识。整个文件以二进制数据内容进行存储。
版本号的长度为16字节;每个操作记录都包含了操作对应的操作码,操作对应的事务ID,该操作记录总的字节长度,以及每个操作不同的数据内容。
由于editLog文件采用二进制的存储方式,不方便直接进行查看,因此hdfs提供了命令将editLog转换为其他格式方便查看。
例如:下面的命令将一个editLog文件转换为xml格式并保存在tmp.xml文件中
hdfs oev -i edits_0000000000000000810-0000000000000000812 -o tmp.xml
查看该文件内容:
从上面的文件内容中可以看到几点
1)该editLog文件中只有一条操作记录,即创建了/hncswc目录
2)开始标识符和结束标识符都有自己对应的操作码和事务ID,也就是说,开始标识符和结束标识符本质上也是一条操作记录
【总结】
本文简单讲述了editLog的相关知识,例如editLog的文件格式,文件查看,刷盘机制等。但也还有一部分内容未涉及:例如editLog文件是否有上限,如果有,上限是多少,到达上限后会怎样?另外,元数据由fsimage和editLog组成,fsiamge和editLog的关系是怎样的。。。
上述这些疑问都将在下篇文章《hdfs——fsimage》会进行说明,敬请期待。