直接用blkio权重控制+设备级限速+合理调度协同可稳住磁盘io:权重(如--blkio-weight 800)确保关键服务争抢时优先获得io,设备限速(如--device-write-bps /dev/sda:5mb)防突发打满,再配合tmpfs减落盘、iotop/iostat验证,实现精准资源隔离。

直接用 blkio 权重控制 + 设备级限速 + 合理调度协同,就能稳住磁盘 IO,避免业务超时。关键不是压低所有容器的 IO,而是让数据库、API 等关键服务在争抢时“插队成功”,同时把日志、备份等后台任务“按住节奏”。
设置 blkio.weight 明确 IO 优先级
这是最常用也最有效的起点。权重只在磁盘忙时起作用,不争抢时大家自由读写,不影响平时性能。
- 核心数据库容器建议设 700–900(如
--blkio-weight 800) - 普通 Web 或 API 容器设 400–600(默认 500 即可)
- 日志轮转、ETL 批处理类容器压到 100–300(如
--blkio-weight 200) - 权重比决定相对带宽比例:800:200 ≈ 4:1,MySQL 在争抢时能拿到约 4 倍于日志容器的 IO 时间片
对高吞吐容器加设备级限速
仅靠权重不够防突发打满。尤其当某个容器突然刷写大文件或批量导入,仍可能拖慢整块盘。这时要用 --device-read-bps 和 --device-write-bps 做硬限速。
- 例如限制某日志容器对
/dev/sda的写入不超过 5MB/s:--device-write-bps /dev/sda:5mb - 注意设备路径要真实存在(
lsblk查看),且主次设备号需匹配(如8:0对应 sda) - 限速单位支持
b、k、m、g,大小写敏感(mb是兆字节,MB会报错)
配合 tmpfs 或命名卷减少落盘压力
很多超时其实来自频繁小文件写入(比如每秒写几百条日志)。与其让它抢磁盘,不如让它别碰磁盘。
- 将临时日志目录挂为
tmpfs(内存盘):-v /var/log/app:/var/log/app:tmpfs,size=64m - 用命名卷替代匿名卷,Docker 会对命名卷做更优的底层缓存和预读策略
- Java 应用还要调小
-XX:+UseContainerSupport并显式设-Xmx,避免 JVM 误判内存而触发大量 GC 日志写入
验证与持续监控不能少
配完不验证,等于没配。IO 争抢问题隐蔽,必须结合指标交叉判断。
- 查容器实际生效的权重:
cat /sys/fs/cgroup/blkio/docker/$(docker inspect -f '{{.Id}}' 容器名)/blkio.weight - 实时看 IO 分布:
iotop -o -P(只看实际进程)、iostat -x 1(看 %util、r_await、w_await) - 对比调优前后响应时间:重点关注 P95/P99 延迟是否回落,而非平均值
- 若
%util长期 >90% 且w_await>50ms,说明磁盘已成瓶颈,需考虑升级存储或拆分物理盘











