Docker Compose 通过 blkio_weight 字段(v2.20+)将底层 --blkio-weight 能力引入 YAML,取值10–1000,默认500,仅在多容器共用同一物理设备(如 /dev/sda)并发生同步IO竞争时按权重比例分配IO时间片;需先验证宿主机 blkio cgroup挂载、启用及CFQ/BFQ调度器支持,配合命名卷/绑定挂载减少overlay2开销,并用 docker inspect、iotop、iostat 验证效果。

用 Docker Compose 优化多容器磁盘 I/O 竞争,核心是把底层 Docker 的 --blkio-weight 能力带进 YAML 配置,并配合存储挂载、调度器检查和监控验证,让数据库、日志、备份等服务在共用同一块磁盘时各得其所。
确认宿主机支持 blkio 权重机制
Compose 不会自动启用 IO 控制,必须先确保宿主机已就绪:
- 运行
ls /sys/fs/cgroup/blkio/,目录存在且可读写才表示 blkio cgroup 已挂载 - 执行
cat /proc/cgroups | grep blkio,确认 enabled 列为 1 - 检查磁盘调度器:
cat /sys/block/sda/queue/scheduler,输出中应含[cfq]或[bfq](CFQ 更稳定,BFQ 在较新内核下也可用) - 若用 systemd 启动,需确认未启用 cgroups v2:检查
/proc/cmdline是否含systemd.unified_cgroup_hierarchy=0
在 docker-compose.yml 中配置 blkio_weight
Compose v2.20+ 原生支持 blkio_weight 字段,直接写入 service 级别即可:
- 取值范围 10–1000,默认 500;数值越高,争抢时获得的 IO 时间片越多
- 权重只在多个容器同时向同一块设备(如
/dev/sda)发起同步读写时生效 - 示例配置:
mysql:
image: mysql:8.0
volumes: ["/data/mysql:/var/lib/mysql"]
deploy:
resources:
limits:
blkio_weight: 800
log-processor:
image: alpine
command: sh -c "while true; do echo log >> /logs/app.log; sync; done"
volumes: ["/data/logs:/logs"]
deploy:
resources:
limits:
blkio_weight: 200
搭配命名卷或绑定挂载降低 IO 放大
单纯设权重不够,还要减少容器层本身的 IO 开销:
- 高频读写路径(如数据库数据目录、日志目录)务必使用 命名卷 或 绑定挂载,绕过 overlay2 的联合文件系统层
- 避免将日志直接写进容器可写层——那会触发大量小文件 copy-on-write,加剧随机写放大
- 例如:
docker volume create mysql-data,然后在 compose 中写volumes: ["mysql-data:/var/lib/mysql"] - SSD 上权重效果可能不如 HDD 明显,但结合直通挂载后,延迟抖动仍能显著收敛
验证与持续观察
配完不验证等于没配。重点看三件事:
- 查配置是否落地:
docker inspect <mysql-container-id> | grep blkio_weight,或进入对应 cgroup 路径查blkio.weight文件 - 压测时用
iotop -o -P观察各容器进程的 IO% 分布,高权重容器应持续占更高比例 - 跑
iostat -x 1看await和%util,若争抢缓解,await波动会变小,%util不再长期卡在 100% - 注意:权重不影响异步 IO(如部分 buffer write),所以要确保关键路径含
fsync或O_SYNC才能被调度器感知


















