systemd-run --scope 可通过 cgroup v2 的 IO 控制器限制脚本 I/O 带宽,需启用 cgroup v2 并激活 blkio,绑定具体块设备(如 /dev/sda),支持读写独立限速,并可组合内存、CPU、任务数及超时等限制确保稳定性。

用 systemd-run --scope 限制 Shell 数据处理脚本的 I/O 物理配额,核心是启用 cgroup v2 的 IO 控制器,并通过 --property 设置读写带宽上限。它不依赖外部工具(如 ionice 或 cpulimit),而是由内核直接强制执行,适合对磁盘压力敏感的批处理任务(比如日志归档、CSV 解析、数据库导出等)。
确认系统支持 IO 配额
IO 带宽限制在 cgroup v2 下通过 io.max 实现,需满足两个前提:
-
cgroup v2 已启用:运行
cat /proc/sys/kernel/cgroup_version,输出必须为2 -
blkio 控制器已激活:检查
cat /proc/cgroups | grep blkio,第三列应为1;若为0,需在内核启动参数中添加systemd.unified_cgroup_hierarchy=1并重启
指定设备与带宽上限
IO 配额必须绑定到具体块设备(如 /dev/sda、/dev/nvme0n1),不能只写挂载点(如 /data)。常用写法:
- 限制脚本对系统盘的写入不超过 20MB/s:
systemd-run --scope --property=IOWriteBandwidthMax=/dev/sda:20M ./process-data.sh - 同时限制读取 50MB/s、写入 15MB/s:
systemd-run --scope --property=IOReadBandwidthMax=/dev/sdb1:50M --property=IOWriteBandwidthMax=/dev/sdb1:15M ./process-data.sh - 若脚本涉及多个磁盘(如读 SSD、写 HDD),可叠加多个
--property,每项独立生效
配合其他资源限制更稳妥
单纯限 I/O 不足以防止失控——脚本可能卡在 CPU 密集计算、内存暴涨或产生海量子进程。建议组合使用:
- 防内存溢出:
--property=MemoryMax=2G - 防 CPU 占满:
--property=CPUQuota=75% - 防 fork 炸弹:
--property=TasksMax=16 - 防超时阻塞:
--runtime-max-sec=1800(最长运行 30 分钟)
验证与排错要点
启动后可通过以下方式确认限制是否生效:
- 查单元名:
systemd-run输出类似Running as unit: run-rf3a2b4c5d6e.scope,后续命令用该名称 - 看当前 I/O 使用:
systemctl show run-rf3a2b4c5d6e.scope -p IOReadBytes -p IOWriteBytes - 查是否被限速:
systemd-cgtop中观察对应 scope 的IO Read/Write列是否稳定在设定值附近 - 若脚本异常退出,查 OOM 或 IO 被拒原因:
journalctl -u run-rf3a2b4c5d6e.scope -n 30,留意IO limit exceeded或Blocked due to IO pressure类提示


















