• 一次磁盘占用率 100% 的排查记录


    原文首发公众号:一次磁盘占用率 100% 的排查记录

    你好,我是悟空。

    最近遇到一个服务器的问题:磁盘满了,占用率 100%~

    这个问题太常见了,于是先来排查一波是哪些文件占用了大量磁盘。

    一、排查磁盘占用率100%

    1.1 查看磁盘使用的大致情况

    第一个命令就是 df -h,来查看磁盘的占用情况。df 是 disk free 的缩写,用于显示目前在 Linux 系统上的文件系统磁盘的使用情况统计。

    如下图所示,可以看到磁盘占用率 100%。

    第一列 Filesystem 代表文件系统的名称。

    第二列 Size 表示文件系统的大小。

    第三列 Used 表示已占用多大的磁盘空间。

    第四列 Avail 表示可用磁盘空间的大小。

    第五列 Use% 表示磁盘使用率多大,100% 表示磁盘占满了。

    第六列 Mounted On 表示挂载在哪个目录。

    从上面的结果可以看到有个文件系统占用率为 100%,为/dev/sda2,挂载的目录为 /,那我们就来看下这个目录下都存放哪些大文件吧。

    1.2 查看目录下的大文件

    使用 du 命令来显示目录或文件所占用的磁盘空间大小。

    # 先进入到根目录 `/`
    cd /
    # 列出当前目录或文件的总大小,并按倒叙排序
    du -sh /* | sort -nr
    

    找到最大的目录 var,占用 100 多个 G。进入到这个目录中,然后再次执行 du 命令

    du -sh /var/* | sort -nr
    

    这样一级一级的找,就能找到占用空间最大的文件了。

    最后发现是 Logstash 容器的日志文件占用太大,截图如下。大家看到的占用 4.8G,这是我清理日志之后的大小,之前这个容器占用 90 多个 G。

    1.3 Logstash 容器为什么占用磁盘这么大

    为啥 Logstash 容器会有这么多日志???

    我们看下这个日志里面的内容就知道了。使用 tail 命令查看文件的最后 100 行数据。

    tail -n 100 <容器 id>-json.log
    # 也可以通过 docker logs 来查看日志
    docker logs  --tail=100 159
    

    发现全都是 Logstash 解析日志时打印的信息。如下图所示:

    每次 Filebeat 采集日志后,传输给 Logstash 后,Logstash 都会打印一条解析后的日志。

    而我们的后端服务会打印很多日志,传输给 Logstash 的日志会越来越多,Logstash 又会疯狂的写自己的解析日志,久而久之,磁盘就被占满了

    问题原因找到了,那解决方案是什么呢?

    二、容器日志清理方案

    • 方案一:手动清理日志文件,可解燃眉之急,治标不治本。

    • 方案二:脚本定期清理日志文件,缺点是日志文件全丢了,无法追溯。

    • 方案三:限制所有容器的日志文件大小,治本,缺点是需要重新创建容器和启动 docker 镜像。

    2.1 方案一:手动清理方案

    cat /dev/null > /var/lib/docker/containers/容器id/容器id-json.log
    

    注意:这里没有使用 rm 方式来删除文件。使用 rm -rf 方式删除日志后,通过 df -h 会发现磁盘空间并没有释放。原因是在Linux或者Unix系统中,通过 rm -rf 或者文件管理器删除文件,将会从文件系统的目录结构上解除链接(unlink)。如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。正确姿势是cat /dev/null > *-json.log,当然你也可以通过rm -rf删除后重启docker。

    2.2 方案二:脚本定期清理

    提供一个清理脚本

    #!/bin/sh 
    
    echo "======== start clean docker containers logs ========"  
    
    logs=$(find /var/lib/docker/containers/ -name *-json.log)  
    
    for log in $logs  
            do  
                    echo "clean logs : $log"  
                    cat /dev/null > $log  
            done  
    
    echo "======== end clean docker containers logs ========"
    

    给脚本添加权限

    chmod +x clean_docker_log.sh
    

    执行脚本的命令

    ./clean_docker_log.sh
    

    大家可以把执行脚本的命令加到 Linux 的定时任务中就可以了,这里不做展开。

    下面要说的是我目前使用的方案。

    2.3 方案三:限制 Docker 容器日志大小

    新建 /etc/docker/daemon.json,若有就不用新建了。

    vim /etc/docker/daemon.json
    

    配置内容如下:

    {
    "log-driver":"json-file",
    "log-opts": {"max-size":"500m", "max-file":"3"}
    }
    

    max-size=500m,表示容器的日志文件大小上限是 500M,
    max-file=3,表示容器有三个日志,第一个满了 500M之后就写第二个,第二个满了 500M就写第三个,如果第三个满了,就清空第一个日志文件,重新写第一个日志文件。如下图所示:

    改完之后需要重启 docker 守护进程

    systemctl daemon-reload
    systemctl restart docker
    

    另外这种方式只对新建的容器有效的,之前的容器不生效,所以我又把之前的 Logstash 容器删除了,然后重新启动了一个 Logstash 容器。

    参考资料:

    https://www.cnblogs.com/gcgc/p/10521005.html

    Linux df 命令 https://www.runoob.com/linux/linux-comm-df.html

    Linux du 命令 https://www.runoob.com/linux/linux-comm-du.html

    关于我

    8 年互联网开发经验,擅长微服务、分布式、架构设计。目前在一家大型上市公司从事基础架构和性能优化工作。

    InfoQ 签约作者、蓝桥签约作者、阿里云专家博主、51CTO 红人。

    我的所有文章都汇总到这里了 http://www.passjava.cn



  • 相关阅读:
    Spring Cloud Alibaba微服务从入门到进阶(四)(服务发现-Nacos )
    全栈工程师需要具备哪些技能?
    知识图谱--Jena基础操作和检索推理应用
    消息队列与快递柜之间的奇妙关系
    加密项目是否采用DAO模式 首先考量这8个因素
    敏捷也许是最适合外包团队的项目管理方法
    Vue/Nuxt框架开发的PC端网站兼容平板设备的
    ChatGPT王炸升级GPT-4 Turbo:更强大还更便宜
    uni-app:引用文件的方法
    pdf转word格式乱了怎么调整?教你几个小妙招
  • 原文地址:https://www.cnblogs.com/jackson0714/p/16774716.html