性能文章>干货|disk.usage告警,看这一遍就够了>

干货|disk.usage告警,看这一遍就够了原创

1年前
392922

背景

磁盘利用率告警持续1天了

看到有线上ECS磁盘告警持续一天了。

问了下,已经处理过,该删都删了,但是告警还是消不掉。目前超的不是太多,就没有再管了

如果一直触发告警,担心影响到处理其它重要告警,就花时间去处理一下

问题描述

1、是否误告警? 不是
登录服务器,通过df -h查看
挂载点的磁盘利用率和告警信息一致,无误。
接着我们就是要找到导致磁盘空间满的目录或文件。

想了解查看大文件的详情命令?见文章末尾

2、删除老的日志文件

【日志文件一般保留90天即可】
查看最后修改时间大于90天,且文件大小大于500M的文件。
find / -type f -size +500M -mtime +90 |xargs rm -f
tips:
这个可以设置一个crontab任务来定期清理的
3、复核步骤2的效果
使用df -h查看,磁盘利用率没有变化
难道已经删除过了?
4、查找还有些大文件
是的,这个维度的冗余数据已经删除了。查看了下,可以删除的旧日志文件已经删除过了
查看了下,也没有找到明显的大文件

5、难道是删除了被Linux线程正在使用的文件?

查看已被删除,但文件句柄仍未释放的文件

有一个28G左右的大日志文件,删除了,但是空间没释放
lsof |grep deleted
tips:
有些机器可能未安装这个工具。
Unix-like OS可以使用命令 yum -install lsof 安装
其它操作系统上的安装办法,在度娘上可以找到的哦
果然有!
使用du 命令再确认下:是不是与df命令的执行结果 是不同的

是不同。du命令统计的文件总大小与df 命令统计的不一致

 

问题已经搞清楚了,来整体梳理下

故障原因

那问题就查清了:
1、告警是根据df命令的执行结果来触发的。
2、大文件也删除了
3、df 仍会统计这个被删除的文件。因为 这个已经被删除的大文件的文件句柄仍然被tomcat进程持有,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,linux内核还是不会释放这个文件的磁盘空间

 

持续告警原因分析

第一次出现告警后,值班同学处理时,按操作手册找到这个28G的大日志文件
直接使用rm命令删除
由于这个已经被删除的文件句柄仍然被tomcat进程持有,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,linux内核还是不会释放这个文件的磁盘空间。此时,df 仍会统计这个被删除的文件。
所以就出现这样矛盾的现象:磁盘上看不到了占用空间的大日志文件,但告警仍然持续
 

解决办法

当前服务是HA的,有两个实例。
所以,解决办法就很简单了:
确认另一个tomcat进行是正常后,重新仍然占用的这个tomcat进行即可。

优化措施

1、增加删除冗余日志的定时任务
2、删除大文件时,不能直接删除。要换下面的方式
echo "">/z/java/apache-tomcat-8.5.11/logs/catalina.out
cat /dev/null >/z/java/apache-tomcat-8.5.11/logs/catalina.out
3、tomcat的catalina.out日志文件,按日期进行分割,而是全部输出全部写入到一个catalina.out,这样日积月累就会造成.out日志越来越大,难于维护

故障小结

这个问题是tomcat的catalina.out日志没有按日期进行分割,全部输出全部写入到一个catalina.out,导致文件越来越大。
在没有停止tomcat进行的情况下,使用rm命令删除了这个文件,但catalina.out的文件句柄仍在使用中。
所以,df命令并不显示减去该文件后的大小,然后,告警持续。
解决办法,就是tomcat进行重启,释放catalina.out的文件句柄即可。

文件系统告警排查问题小结

1、先确认告警的真实性
2、找到引发告警的根因及处理

处理流程
3、制定优化措施

一个疑问:为什么不使用du的执行结果

既然du命令的执行结果这么准确,为什么不使用du的执行结果来判断是否有异常?
在尝试给一个理由前,先梳理下du和df命令的一些差异:
1、统计占用空间时的维度
du 侧重在文件和目录磁盘使用的空间占用方面,
df 则侧重在文件系统级别的磁盘占用方面。
2、命令的适用范围
du命令是用户级的程序,它不考虑Meta Data;
df命令则查看文件系统的磁盘分配图并考虑Meta Data。
关于Meta Data的介绍详见文末
结论: df更合适
1、因为是监控整个文件系统的磁盘利用率,使用df更合适。
2、df的性能更高。详见:
https://zhuanlan.zhihu.com/p/560196301

最后,留个问题:
Windows有没有这种问题?

加餐环节

du和df命令简介
du - man page描述 du:estimate file space usage。它的原理是深度优先遍历目标文件目录下的所有文件(非orphan inode),使用stat()家族获取文件信息。它的数据是基于文件获取,可以跨多个分区操作。包含了分配给文件及目录的磁盘块数。
df - man page描述 df:report file system disk space usage。coreutils中的df使用了glibc的statvfs(),间接地调用系统调用statfs()家族,数据来源于文件系统的super block。包含了用户数据(文件及目录)和Meta Data。

Meta Data:

文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。
这些数据对大多数用户级的程序来说是不可见的,通常称为Meta Data。

查看大文件的命令:

