namenode元数据多目录配置及测试

1. 配置方法

namenode元数据的配置属性为:dfs.namenode.name.dir
多个目录以逗号分隔即可(注意使用ambari配置时,要使用换行符)
目录所属者需要改成hdfs:hadoop,不然会没有写权限。

另外这里多个目录应该要挂载到不同磁盘,才能达到容错性提升的用途。

配置完后重启namenode,但是这时候新的目录是没数据的,要新的目录有数据有两种方法
1、手动copy旧目录的文件(最好先停止namenode服务后操作)
2、手动执行checkpoint,由namenode自动写fsimage到目录
先进入安全模式:su hdfs -l -c ‘hdfs dfsadmin -safemode enter’
执行checkpoint:su hdfs -l -c ‘hdfs dfsadmin -saveNamespace’
退出安全模式:su hdfs -l -c ‘hdfs dfsadmin -safemode leave’

2. 目录故障测试

1、NFS作为存储目录,且NFS服务挂掉

会导致hdfs写文件阻塞,进而会导致namenode挂掉
查看JVM堆栈,可以看到大量线程阻塞在磁盘读取上
因此暂不考虑使用NFS的方式

2、测试某个目录无法读写

把/data/hadoop/hdfs/namenode2的所属者改成root,且chmod 700,让namenode进程对目录没有任何权限
这时进行hdfs读写测试,发现仍然可以正常读写数据

分别观察/data/hadoop/hdfs/namenode/current和/data/hadoop/hdfs/namenode2/current目录下的edits文件,前者会有新的eits文件产生,后者则没有,符合预期

错误日志:

2022-05-13 09:42:01,710 ERROR namenode.FSEditLog (JournalSet.java:mapJournalsAndReportErrors(402)) - Error: starting log segment 616462865 failed for (journal JournalAndStream(mgr=FileJournalManager(root=/data/hadoop/hdfs/namenode2), stream=null))
java.io.FileNotFoundException: /data/hadoop/hdfs/namenode2/current/edits_inprogress_0000000000616462865 (Permission denied)

结合程序代码,是namenode尝试把edits_inprogress_xxx文件rename为edits_xxx文件时报没有权限的错

namenode ui也显示/data/hadoop/hdfs/namenode2状态为fail:
namenode元数据多目录配置及测试_第1张图片
ambari上也有对应告警:
namenode元数据多目录配置及测试_第2张图片
然后把/data/hadoop/hdfs/namenode2的所属者还原为hdfs,再进行观察
这时候新的editslog可以写入了,但是发生故障这段期间的edits文件是丢失了的,不过namenode在启动的时候,是从JournalNode读取edits文件的,所以理论应该没有影响
不过保险起见,最好手工执行下checkpoint操作,把本地fsimage文件更新为最新

3、两个目录都无法读写

把两个目录的所属者都改成root,且chmod 700

namenode直接挂掉

关键错误日志:

2022-05-13 10:14:09,275 WARN  namenode.FileJournalManager (FileJournalManager.java:startLogSegment(128)) - Unable to start log segment 616464161 at /data/hadoop/hdfs/namenode2/current/edits_inprogress_0000000000616464161: /data/hadoop/hdfs/namenode2/current/edits_inprogress_0000000000616464161 (Permission denied)
2022-05-13 10:14:09,275 ERROR namenode.FSEditLog (JournalSet.java:mapJournalsAndReportErrors(402)) - Error: starting log segment 616464161 failed for (journal JournalAndStream(mgr=FileJournalManager(root=/data/hadoop/hdfs/namenode2), stream=null))
java.io.FileNotFoundException: /data/hadoop/hdfs/namenode2/current/edits_inprogress_0000000000616464161 (Permission denied)
 
...
 
2022-05-13 10:14:09,275 ERROR namenode.FSEditLog (JournalSet.java:disableAndReportErrorOnJournals(352)) - Disabling journal JournalAndStream(mgr=FileJournalManager(root=/data/hadoop/hdfs/namenode), stream=null)
2022-05-13 10:14:09,276 ERROR namenode.FSEditLog (JournalSet.java:disableAndReportErrorOnJournals(352)) - Disabling journal JournalAndStream(mgr=FileJournalManager(root=/data/hadoop/hdfs/namenode2), stream=null)
2022-05-13 10:14:09,276 ERROR namenode.FSEditLog (JournalSet.java:mapJournalsAndReportErrors(411)) - Error: starting log segment 616464161 failed for too many journals
2022-05-13 10:14:09,276 INFO  ipc.Server (Server.java:logException(2726)) - IPC Server handler 397 on 8020, call Call#163 Retry#0 org.apache.hadoop.hdfs.server.protocol.NamenodeProtocol.rollEditLog from 172.19.103.9:52254
 
...
 
