HDFS文件系统——编辑日志和镜像文件详细介绍
我们知道,启动Hadoop之后,在主节点下会产生Namenode,即名称节点进程,该节点的目录下会保存一份元数据,用来记录文件的索引,而在从节点上即Datanode则会保留真实的数据,对于Namenode来说,最重要的两个文件就是Fsimage和Edits了,它们记录了用户的一系列在文件系统中的操作并保存了文件索引
1. 初始化文件系统基本步骤
为了演示这两个文件的详细介绍,我们首先需要格式化文件系统,由于之前搭建了高可用,因此必须严格按照顺序执行命令,具体步骤如下:
1. 关闭所有进程
stop-all.sh
xzk.sh stop
2. 使用xcall命令删除所有节点/home/centos/ha文件夹
xcall.sh rm -rf /home/centos/ha
3. 启动zookeeper,注意zk一定要先启动!!!
xzk.sh start
4. 启动s102-s104节点的journalnode进程
hadoop-daemons.sh start journalnode
5. 在zookeeper上初始化元数据,注意这一步一定要先进行,否则Namenode将会格式化失败!!!
hdfs zkfc -formatZK
6. 格式化HDFS
hdfs namenode -format
7. 将s101上的ha文件夹发送到s105上去
scp -r /home/centos/ha root@s105:/home/centos
8. 启动HDFS文件系统
多次初始化Namenode导致Datanode无法启动问题解决
由于hadoop是通过元数据中VERSION下存有的Cluster ID来标识几个节点是否是同一集群的,因此多次初始化会使得namenode和datanode的clusterID不一致,即不是同一集群,从而导致这个问题,解决方案有两个:
1. 重复上述步骤
2. 查看主节点的Cluster ID,将这个ID复制到从节点的VERSION文件中去即可,路径为/home/centos/ha/dfs/data/current,查看主节的ID为:
2. 编辑日志和镜像文件详细介绍
我们首先查看一下最原始的Namenode下的文件有哪些:
VERSION文件加载了Cluster ID,seen_txid记录的是transaction id,事务ID,镜像文件后缀序列从0起步,存储真正的索引文件,包括但不限于权限,大小以及文件名,编辑日志即edits_inprogress文件序号从1起步,记录了hadoop从开启到关闭,用户的所有操作
为了探究在进行某步操作时,编辑日志以及镜像文件这两个文件究竟发生了什么样的变化,需要进行测试:
put一个文件到HDFS上去,hdfs dfs -put /root/wc.txt /,第一个实验我们将root家目录下预先放好的名为wc.txt的文件put到HDFS的根目录下
查看current目录下的文件,发现是这样的结构:
发现出现了类似于edits_0000000000000000001-edits_0000000000000000002这样的文件,后缀总是用两个数字作为编号,而edits_inprogress文件又重新生成了一份,而从目录信息中的时间又可知,编辑日志是每两分钟滚动一次的,每滚动一次就将edits_inprogress文件实例化成edits文件,而同时又新生成一份edits_inprogress文件,后缀的序号是旧的edits文件后缀最大序号加1
那么这个edits文件里面到底是什么内容呢,由于这个文件无法直接cat查看,为了一探究竟,我们使用了hdfs oev -i edits_0000000000000000006-0000000000000000013 -o ~/edits.xml -p xml命令进行查看,得到以下信息:
xml version="1.0" encoding="UTF-8"?> <EDITS> <EDITS_VERSION>-63EDITS_VERSION> <RECORD> <OPCODE>OP_START_LOG_SEGMENTOPCODE> <DATA> <TXID>6TXID> DATA> RECORD> <RECORD> <OPCODE>OP_ADDOPCODE> <DATA> <TXID>7TXID> <LENGTH>0LENGTH> <INODEID>16386INODEID> <PATH>/wc.txt._COPYING_PATH> <REPLICATION>3REPLICATION> <MTIME>1574260053772MTIME> <ATIME>1574260053772ATIME> <BLOCKSIZE>134217728BLOCKSIZE> <CLIENT_NAME>DFSClient_NONMAPREDUCE_-929106461_1CLIENT_NAME> <CLIENT_MACHINE>192.168.153.101CLIENT_MACHINE> <OVERWRITE>trueOVERWRITE> <PERMISSION_STATUS> <USERNAME>rootUSERNAME> <GROUPNAME>supergroupGROUPNAME> <MODE>420MODE> PERMISSION_STATUS> <RPC_CLIENTID>48f6f0ee-0e35-4b0f-86b1-b2df41b2c4cdRPC_CLIENTID> <RPC_CALLID>3RPC_CALLID> DATA> RECORD> <RECORD> <OPCODE>OP_ALLOCATE_BLOCK_IDOPCODE> <DATA> <TXID>8TXID> <BLOCK_ID>1073741825BLOCK_ID> DATA> RECORD> <RECORD> <OPCODE>OP_SET_GENSTAMP_V2OPCODE> <DATA> <TXID>9TXID> <GENSTAMPV2>1001GENSTAMPV2> DATA> RECORD> <RECORD> <OPCODE>OP_ADD_BLOCKOPCODE> <DATA> <TXID>10TXID> <PATH>/wc.txt._COPYING_PATH> <BLOCK> <BLOCK_ID>1073741825BLOCK_ID> <NUM_BYTES>0NUM_BYTES> <GENSTAMP>1001GENSTAMP> BLOCK> <RPC_CLIENTID>RPC_CLIENTID> <RPC_CALLID>-2RPC_CALLID> DATA> RECORD> <RECORD> <OPCODE>OP_CLOSEOPCODE> <DATA> <TXID>11TXID> <LENGTH>0LENGTH> <INODEID>0INODEID> <PATH>/wc.txt._COPYING_PATH> <REPLICATION>3REPLICATION> <MTIME>1574260055275MTIME> <ATIME>1574260053772ATIME> <BLOCKSIZE>134217728BLOCKSIZE> <CLIENT_NAME>CLIENT_NAME> <CLIENT_MACHINE>CLIENT_MACHINE> <OVERWRITE>falseOVERWRITE> <BLOCK> <BLOCK_ID>1073741825BLOCK_ID> <NUM_BYTES>75NUM_BYTES> <GENSTAMP>1001GENSTAMP> BLOCK> <PERMISSION_STATUS> <USERNAME>rootUSERNAME> <GROUPNAME>supergroupGROUPNAME> <MODE>420MODE> PERMISSION_STATUS> DATA> RECORD> <RECORD> <OPCODE>OP_RENAME_OLDOPCODE> <DATA> <TXID>12TXID> <LENGTH>0LENGTH> <SRC>/wc.txt._COPYING_SRC> <DST>/wc.txtDST> <TIMESTAMP>1574260055288TIMESTAMP> <RPC_CLIENTID>48f6f0ee-0e35-4b0f-86b1-b2df41b2c4cdRPC_CLIENTID> <RPC_CALLID>9RPC_CALLID> DATA> RECORD> <RECORD> <OPCODE>OP_END_LOG_SEGMENTOPCODE> <DATA> <TXID>13TXID> DATA> RECORD> EDITS>
原来,简简单单一个put操作竟分成了那么多个操作步骤,仔细查看,可知,一共分成了,
OP_START_LOG_SEGMENT OP_ADD OP_ALLOCATE_BLOCK_ID OP_SET_GENSTAMP_V2 OP_ADD_BLOCK OP_CLOSE OP_RENAME_OLD
这7个步骤,在最后一个步骤中将之前的._COPYING_后缀去掉,正式重命名为原文件名,而每增添一个操作步骤,事务ID即TXID就会自增1,难怪我们在current目录下发现了edits_0000000000000000006-0000000000000000013这个文件,原来这两个数字就是事务ID的开始和结束编号!!!
我们查看了Edits文件,现在再来看一下fsimage文件是怎样的:
xml version="1.0"?> <fsimage> <NameSection> <genstampV1>1000genstampV1> <genstampV2>1002genstampV2> <genstampV1Limit>0genstampV1Limit> <lastAllocatedBlockId>1073741826lastAllocatedBlockId> <txid>41txid> NameSection> <INodeSection> <lastInodeId>16387lastInodeId> <inode> <id>16385id> <type>DIRECTORYtype> <name>name> <mtime>1574261024683mtime> <permission>root:supergroup:rwxr-xr-xpermission> <nsquota>9223372036854775807nsquota> <dsquota>-1dsquota> inode> <inode> <id>16387id> <type>FILEtype> <name>wc.txtname> <replication>3replication> <mtime>1574261024676mtime> <atime>1574261024495atime> <perferredBlockSize>134217728perferredBlockSize> <permission>root:supergroup:rw-r--r--permission> <blocks> <block> <id>1073741826id> <genstamp>1002genstamp> <numBytes>75numBytes> block> blocks> inode> INodeSection> <INodeReferenceSection>INodeReferenceSection> <SnapshotSection> <snapshotCounter>0snapshotCounter> SnapshotSection> <INodeDirectorySection> <directory> <parent>16385parent> <inode>16387inode> directory> INodeDirectorySection> <FileUnderConstructionSection>FileUnderConstructionSection> <SnapshotDiffSection> <diff> <inodeid>16385inodeid> diff> SnapshotDiffSection> <SecretManagerSection> <currentId>0currentId> <tokenSequenceNumber>0tokenSequenceNumber> SecretManagerSection> <CacheManagerSection> <nextDirectiveId>1nextDirectiveId> CacheManagerSection> fsimage>
我们可以发现,镜像文件fsimage实际上就是记录了整个HDFS文件系统的树形结构,比如父目录是什么,子文件是什么它们的用户是谁,权限是什么,在什么时候创建的等等详细信息,也就是真正的索引文件
2.1 HDFS启动过程详解
1. 加载镜像文件
将镜像文件中存储的索引信息载入到内存
2. 加载编辑日志
将edits_inprogress文件实例化为edits文件(hdfs dfsadmin -rollEdits),创建新的edits_inprogress文件
3. 保存检查点,更新镜像文件
将旧的镜像文件,执行新的edits文件的操作步骤,生成新的镜像文件到磁盘
4. 进入到安全模式
以上三个步骤操作时,集群会处于仅可读的状态,此状态被称为安全模式
5. datanode报告信息
启动之后,datanode会每隔三秒钟向namenode发送ping信息,证明自己还活着,因此,查看这一页面,如果发现Last contact的秒数大于3,就说明某一Datanode已经死亡
2.2 Secondarynamenode(辅助名称节点)讲解
之前提到,由于在进行编辑日志和镜像文件融合的过程中会进入到Safe mode,这个动作进行的频率是每一小时一次,而一旦进入到安全模式用户是没办法进行任何操作的,因此会造成麻烦,于是引入辅助名称节点的概念,相当于edit继续记录,但是合并的过程给到Secondarynamenode去做了,合并过程不需要进入到safe mode,其实就是为了在合并的时候仍然可以对用户提供服务;另一个好处就是Secondarynamenode相当于是对主节点做了一个备份,保证了一个安全性,具体工作流程见下图:
2.3 手动操作编辑日志和镜像文件的方法
手动滚动编辑日志:
hdfs dfsadmin -rollEdits
手动融合镜像文件:
需要首先进入安全模式
hdfs dfsadmin -safemode enter
融合过程也会触发重新滚动编辑日志的操作
hdfs dfsadmin -saveNamespace
离开安全模式
hdfs dfsadmin -safemode leave