查看最后修改时间大于90天,且文件大小大于500M的文件。
日志文件一般保留90天即可
find / -type f -size +500M -mtime +90 |xargs du -ksh
如果确认涉及的文件都可以删除,则可以使用命令
find / -type f -size +500M -mtime +90 2 |xargs rm -f
说明:“/”代表的是根目录。如果只想搜指定的目录,更新这个参数即可,譬如查看/opt目录
find /opt -type f -size +500M -mtime +90 |xargs du -ksh
当普通用户使用“find”命令来查询这些文件目录时,往往会出现"Permission denied."(禁止访问)字样。

Permission denied

这种报错信息,如果大量出现,会把想要的关键信息淹没掉。
优化一下:

find / -type f -size +500M -mtime +90 2>/dev/null |xargs du -ksh

find / -type f -size +500M -mtime +90 2>/dev/null |xargs rm -f

du命令报错了:No such file or director

上面命令继续优化:不在控制台展示报错信息

find / -type f -size +500M -mtime +90 2>/dev/null |xargs du -ksh 2>/dev/null

find / -type f -size +500M -mtime +90 2>/dev/null |xargs rm -f

这个 2 到底是什么?
是Linux定义的一种文件描述符。写shell脚本下面三个会经常用到

Linux的保留文件描述符

Linux 文件描述符到底是什么?

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。
一个 Linux 进程可以打开成百上千个文件,为了表示和区分已经打开的文件,Linux 会给每个文件分配一个编号(一个 ID),这个编号就被称为文件描述符(File Descriptor)。
一个 Linux 进程启动后,会在内核空间中创建一个 PCB【Process Control Block】,PCB 内部有一个文件描述符表(File descriptor table),记录着当前进程所有可用的文件描述符,也即当前进程所有打开的文件。
0、1、2 这三个是特殊的文件描述符:
标准输入是文件描述符0。它是命令的输入,缺省是键盘,也可以是文件或其他命令的输出。
标准输出是文件描述符1。它是命令的输出,缺省是屏幕,也可以是文件。
标准错误是文件描述符2。这是命令错误的输出,缺省是屏幕,同样也可以是文件。

文件描述符-文件表-i-node表的作用域及之间的关系

文件描述符限制
有资源的地方就有战争,“文件描述符”也是一种资源,系统中的每个进程都需要占用“文件描述符”资源。使用这个资源的一些规则如下图所示:

FD使用规则

违反上述限制时的常见错误:“Too many open files”
如果出现这种错误, 可以通过增大进程可用的文件描述符数量来解决。
有些时候,并不是因为进程可用的文件描述符过少,而是因为程序bug,打开了大量的文件连接(web连接也会占用文件描述符)而没有释放。需要去甄别是哪种情况。
程序申请的资源在用完后及时释放,才是解决“Too many open files”的根本之道。

 

/dev/null又是什么呢?

/dev/null 属于字符特殊文件,它属于空设备,是一个特殊的设备文件,它会丢弃一切写入其中的数据,写入它的内容都会永远丢失,而且没有任何可以读取的内容。俗称“黑洞”,只进不出之意。

2>/dev/null

所做的重定向是将命令错误的输出到 /dev/null ,也就是将命令执行时发生的错误信息的输出重定向到 /dev/null 。然后 /dev/null 只做一件事,那就是将这些信息都全部丢弃掉。

find的另一个用法:-exec参数
-exec参数后面跟的是command命令,它的终止是以";"为结束标志的,不可缺少“;”,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。
{} 花括号代表前面find查找出来的文件。
find /opt -type f -size +500M -mtime +90 -exec du -ksh {} \;  2>/dev/null
find /opt -type f -size +500M -mtime +90 -exec rm -f {} \;  2>/dev/null

find命令配置exec使用时,结束标志“;”前要加转义符\

{}与结束标志之间要加空格

如何发现被应用程序引用了“已删除”文件呢?

lsof:list open files 使用lsof查看打开的文件。

lsof命令查看deleted状态的文件

Unix-like OS下,磁盘空间莫名被吃的一种情况?
Used和Avail加起来不够Size!

Used和Avail加起来不够Size,莫名被吃掉一部分

其实这是Linux文件系统的一种安全策略,它默认会为root用户保留5%的磁盘空间,留作紧急情况使用。这样能保证有些关键应用(比如数据库)在硬盘满的时候有点余地,不至于马上就 crash
我们可以通过tune2fs修改预留空间的比例
tune2fs -m 1 /dev/vda1

通过下图可以看到前后对比:

调整预留空间比例

这样被吃掉的空间,就释放出来了!

参考:

https://mp.weixin.qq.com/s/ViMNsRnfVkmQO7mvrbWrWQ

https://mp.weixin.qq.com/s/oCK0chpOmJcCnPdMhcketw

https://cloud.tencent.com/developer/article/1492195

https://www.jianshu.com/p/8c8a19048179

http://c.biancheng.net/view/3066.html

https://www.cnblogs.com/softidea/p/3965093.html

https://www.jianshu.com/p/8df4e9ff6628

 

 

点赞收藏
bit01
请先登录,查看2条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

服务器之 ECC 内存的工作原理

服务器之 ECC 内存的工作原理

从 Linux 内核角度探秘 JDK MappedByteBuffer

从 Linux 内核角度探秘 JDK MappedByteBuffer

日常Bug排查-连接突然全部关闭

日常Bug排查-连接突然全部关闭

2
2