这是一篇历史文章,貌似16还在负责做集群的时候遇到并解决的一问题。之所以发出来是因为感觉比较实用,自从公众号迁移之后,历史文章不能搜索了,所以浪尖每隔一段时间,抽一篇比较实用的历史文章发出来,以便于大家复习和新手来公众号搜索。

现象描述

建集群的时候,datanode的节点数据磁盘总共是四块磁盘做矩阵成了一个7.2TB的sdb1(data1),两块通过矩阵做了一个3.6TB的sdc1(data2)磁盘,运维做的,历史原因。刚开始没有发现,然后集群过了一段时间,随着数据量的增加,发现集群有很多磁盘超过使用率90%告警,浪尖设置磁盘告警阈值是90%,超过阈值就会发短信或者微信告警,提醒我们磁盘将要满了进行预处理,但是通过hadoop的监控指标获取的磁盘利用率维持在55%+,这种情况下不应该发生告警的。磁盘的使用率在hadoop的hdfs的namnode的web ui也可以看到,如下:

hdfs内存清理 hdfs磁盘空间不足_hadoop

这个时候,大家的怀疑会集中于hdfs的某些datanode节点数据存储过于集中,导致某些节点磁盘告警。但是大家都知道,hdfs允许datanode节点接入时datanode之间磁盘异构,数据存储hadoop会自动在datanode之间进行均衡。所以这个怀疑可以排除。

登录告警节点,发现确实data2磁盘使用率超过了90%,但是data1使用率维持在不足50%。

这时候问题就显而易见了,hadoop3.0之前hdfs数据存储只支持在datanode节点之间均衡,而不支持datanode内部磁盘间的数据存储均衡。

hdfs内存清理 hdfs磁盘空间不足_hadoop_02

那么这个时候怎么办呢?

起初

浪尖想的是将data1那个矩阵,拆分成两块由两块磁盘组成的矩阵,然后重新滚动上下线Datanode(数据迁移或者通过副本变动让其进行均衡)。但是,后来很快否定了这种方法,原因是很简单。几百TB的数据,在集群中均衡,即使是滚动重启,那么多机器也要持续好久,然后在数据迁移或者均衡的时候,整个几群的带宽和磁盘都是会增加很大负担,导致集群的可用性降低。

接着

通过hadoop官网发现hadoop 3.0不仅支持datanode之间的数据均衡,也支持datanode内部管理的多磁盘的之间的数据均衡。

hdfs内存清理 hdfs磁盘空间不足_hadoop_03

这个时候,可以考虑升级hadoop集群到hadoop3.0,但是思考再三浪尖觉得浪费时间,不划算,最终放弃这种方案。

最后

几经思考,终于想出了一个原本就很简单的方案,只需要重启datanode,就可以实现提高大磁盘利用率的方法。首先,要知道的是datanode管理磁盘,是根据我们dfs.data.dir参数指定的目录。那么,我们的思路就很简单了,给data1多个目录,不就可以增加其写入的概率,进而提升磁盘的使用率了么。配置方式如下:

<property>
        <name>dfs.data.dir</name>
        <value>/data1/dfs/dn,/data1/dfs/dn1,/data2/dfs/dn</value>
</property>

配置结束之后,重启datanode集群,过一定时间查看该目录的大小,然后发现有数据写入。

hdfs内存清理 hdfs磁盘空间不足_hadoop_04

由此证明,想法是可行的。

此方法的缺点是,原有的数据不会进行均衡,增加目录的方式只是增加了新数据写入大磁盘的概率,但是这样就可以了,等着原有数据自动删除即可。

彩蛋

浪尖已经有四五年没做hadoop等集群平台相关的工作了,所以不建议新手加入浪尖的星球,具体细节可能只能提供思路,不过所有的问题在你着手解决,一个个方案尝试的时候,都会迎刃而解,毕竟做开发的任务就是解决问题。

我可能是唯一一个不建议新手加入星期的博主吧。。。

不过假设你对spark,flink,kafka,hbase等源码,调优等感兴趣,还是可以加入浪尖的星球了。毕竟破千了。