2022-05-13 10:14:09,901 ERROR namenode.FSEditLog (JournalSet.java:mapJournalsAndReportErrors(411)) - Error: write op failed for too many journals
2022-05-13 10:14:09,902 ERROR namenode.FSEditLog (FSEditLog.java:logSync(691)) - Could not sync enough journals to persistent storage due to No journals available to flush. Unsynced transactions: 1
java.lang.Exception
        at org.apache.hadoop.hdfs.server.namenode.FSEditLog.logSync(FSEditLog.java:691)
        at org.apache.hadoop.hdfs.server.namenode.FSEditLogAsync.run(FSEditLogAsync.java:188)
        at java.lang.Thread.run(Thread.java:748)
 
...
 
2022-05-13 10:14:09,906 FATAL namenode.FSEditLog (JournalSet.java:mapJournalsAndReportErrors(390)) - Error: close journal failed for required journal (JournalAndStream(mgr=QJM to [172.19.103.8:8485, 172.19.103.7:8485, 172.19.103.9:8485], stream=QuorumOutputStream starting at txid 616464161))
java.io.IOException: FSEditStream has 205 bytes still to be flushed and cannot be closed.
        at org.apache.hadoop.hdfs.server.namenode.EditsDoubleBuffer.close(EditsDoubleBuffer.java:74)
        at org.apache.hadoop.hdfs.qjournal.client.QuorumOutputStream.close(QuorumOutputStream.java:67)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet$JournalAndStream.closeStream(JournalSet.java:103)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet$JournalAndStream.close(JournalSet.java:111)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet$3.apply(JournalSet.java:235)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet.mapJournalsAndReportErrors(JournalSet.java:385)
        at org.apache.hadoop.hdfs.server.namenode.JournalSet.close(JournalSet.java:232)
        at org.apache.hadoop.io.IOUtils.cleanupWithLogger(IOUtils.java:280)
        at org.apache.hadoop.hdfs.server.namenode.FSEditLog.logSync(FSEditLog.java:693)
        at org.apache.hadoop.hdfs.server.namenode.FSEditLogAsync.run(FSEditLogAsync.java:188)
        at java.lang.Thread.run(Thread.java:748)
2022-05-13 10:14:09,907 WARN  client.QuorumJournalManager (QuorumOutputStream.java:abort(74)) - Aborting QuorumOutputStream starting at txid 616464161
2022-05-13 10:14:09,913 INFO  util.ExitUtil (ExitUtil.java:terminate(210)) - Exiting with status 1: Error: close journal failed for required journal (JournalAndStream(mgr=QJM to [172.19.103.8:8485, 172.19.103.7:8485, 172.19.103.9:8485], stream=QuorumOutputStream starting at txid616464161))
2022-05-13 10:14:09,922 INFO  namenode.NameNode (LogAdapter.java:info(51)) - SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at hdfs07-dev.yingzi.com/172.19.103.8
************************************************************/

4、某块磁盘写满

使用chaosd工具模拟磁盘故障
https://chaos-mesh.org/website-zh/docs/next/simulate-disk-pressure-in-physical-nodes/
在/data/hadoop/hdfs/namenode2目录建一个tmp目录,在这个目录下执行命令:chaosd attack disk fill -c 100 --fallocate=false
实际发现在磁盘还有一定空间的时候(几百k),做个合格命令就会报磁盘空间不足了。猜测是有其他进程又释放了空间
自己写一个简单的脚本去把剩余的空间填满:

while true :
do
    echo 111 >> /data/hadoop/hdfs/namenode2/tmp/tmp.txt
done

此时观察到的现象和第2点类似,只是错误日志不一样

删除tmp目录下生产的example,使磁盘空间恢复,namenode磁盘状态也自动恢复

5、磁盘写负载高

同样也使用chaosd工具模拟磁盘故障
在tmp目录下执行命令:chaosd attack disk add-payload write -s 80G -n 20

写80G数据耗时57s,平均1.4G/s

执行命令:iostat -x -t 2
可以看到磁盘的io使用率基本达到了100%:
在这里插入图片描述

chaosd命令写完80G文件就会停止执行,想要继续执行需要删除生成的文件才能继续执行
为了模拟长时间的io压力,通过脚本来不停的调用chaosd命令:

while true :
do
    echo 111
    chaosd attack disk add-payload write -s 80G -n 20
    rm -f ./example*
done

监控图如下:
namenode元数据多目录配置及测试_第3张图片
观察namenode状态未发现有异常
查看目录也能正常生成edits文件
猜测原因是namenode写edits文件本身就不频繁,对IO的要求并不高

6、结论

某个磁盘出现无法写入、磁盘满、磁盘写负载高时,不会影响namenode正常提供服务

但是如果读写磁盘时一直阻塞(比如NFS服务挂掉),则会对namenode造成较大的影响

你可能感兴趣的:(#,hdfs,备忘,hadoop,namenode多目录)