一行日志竟引发 110KB 磁盘写入
Single log line is 49KB+ (ext4) / 110KB+ (btrfs) of systemd-journald disk writes

在 Debian 13 系统上,用户发现 systemd-journald 存在严重的 IO 效率问题。原本每秒仅写入两行日志的虚拟机,却产生了约 50 IOPS 的磁盘负载。进一步测试显示,在 ext4 文件系统下,单行日志竟导致超过 49KB 的磁盘写入,而在 btrfs 下更是高达 110KB。尽管尝试关闭压缩功能,情况并未改善。开发者通过调试发现,journald 在处理 mmap 文件时存在机制缺陷,导致内存压力下频繁刷新缓存,造成大量无效 IO。这一现象不仅拖慢系统响应,还可能因非正常重启导致日志损坏,暴露了该日志服务在底层实现上的低效与脆弱。
journald 使用了极其低效的格式,文件体积往往是实际写入内容的数倍。
HN 评论区
217- 0x_rs
journald 糟糕的原因有很多,但更糟糕的是,你机器上运行的所有程序都觉得自己有权在毫无提示的情况下把想记的日志全倒进去。打开一个文件选择器,kio 就会觉得每天往里面狂塞几万甚至几十万条日志是个好主意,把目录里的每个文件都列一遍,还附带诸如“刚删除的项目未找到节点”之类的日志,这对用户来说毫无影响。你几乎得维护一个脚本,跟踪每个新服务引发的日志洪水,确保它们不把系统日志当成垃圾场。公平地说,内核和 USB 外设也可能状态不佳,每小时往里面狂塞 300 万行日志,比如 input irq status -75。
要跟上所有程序级的配置(如果有的话)和服务文件实在太麻烦了,不过 systemd 里的 LogFilterPatterns 可以在非预期方向上帮上忙:你可以在 /etc/systemd/system/service.d/ 下创建一个 .conf 文件,作为统一的日志黑名单,把那些刷屏的日志模式一个个加进去,甚至不用去追查错误的日志级别。看起来大概是这样:
[Service]
LogFilterPatterns=~I am a completely useless log entry
LogFilterPatterns=~I am another useless log entry
但它无法识别标识符,对内核刷屏也毫无作用。它唯一的好处就是能让某些消息闭嘴。另外,我认为任何 btrfs 安装如果没在 cache、journal 等位置开启 nocow,都是有缺陷的 […]
- otterley
中途肯定出了点问题,因为这不是数据库最初的设计意图(我加粗了):
"""
原生日志文件格式借鉴了经典日志文件和 git 仓库。其设计方式是日志数据只追加到末尾(以确保基于 mmap() 访问的健壮性和原子性),同时在头部更新一些元数据来引用新增内容。条目由多个字段组成,这些字段作为独立对象存储在日志文件中,所有需要它们的条目都引用这些对象。这节省了大量磁盘空间,因为日志条目通常高度重复(例如:每条本地消息都会包含相同的 _HOSTNAME= 和 _MACHINE_ID= 字段)。数据字段经过压缩以节省磁盘空间。最终效果是,尽管 journald 记录的元数据远多于经典 syslog,但磁盘占用量并不会立刻反映出这一点。
"""
参见 https://docs.google.com/document/u/0/d/1IC9yOXj7j6cdLLxWEBAG...
- jck86
最要命的是,你实际上根本无法过滤 journald。唯一的选择是按严重级别限制(例如只保留错误及以上),或者切换到非持久化的 journald 存储,转发到 rsyslog 再在那里过滤。
细节我有点记不清了,但有时某个驱动会发疯,开始每秒记录多次,比如 amdgpu 在从挂起恢复后出现的 bug。花了好一会儿才把它过滤掉,幸运的是那只是内核消息(dmesg),但有一段时间我不得不禁用持久化内核日志,这离理想状态差得远。
我理解对于某些核心部分,简单性比功能更重要。但 journald 太基础了,居然能启用持久化存储,可我也不想把它关掉。
- barrkel
在我看来,journald 是 systemd 生态中最糟糕的部分。你最好只把它当作路由器,别在里面存任何日志。它使用的索引系统很慢,而且对话痨子系统毫无控制力——你无法单独截断某个标识符的日志。对于索引所做的所有事情,用现代 grep 工具如 ag 或 rg 能获得更好的性能。结构化固然有价值,但放在 journald 里就不合适了。
- smartmic
我最近查看了 journald 的磁盘占用,也被震惊到了。我下一步走向心安理得的选择是 https://www.devuan.org/os/init-freedom
打算把它作为 Debian 系统的下一个发行版试试,之前在另一台机器上长期使用 Void Linux(runit)的经验很棒。
- pudgywalsh
你是怎么试图复制 Windows NT 的事件日志——这东西自 90 年代系统还在 32MB 或更少内存上运行时就没怎么变过——然后败得如此惨烈的?
我在 Linux 系统上做的第一件事就是安装一个正经的 syslog 守护进程。
- ValdikSS
https://github.com/systemd/systemd/issues/40262#issuecomment...
- amluto
哦,mmap 写入。我多年前也犯过这个错误。:) 我在那个 GH 问题下留了条评论。