背景介绍:
近日由于公司大数据集群进行了升级,新增的服务器数据盘几乎是空的,但是考虑到集群数据量较大(大概100多个TB),而且集群几乎24小时在用,考虑到以下因素, 1 做大规模集群负载均衡是否会造成数据丢失?
2 根据hadoop官网介绍限制负载均衡网络限制(dfs.datanode.balance.bandwidthPerSec)是否可以起到真正的作用?
3 迁移过程中,有些块正在用,怎么办?
4 数据丢失怎么办?
考虑到以上因数,没有足够的把握,也不敢做负载均衡,看了一下hadoop官网,有如下一个配置dfs.datanode.du.reserved,默认值是0,官方解释为eserved space in bytes per volume. Always leave this much space free for non dfs use.大概意思就是说在每块磁盘上会保留你设置的字节数空间作为非hdfs,于是就设置了100GB余留空间没,重启了dfs服务
虽然设置了保留空间,但是过了一段时间还是收到报警,磁盘快被写满了,感觉配置没有生效,后来网上搜了下资料,找到了问题,原来是这样的
我们进入服务器进行df -h,或则df(会更精确查看)
[appuser@112.126.68.226/10.163.3.208 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 60G 34G 23G 60% /
tmpfs 16G 4.0K 16G 1% /dev/shm
/dev/xvdb 197G 169G 19G 91% /app
以上可以看出我的app数据盘大小是197GB,使用了169GB,剩余19GB,那么197!=169+19,那么剩余的空间197-169-19=9GB去哪里了,后来发现centos系统默认会余留磁盘的5%(197*5%,由于这里用的是GB,不是字节,会存在误差,大家可以通过字节数去算,会更精确)用来打root日志等供系统使用,然后看了下源码,源码如下
代码路径在
package org.apache.hadoop.hdfs.server.datanode.fsdataset.impl;
代码如下
/**
* Calculate the capacity of the filesystem, after removing any
* reserved capacity.
* @return the unreserved number of bytes left in this filesystem. May be zero.
*/
long getCapacity() {
long remaining = usage.getCapacity() - reserved;
return remaining > 0 ? remaining : 0;
}
@Override
// 请看这里
public long getAvailable() throws IOException {
long remaining = getCapacity()-getDfsUsed();
long available = usage.getAvailable();
if (remaining > available) {
remaining = available;
}
return (remaining > 0) ? remaining : 0;
}
long getReserved(){
return reserved;
}
BlockPoolSlice getBlockPoolSlice(String bpid) throws IOException {
BlockPoolSlice bp = bpSlices.get(bpid);
if (bp == null) {
throw new IOException("block pool " + bpid + " is not found");
}
return bp;
}
如果你设置的非hdfs空间小于或则等于系统默认余留值,那么磁盘会被写满了
假设你要设置非hdfs空间为100GB,系统预留为100GB,那么你需要在dfs.datanode.du.reserved设置的参数就就是200GB,当然要以字节为单位,计算公式是这样的,你要设置的磁盘空间=总空间-已经使用的空间-剩余的空间-系统预留的空间,一般系统预留空间默认为磁盘大小的5%,
这样修改之后重启hdfs就可以了,由于上次的失误,部分磁盘使用率已经超过了设定的磁盘预留值,目前发现dfs不会再往限制部分写了,这样hdfs磁盘余留空间限制才生效!
由于小编水平有限,说的不对的请各位大神多多指点!