草庐IT

一篇文章彻底理解 HDFS 的安全模式

明哥的IT随笔 2023-05-22 原文

一篇文章彻底理解 HDFS 的安全模式

1 什么是 HDFS 的安全模式

Hdfs 的安全模式,即 HDFS safe mode, 是 HDFS 文件系统的一种特殊状态,在该状态下,hdfs 文件系统只接受读数据请求,而不接受删除、修改等变更请求,当然也不能对底层的 block 进行副本复制等操作。

从本质上将,安全模式 是 HDFS 的一种特殊状态,而 HDFS 进入该特殊状态的目的,是为了确保整个文件系统的数据一致性/不丢失数据,从而限制用户只能读取数据而不能改动数据的。

2 什么情况下 HDFS 会进入安全模式

HDFS 进入安全模式的情况分为两种,即主动进入与被动进入。

2.1 HDFS 被动进入安全模式

管理员出于运维管理等各种原因,可以主动执行命令让 hdfs 进入安全模式,相关的命令有:hdfs dfsadmin -safemode enter/get/leave;

2.2 HDFS 主动进入安全模式

HDFS 也可能会主动进入安全模式,这种情况更为常见,是 HDFS 在特殊状况下,为了保证整个文件系统的数据一致性/整个文件系统不丢失数据,而主动进入的一种自我保护状态,底层根本原因又分为两种:

  • HDFS 底层启动成功并能够跟 namenode 保持定期心跳的 datanode 的个数没有达到指定的阈值, 阈值通过参数 dfs.namenode.safemode.min.datanodes 指定;
  • HDFS 底层达到了最小副本数要求的 block 的百分比没有达到指定的阈值:最小副本数通过参数 dfs.namenode.replication.min/dfs.namenode.safemode.replication.min 指定,阈值通过参数 dfs.namenode.safemode.threshold-pct 指定;
  • 当然如果 HDFS 底层启动成功并能够跟 namenode 保持定期心跳的 datanode 的个数没有达到指定的阈值,此时HDFS 底层达到最小副本数要求的 block 的百分比一般也都不会达到指定的阈值;
  • 不难理解,正常情况下,HDFS 启动过程中会有一段时间主动进入安全模式并在一段时间后主动退出安全模式,这是由 hdfs 的分本式架构决定的,因为 namenode 启动成功后,需要等待 datanode 启动成功并通过心跳汇报 datanode 上存储的 block 的信息(block report),只有在掌握了足够的 block 的信息(达到最小副本数要求的 block 占所有 block 的百分比达到指定的阈值),并等待特定时间后(通过参数 dfs.namenode.safemode.extension 30000控制),才会主动退出安全模式。

从现实情况来看,常见的HDFS进入安全模式的直接原因有:

  • 部分 datanode 启动失败或者因为网络原因与 namenode 心跳失败;
  • 部分 datanode 节点存储 hdfs 数据的磁盘卷有损坏,导致存储在该磁盘卷中的数据无法读取;
  • 部分 datanode 节点存储 hdfs 数据的磁盘分区空间满,导致存储在该磁盘卷中的数据无法正常读取;

3 HDFS 进入安全模式怎么办?

3.1 分析原因

当 HDFS 主动进入安全模式后,首先需要分析其主动进入安全模式的原因,可以通过以下途径进行分析:

  • 查看 namenode webui:可以查看 hdfs namenode webui 的 “overview”/“Startup Progress”/“Datanode Volume Failures” 等页面;
  • 查看 namenode 和 datanode 日志,可以直接查看后台主机特定目录下的文件,如 /var/log/hadoop-hdfs目录下的 hadoop-hdfs-hdfs-datanode-node1.out/hadoop-cmf-hdfs-NAMENODE-node1.log.out 等文件,也可以通过 CM 等管控台的 “诊断-日志” 等页面指定服务指定时间指定日志级别进行搜索;
  • 比如如下报错日志,即提示了 /dev/mapper/rhel-root 对应的文件系统即根目录磁盘空间不足,hadoop自动进入了安全模式:
- org.apache.hadoop.hdfs.server.namenode.FSNamesystem:NameNode low on available disk space.Already in safemode.
- org.apache.hadoop.hdfs.StateChange: STATE* Safemode is ON. Resources are low on NN. Please add or free up more resources then turn off safemode manually. NOTE:If you turn off safemode before adding resources,the NN will immediately return to safemode. Use"hdfs dfsadmin -safemode leave" to turn safemode off.
- org.apache.hadoop.hdfs.server.namenode.NameNodeResourceChecker:Space available on volume '/dev/mapper/rhel-root' is 103092224, which is below the configured reserved amount 104857600

3.2 修复问题

通过以上排查确认进入安全模式的原因后,就可以进行针对性的修复了:

  • 比如如果有 datanode 未启动成功,则尝试修复并启动对应的 datanode;
  • 比如如果有 datanode 存储 hdfs 数据的磁盘分区空间满,则尝试扩展磁盘分区空间;
  • 比如如果有 datanode 存在存储卷故障,则尝试修复存储卷,如果无法修复则需要替换存储卷(会丢失存储卷上的数据);
  • 需要注意的是,如果出现了某些 datanode 节点彻底损坏无法启动,或某些 datanode 节点磁盘卷故障彻底无法修复的情况,则这些数据对应的 block 及 block 上层的 hdfs 文件,就被丢失了,后续可能需要联系业务人员补数据(从上游重新拉取数据,或重新运行作业生成数据),如果业务人员也无法补数据,这些数据就被彻底损坏无法恢复了;
  • 可以通过如下命令查看丢失的 block 及这些 block 对应的上层 hdfs 文件,并记录下来后续交给业务人员去判断是否需要补数据:hdfs fsck / -list-corruptfileblocks,hdfs fsck / -files -blocks -locations;
  • 对于不存在数据丢失的情况,按照上述方式修复并重启集群后,HDFS 就会退出安全模式并正常对外提供读写服务;
  • 对于存在数据丢失的情况,需要通过如下命令手动退出安全模式并删除损坏的/丢失的 block 对应的上层 hdfs 文件:
    • 退出安全模式(只有退出安全模式才能删除数据):sudo -u hdfs hdfs dfsadmin -safemode leave;
    • 删除丢失的 blockd 对应的上层 hdfs 文件(自动检查文件系统并把丢失的block的上层hdfs文件删除):sudo -u hdfs hdfs fsck / -delete;
    • 在删除了丢失的 block 对应的上层 hdfs 文件后,HDFS 底层达到最小副本数要求的 block 的百分比就达到了指定的阈值(总文件数降低了总 block数也相应降低了,所以成功汇报的block的百分比就相应上升达到阈值了),所以重启后也就能够正常退出安全模式并正常对外提供读写服务了;

3.3 修复问题的错误方法

不对 hdfs 主动进入安全模式的具体原因进行分析,而是直接通过如下方法强制退出安全模式,是无脑的错误示范:

  • 直接通过命令强制退出安全模式:sudo -u hdfs hdfs dfsadmin -safemode leave
  • 不经分析直接删除损坏的文件:sudo -u hdfs hdfs fsck / -delete
  • 直接更改相关参数降低安全模式阈值:比如 dfs.namenode.safemode.threshold-pct/dfs.namenode.safemode.min.datanodes;

4 HDFS 安全模式相关参数

HDFS 安全模式相关参数有:

- dfs.namenode.safemode.threshold-pct: 副本数达到最小要求的 block 占系统总block数的百分比, default 0.999f,Specifies the percentage of blocks that should satisfy the minimal replication requirement defined by dfs.namenode.replication.min. Values less than or equal to 0 mean not to wait for any particular percentage of blocks before exiting safemode. Values greater than 1 will make safe mode permanent;
- dfs.namenode.safemode.min.datanodes:离开安全模式的最小可用datanode数量要求,default 0,Specifies the number of datanodes that must be considered alive before the name node exits safemode. Values less than or equal to 0 mean not to take the number of live datanodes into account when deciding whether to remain in safe mode during startup. Values greater than the number of datanodes in the cluster will make safe mode permanent;
- dfs.namenode.safemode.extension:集群可用 block 比例、可用 datanode 都达到要求之后,自动退出安全模式的时延,default	30000,Determines extension of safe mode in milliseconds after the threshold level is reached. Support multiple time unit suffix (case insensitive), as described in dfs.heartbeat.interval;
- dfs.namenode.safemode.replication.min: 判断能否退出安全模式时对 block 的最小副本数的要求,默认为1,a separate minimum replication factor for calculating safe block count. This is an expert level setting. Setting this lower than the dfs.namenode.replication.min is not recommend and/or dangerous for production setups. When it's not set it takes value from dfs.namenode.replication.min;
- dfs.namenode.replication.min: block 的最小副本数,default 1,	Minimal block replication;
其他磁盘预留空间大小类参数:dfs.datanode.du.reserved/dfs.datanode.du.reserved.pct/dfs.datanode.du.reserved.calculator/dfs.namenode.resource.du.reserved/dfs.namenode.resource.checked.volumes/dfs.namenode.resource.checked.volumes.minimum;

5 一个某客户生产环境HDFS 进入安全模式的修复案例

某客户线上业务系统中的大数据 HIVE 作业无法运行,查看 hdfs 发现进入了安全模式,如下所示:

进一步查看发现,所有 datanode 都成功启动了,但部分 datanode 存在存储卷故障,且这些存储卷背后是 nfs 网络文件系统,如下所示:

查看 datanode日志发现,datanode 底层的 DataXceiver 线程无法读取部分 block,导致 ReplicaNotFoundException:

通过 CM 管控台的 “诊断-日志” 页面,指定服务为HDFS,指定时间为近期1个小时,指定日志级别为 WARN,搜索发现,调用方法
user=pwd.getpwuid(s.st_uid) 时报错了:keyError:‘getpwuid(): uid not found: 4294967294’,且报错对应的正是 nfs 网盘目录:

通过 ls 命令查看发现,上述报错对应的 nfs 网盘目录的 owner显示的正是错误信息中的 4294967294,而不是用户名比如 hdfs等,且通过命令 ”uid hdfs“ 查看发现 hdfs 对应的uid并不是4294967294:

至此问题确认,概括如下:

  • nfs 挂载的目录被认为是 “Datanode Volume Failures” ,所以 nfs 目录下的 block 数据对 hdfs 不可读写,所以副本数达到最小要求的 block 占系统总 block 数的百分比达不到默认的阈值,hdfs 出于数据一致性的要求,自动进入了安全模式;

  • 而导致 hdfs 无法读写 nfs 对应目录下的 block数据的原因是,不知出于何种原因,nfs 对应目录的 owner/group 显示的是 4294967294/4294967294,而不是期望的 hdfs/hdfs,所以底层调用方法 user=pwd.getpwuid(s.st_uid)获取 nfs 对应目录的woner/group 时,报错了:keyError:‘getpwuid(): uid not found: 4294967294’,最后 hdfs 因为无法获取 nfs 对应目录的 owner/group 而无法读取该目录下的文件;

  • 为修复问题,手动通过命令 chown 更改了nfs 对应目录的 owner/group 为 hdfs/hdfs,然后重启 hdfs,在重启后 hdfs 自动进入并自动退出了安全模式,正常对外提供读写服务。

  • 为避免节点重启再出现上述问题,后续安排了了解 nfs 的运维同学帮忙排查下 nfs 挂载的目录为什么显示的 owner/group 是 4294967294/4294967294 而不是 hdfs/hdfs。

  • 最后需要强调说明下,由于 NFS 在性能和稳定性上相比本地磁盘差距不小,不建议在 hdfs 底层使用 nfs 网盘。(如果在测试等环境使用 nfs 网盘,一定要记得需要通过修改文件 /etc/fstab 确保开机自动挂载 nfs).

有关一篇文章彻底理解 HDFS 的安全模式的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  5. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  6. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  7. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  8. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  9. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  10. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

随机推荐