磁盘I/O性能是Linux服务器常见瓶颈,数据库、日志系统、虚拟化平台等场景对I/O吞吐和延迟敏感。Linux内核提供多种I/O调度器和文件系统选项,合理配置可显著提升服务器磁盘性能。服务器运维中,磁盘I/O调优是性能优化的高频任务。
I/O调度器类型与适用场景分析
Linux内核支持多种I/O调度器,不同调度器针对不同工作负载优化:
mq-deadline:多队列截止时间调度器,为每个请求设置截止时间,保证请求不会长时间饥饿。适合SSD和NVMe设备,是大多数发行版默认选择。
bfq:Budget Fair Queueing调度器,按进程分配I/O带宽预算,适合交互式应用和桌面环境。在服务器场景中,bfq可防止单个进程占用全部I/O带宽。
kyber:基于deadline的调度器,为同步和异步请求分别维护队列,适合NVMe等高速设备。
none:不使用调度器,请求直接传递给设备。适合NVMe SSD,设备自带I/O调度能力时无需内核层额外开销。
# 查看当前设备使用的调度器
cat /sys/block/sda/queue/scheduler
# 输出示例: [mq-deadline] kyber bfq none
# 临时修改调度器(重启失效)
echo kyber > /sys/block/nvme0n1/queue/scheduler
# 永久配置(通过udev规则)
cat > /etc/udev/rules.d/60-io-scheduler.rules << 'EOF'
# NVMe SSD 使用 none 调度器
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="none"
# SATA SSD 使用 mq-deadline
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}="0", ATTR{queue/scheduler}="mq-deadline"
# 机械硬盘使用 bfq
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}="1", ATTR{queue/scheduler}="bfq"
EOF
udevadm trigger --type=devices --action=change
文件系统选型与挂载参数优化
Linux支持多种文件系统,每种针对不同工作负载优化:
ext4:稳定可靠,兼容性好,适合通用服务器场景。支持日志、extents、延迟分配等特性。
XFS:高并发性能优秀,大文件处理能力强,适合数据库存储和大数据场景。RHEL/CentOS默认文件系统。
Btrfs:支持CoW(写时复制)、快照、压缩、子卷,适合需要频繁快照的场景。
# 创建XFS文件系统并启用高级特性
mkfs.xfs -f -d agcount=16 -l size=1024m /dev/nvme0n1p2
# 挂载参数优化
# 数据库场景(高IOPS,低延迟)
mount -o noatime,nodiratime,nobarrier,discard,inode64 /dev/nvme0n1p2 /data
# 日志场景(高吞吐,顺序写为主)
mount -o noatime,nodiratime,relatime,data=writeback /dev/sda1 /var/log
# 写入/etc/fstab持久化
/dev/nvme0n1p2 /data xfs noatime,nodiratime,nobarrier,discard,inode64 0 0
关键挂载参数说明:
noatime/nodiratime:禁止更新文件/目录访问时间,减少不必要的写操作。对读密集型场景可提升5%-10%性能。
nobarrier:禁用写屏障。在设备自带断电保护(如BBU电池)时可安全使用,减少fsync开销。无断电保护的设备不建议使用。
discard:启用TRIM,SSD自动回收已删除块的存储空间。NVMe设备建议启用。
data=writeback(ext4专用):允许元数据先于数据写入日志,提升写入性能但在断电时可能丢失最近数据。仅适合可容忍数据丢失的场景。
I/O队列深度与预读优化
内核I/O队列参数直接影响设备的并发处理能力:
# 查看队列深度
cat /sys/block/nvme0n1/queue/nr_requests
# 默认128,高速NVMe可提升到512
# 调整队列深度
echo 512 > /sys/block/nvme0n1/queue/nr_requests
# 预读设置(readahead)
# 顺序读密集场景适当增大预读
cat /sys/block/sda/queue/read_ahead_kb
# 默认128KB,大文件顺序读可提升到4096KB
echo 4096 > /sys/block/sda/queue/read_ahead_kb
# NVMe设备一般不需要大预读,保持默认即可
echo 256 > /sys/block/nvme0n1/queue/read_ahead_kb
# 持久化配置
echo 'ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/nr_requests}="512"' >> /etc/udev/rules.d/60-io-tuning.rules
磁盘I/O性能基准测试
调优前后需要量化对比,fio是Linux下最常用的I/O基准测试工具:
# 安装fio
yum install fio -y # CentOS/RHEL
apt install fio -y # Ubuntu/Debian
# 随机读写IOPS测试(数据库场景)
fio --name=rand_rw_test \
--filename=/data/fio_testfile \
--rw=randrw \
--rwmixread=70 \
--bs=4k \
--size=10G \
--numjobs=4 \
--iodepth=32 \
--runtime=60 \
--time_based \
--group_reporting
# 顺序读写吞吐测试(日志/备份场景)
fio --name=seq_write_test \
--filename=/data/fio_testfile \
--rw=write \
--bs=1M \
--size=20G \
--numjobs=2 \
--iodepth=16 \
--runtime=60 \
--time_based \
--group_reporting
# 测试完成后清理
rm -f /data/fio_testfile
测试结果关注以下指标:
IOPS:每秒I/O操作数,4K随机读写场景的核心指标。NVMe SSD通常可达10万以上。
吞吐量(BW):每秒数据传输量,1M顺序读写场景的核心指标。NVMe SSD可达3GB/s以上。
延迟(lat):单次I/O操作完成时间。P99延迟对数据库等延迟敏感场景至关重要。
常见I/O瓶颈排查工具
当服务器出现I/O性能问题时,以下工具可帮助定位瓶颈:
# iostat - 磁盘I/O统计
iostat -dxm 1
# 关注指标:
# %util - 设备利用率,接近100%表示饱和
# await - 平均I/O等待时间(ms),超过20ms需关注
# r/s w/s - 每秒读写请求数
# ar/s - 读请求合并率
# iotop - 按进程查看I/O使用
iotop -oP
# 实时显示产生I/O的进程,快速定位I/O大户
# blktrace - 块设备I/O跟踪
blktrace -d /dev/nvme0n1 -o - | blkparse -i -
# 详细记录每个I/O请求的生命周期
# /proc/diskstats - 内核磁盘统计
cat /proc/diskstats | grep nvme0n1
# 字段含义:
# field3 读完成次数
# field7 写完成次数
# field9 读扇区数
# field13 写扇区数
# field15 I/O总等待时间(ms)
I/O性能优化是系统工程,需要从调度器选型、文件系统配置、队列参数、挂载选项多个层面协同调优。实际生产环境中应基于基准测试结果逐步调整,每次只改一个参数,量化对比效果,避免多变量同时修改导致无法归因。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-ci-pan-io-xing-neng-you-hua-shi-zhan-io-diao/