• 微信
    咨询
    微信在线咨询 服务时间:9:00-18:00
    纵横数据官方微信 使用微信扫一扫
    马上在线沟通
  • 业务
    咨询

    QQ在线咨询 服务时间:9:00-18:00

    选择下列产品马上在线沟通

    纵横售前-老古
    QQ:519082853 售前电话:18950029581
    纵横售前-江夏
    QQ:576791973 售前电话:19906048602
    纵横售前-小李
    QQ:3494196421 售前电话:19906048601
    纵横售前-小智
    QQ:2732502176 售前电话:17750597339
    纵横售前-燕子
    QQ:609863413 售前电话:17750597993
    纵横值班售后
    QQ:407474592 售后电话:18950029502
    纵横财务
    QQ:568149701 售后电话:18965139141

    售前咨询热线:

    400-188-6560

    业务姚经理:18950029581

  • 关注

    关于纵横数据 更多优惠活动等您来拿!
    纵横数据官方微信 扫一扫关注官方微信
  • 关闭
  • 顶部
  • 您所在的位置 : 首页 > 新闻公告 > 云主机日志过大如何清理?

    云主机日志过大如何清理?

    那天我正在开会,手机连续震动了三次。瞄了一眼,是云监控发来的告警:磁盘使用率已超过百分之九十。我心里一紧,会议剩下的内容几乎没听进去。回到工位登录服务器,执行df -h一看,根分区只剩下不到两个G。可我的网站程序加上数据库一共也才十几个G,怎么就快满了呢?

    用du -sh /* 逐层排查,真相很快就浮出水面了。/var/log目录占了整整四十个G。再往下看,messages文件有十几个G,syslog也有七八个G,还有一堆压缩过的旧日志,日期能追溯到半年前。那一刻我才意识到,这台服务器的日志从部署那天起就从来没有清理过。

    相信不少运维朋友都有过类似的经历。云主机上的日志文件就像家里的灰尘,每天落一点点你根本感觉不到,等你某天突然发现呼吸困难的时候,它已经积了厚厚一层。日志过大不仅会占满磁盘空间,导致数据库无法写入、网站无法上传文件,严重时还会让服务器直接卡死。今天我想跟你聊聊,日志过大的问题到底怎么解决,以及怎么建立一套让日志既保留价值又不撑爆磁盘的机制。

    先说说日志太大的危害,可能比你想象的更严重。最直接的影响是磁盘满了,新的日志写不进去,应用开始报错。我有一个客户是做在线客服系统的,他的服务器上日志文件把磁盘塞满了,结果客服聊天记录写不进数据库,用户发来的消息全部丢失,引发了大量客诉。更隐蔽的影响是,当日志文件达到几十个G的时候,你用cat或者tail命令查看日志都会非常慢,甚至可能把服务器负载拉高。而且日志文件太大,想用grep查找某条历史记录,可能要等上好几分钟。还有一个很多人忽略的点,日志文件如果被进程持续写入,你直接rm删除并不会释放磁盘空间,因为进程还持有文件句柄,空间直到进程重启才会释放。我见过有人删了日志,df一看空间没变,以为系统出bug了,其实就是这个原因。

    那么,日志过大的问题该怎么解决呢?我分成两个层面来讲:一是当下的紧急清理,二是长期的治理机制。

    先说紧急清理,也就是磁盘快爆了,你必须立刻腾出空间的时候。这时候最忌讳的就是慌不择路。我有一套经过验证的操作顺序,你可以参考。

    第一步,定位哪些日志文件最大。用df -h先确认哪个分区满了,通常是根分区或者/var分区。然后进入对应的目录,用du -sh * | sort -rh 或者 ncdu 工具来查看各目录和文件的大小。注意不要用du / -h,那样会扫描整个系统,太慢而且没必要。一般/var/log是重点嫌疑对象,另外/var/log/journal下的systemd日志也可能很大。我曾经在一台跑了半年的服务器上发现,systemd的journal日志占用了二十多个G,而我自己完全没有意识到。

    第二步,根据日志类型选择合适的清理方式。对于普通的文本日志,比如messages、syslog、auth.log这些,可以用重定向或者truncate命令来清空,但不要用rm删除。正确的做法是执行echo > /var/log/messages,或者使用truncate -s 0 /var/log/messages。这样可以瞬间把文件大小归零,同时不影响正在写入的进程。如果直接rm,空间不会释放,还得重启服务。对于已经被压缩的旧日志,比如.gz文件,它们通常是日志轮转后留下的,可以根据时间范围删除。比如删除三个月前的压缩日志:find /var/log -name “.gz” -mtime +90 -delete。这一步要小心,确认一下这些旧日志你确实不需要了。

    第三步,重启相关的日志服务。当你清空或者删除了一些日志文件后,最好重启一下rsyslog、syslog-ng或者systemd-journald,让它们重新打开日志文件。否则某些进程可能还在往已删除的文件句柄里写数据,空间依然没有完全释放。用systemctl restart rsyslog或者systemctl restart systemd-journald即可。

    紧急清理能解燃眉之急,但治标不治本。如果不建立长效机制,几周后磁盘又会告警。下面我就重点讲讲如何建立一个健康可持续的日志管理机制。

    日志轮转是最基础也是最有效的工具。Linux系统自带的logrotate几乎可以处理所有文本日志的轮转、压缩和删除。它的配置文件在/etc/logrotate.conf和/etc/logrotate.d/目录下。每个需要轮转的日志都可以单独配置规则。我拿一个典型的配置举个例子:针对Nginx访问日志,可以设置每周轮转一次,保留最近四周的日志,轮转后立即压缩,对于空日志不处理。配置大致是/var/log/nginx/*.log { weekly rotate 4 compress delaycompress missingok notifempty }。这里面weekly表示每周轮转,rotate 4表示保留4个轮转后的旧日志,compress表示用gzip压缩,delaycompress表示延迟压缩到下一次轮转,这样可以保证当前日志文件不被压缩导致写入失败。missingok表示如果日志文件不存在就忽略,notifempty表示空文件不轮转。

    但光有这些还不够,你需要根据日志的实际增长速度来调整参数。比如某个业务日志一天就能写几个G,那么weekly就太慢了,应该改成daily。比如某个调试日志你只需要保留三天,那就把rotate改成3。我习惯在配置logrotate之后,手动执行logrotate -f /etc/logrotate.d/nginx来测试一下,看看是否按照预期工作。然后加上crontab定时任务,通常系统已经自带每日运行的logrotate cron脚本,你只需要确保它没有被禁用就行。

    除了系统自带的logrotate,有些应用自己有日志管理功能。比如Nginx可以通过配置access_log和error_log指令里的buffer和flush参数来控制日志写入频率。比如Apache的rotatelogs工具可以实现按时间切割。比如Java应用通过Log4j或Logback的配置可以实现按大小和日期滚动。善用这些应用层面的日志管理,可以从源头上控制日志文件的大小。

    对于systemd管理的服务,它的日志是通过journald收集的。journald的日志默认存储在/var/log/journal/目录下,而且不是纯文本格式,不能直接用logrotate处理。你需要配置journald的日志限额。编辑/etc/systemd/journald.conf,设置SystemMaxUse来限制日志占用的最大磁盘空间,比如SystemMaxUse=5G,设置SystemMaxFileSize来限制单个日志文件大小,比如SystemMaxFileSize=500M。修改后执行systemctl restart systemd-journald生效。另外,你也可以用journalctl命令手动清理,比如journalctl --vacuum-size=2G表示将日志压缩到2G以下,journalctl --vacuum-time=30d表示删除30天前的日志。我建议把journalctl的清理命令写进crontab,每周执行一次。

    说完工具和方法,我想分享一个真实的案例,这个案例让我对日志管理有了更深的理解。去年有个做游戏联运的客户找到我,说他的服务器每周都要重启一次,否则就变得非常慢。我登录服务器一看,磁盘空间还有不少,负载也不高。用top命令观察了半天,发现有个叫rsyslogd的进程时不时占用很高的CPU。进一步查看,发现/var/log/messages文件有六十多个G。打开这个文件随便看了一眼,里面充斥着同一个错误信息,每秒几十条,是某个游戏服务插件一直在报一个数据库连接失败的错误。这个错误日志以每秒钟几十兆的速度疯狂写入,一周下来就积累了六十多个G。而且因为日志文件太大,rsyslogd每次写入都要在文件末尾定位,效率极低,导致CPU飙升。解决方案分两步:先紧急清空了这个巨大的messages文件,然后找到报错的源头,修复了数据库连接的配置问题。从那以后,服务器的负载恢复正常,也不需要每周重启了。这个案例给我的启示是:日志过大的根本原因往往是程序在疯狂报错。如果你只清理日志而不解决报错的根源,那就像用一个漏桶接水,永远接不完。所以当你发现某个日志文件异常增长时,一定要打开看看里面在重复什么错误,先把那个问题解决掉,再来处理日志清理。

    除了上述方法,还有一些更高级的日志管理思路。比如使用ELK或者Loki这样的集中式日志系统,把服务器上的日志实时发送到远程的日志中心。这样云主机本地只需要保留很短时间甚至不保留日志,所有日志都集中存储和检索。这种方式的好处是你可以任意查询历史日志,不受本地磁盘限制,而且可以在多台服务器之间统一管理。缺点是需要额外搭建和维护一套日志系统。如果你的服务器数量不多,用logrotate加定期清理就足够了。如果服务器规模超过十台,我建议考虑集中式日志方案。

    另外,云服务商通常也提供日志服务,你可以把日志直接投递到云上的日志产品中,然后在本地上配置logrotate缩短保留周期,比如只保留一天,甚至完全不保留本地日志。这样既满足了排障时需要查看日志的需求,又不用担心磁盘被撑爆。我自己现在就是这样做的:关键服务的错误日志保留本地七天,同时实时同步到云端日志平台。访问日志只保留一天,因为云端有完整的备份。

    在清理日志时还有一些安全合规的考量需要注意。有些行业比如金融、医疗,法规要求日志必须保留一定期限,比如六个月或者一年。你不能为了释放空间而随意删除超过保留期限的日志。对于这类场景,可以考虑把旧日志归档到对象存储或者冷存储中,既合规又经济。云服务商的对象存储通常有生命周期规则,可以自动将超过一定时间的日志转存到更低成本的存储类型。你只需要写一个简单的脚本,每天把一周前的日志压缩打包上传到对象存储,然后删除本地的旧文件就行。

    最后,我想聊一聊心态和习惯的问题。很多运维新手对日志的态度是“眼不见为净”,只要磁盘没满就不去管它。等到告警来了,就简单粗暴地rm一下,然后继续不管。这种做法迟早会再次踩坑。我个人的习惯是把日志管理纳入日常巡检清单,每周花五分钟看一下各服务器的磁盘使用趋势,检查一下logrotate的执行情况。如果有异常增长的日志,第一时间排查原因。这个习惯帮我避免了好几次磁盘写满导致的故障。

    还有一点,日志不是越多越好。很多开发者为了方便调试,在生产环境开启了DEBUG级别的日志,每条请求记录几十行信息。这种做法在开发环境没问题,但到了生产环境,尤其是高并发场景下,日志量会爆炸式增长。我建议生产环境的日志级别至少设为INFO,只在临时排查问题时才临时开启DEBUG,解决完就改回去。同时,对于一些频繁但价值不大的日志,比如健康检查接口的访问日志,可以直接写到单独的日志文件,并设置更短的保留周期,或者干脆不记录。

    总结一下,云主机日志过大这个问题,紧急处理时要用truncate清空而不是rm删除,用du和find定位大文件,然后重启日志服务释放空间。长期治理要靠logrotate配合合理的轮转策略,根据日志增长速度设置daily还是weekly,根据保留需求设置rotate次数,开启压缩节省空间。对于systemd的journal,要设置SystemMaxUse限额。同时要留意程序本身是否在疯狂报错,从根源上解决问题。对于多服务器或合规场景,可以考虑集中式日志系统或云日志服务。最后,养成定期巡检的习惯,让日志管理成为你运维日常的一部分,而不是每次都被告警追着跑。

    希望读完这篇文章,你再看到磁盘告警时,心里能多一份从容,少一份慌乱。毕竟,日志就像服务器的手账,记录了它每一天的喜怒哀乐。我们要做的,不是把这些手账扔掉,而是给它们一个整洁的书架,让它们既有地方安放,又不会挤占我们的生活空间。



    最新推荐


    微信公众帐号
    关注我们的微信