![磁盘已满时 HDFS 数据节点启动失败](https://linux22.com/image/620057/%E7%A3%81%E7%9B%98%E5%B7%B2%E6%BB%A1%E6%97%B6%20HDFS%20%E6%95%B0%E6%8D%AE%E8%8A%82%E7%82%B9%E5%90%AF%E5%8A%A8%E5%A4%B1%E8%B4%A5.png)
我们的 HDFS 集群只占 90%,但有些数据节点的某些磁盘已占 100%。这意味着当我们大规模重启整个集群时,一些数据节点完全无法启动,并显示如下消息:
2013-10-26 03:58:27,295 错误 org.apache.hadoop.hdfs.server.datanode.DataNode:java.io.IOException:Mkdirs 无法创建 /mnt/local/sda1/hadoop/dfsdata/blocksBeingWritten
只需有三次这样的故障,我们就会开始经历真正的数据丢失。
目前,我们通过减少为 root 用户保留的空间量来解决这个问题,但最终会用完。我们还几乎不断地运行重新平衡器,但有些磁盘仍然停留在 100% 上。
由于卷并未出现故障,因此更改 dfs.datanode.failed.volumes.tolerated 设置并不是解决方案。
有任何想法吗?
答案1
根据此默认 HDFS 参数,dfs.datanode.du.reserved
是每个卷的。因此,如果您将其设置为 10 GB,并且您的数据节点为 HDFS 配置了 4 个卷,它将留出 40 GB 供非 DFS 使用。
答案2
也许您应该手动将数据从一个卷移动到另一个数据节点内:
3.12. 在单个数据节点上,如何平衡磁盘上的块?
Hadoop 目前没有自动执行此操作的方法。要手动执行此操作:
- 关闭相关的DataNode
- 使用 UNIX mv 命令将单个块副本和元对从一个目录移动到另一个目录(在选定主机上)。在具有 HDFS-6482(Apache Hadoop 2.6.0+)的版本中,您还需要确保在磁盘之间移动块时,子目录命名的目录结构保持完全相同。例如,如果块副本及其元对位于 /data/1/dfs/dn/current/BP-1788246909-172.23.1.202-1412278461680/current/finalized/subdir0/subdir1/ 下,而您想要将其移动到 /data/5/ 磁盘,则必须将其移动到其下的相同子目录结构中,即 /data/5/dfs/dn/current/BP-1788246909-172.23.1.202-1412278461680/current/finalized/subdir0/subdir1/。如果不保留此结构,移动后 DN 将无法再找到副本。
- 重新启动 DataNode。
答案3
答案4
我认为您真正想要的是将 dfs.datanode.du.reserved 设置为某个非零值,以便数据节点确保系统的 HDFS 卷上始终有那么多可用空间。
注意:dfs.datanode.du.reserved 用于整个系统,不是按卷。
根据HDFS-1564,有关于制作每个卷选项的讨论,但尚未计划用于任何特定版本。