为什么 io 调度程序不合并请求?

为什么 io 调度程序不合并请求?

服务器重启一段时间后(或写入一定量的数据后),写入速度会下降到 1 MB/s 以下。无论使用哪种文件系统(也包括原始分区),也无论使用 HDD(HW RAID)还是 SSD(SW RAID,SSD 连接到主板 AHCI 端口,而不是 RAID 板),都是如此。我们正在使用命令进行测试dd if=/dev/zero of=tst bs=1M oflag=dsync(我也尝试过1k,也尝试过不使用dsync,但性能并没有更好)。

我注意到的唯一奇怪的事情是avgrq-sziostat 输出中只有 8(在其他测试服务器上超过 600),并且 req/s 大约为 100(在 SSD 上也是如此)。并行运行更多时,dd每个线程的速度为 1 MB/s,每个线程大约有 100 req/s。

示例iostat -xN 1输出:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdc               0.00     0.00    0.00  125.00     0.00   500.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     0.00    0.00  124.00     0.00   496.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     3.00    0.00  128.00     0.00   524.00     8.19     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     6.00    0.00  124.00     0.00   728.00    11.74     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     0.00    0.00  125.00     0.00   500.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               0.00     3.00    0.00  128.00     0.00   524.00     8.19     0.00    0.00    0.00    0.00   0.00   0.00

8x 运行时的 Iostat 输出dd

sdc               0.00    64.00    0.00  959.00     0.00  7560.00    15.77     0.00    0.00    0.00    0.00   0.00   0.00

lsblk -O输出与其他服务器一致,没有此问题(如 MIN-IO、RQ-SIZE、LOG-SEC)。当前内核是 4.9.16-gentoo,但问题始于较旧的内核。运行dd速度oflag=direct很快。

编辑:根据 shodanshok 的回答,我现在看到请求确​​实很小,但问题是为什么 io 调度程序不将它们合并为更大的请求?我尝试了cfqdeadline调度程序。有什么我可以检查的吗(或与其他服务器进行比较)?

运行时的输出oflag=direct(速度正常):

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdc               0.00     0.00    2.00  649.00     8.00 141312.00   434.16     2.78    4.26    2.00    4.27   1.53  99.60
sdc               0.00     0.00    0.00  681.00     0.00 143088.00   420.23     2.71    3.99    0.00    3.99   1.46  99.20
sdc               0.00     0.00    2.00  693.00     8.00 146160.00   420.63     2.58    3.71    0.00    3.72   1.42  98.80
sdc               0.00    49.00    2.00  710.00     8.00 146928.00   412.74     2.68    3.76   22.00    3.71   1.39  99.20
sdc               0.00     0.00    1.00  642.00     4.00 136696.00   425.19     2.43    3.79   60.00    3.71   1.42  91.60

服务器是 Dell PowerEdge R330,32 GB RAM,LSI MegaRAID 3108 控制器,带 HDD、SSD 连接到板载 SATA,Intel E3-1270 CPU。文件系统为 ext3,但dd原始分区也会出现同样的情况。

输出lsblk(sdc 是 HW RAID HDD,sda/sdb 是 SW RAID SSD):

NAME    MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb       8:16   0 223.6G  0 disk
|-sdb4    8:20   0     1K  0 part
|-sdb2    8:18   0   140G  0 part
| `-md1   9:1    0   140G  0 raid1 /
|-sdb5    8:21   0    25G  0 part
| `-md2   9:2    0    25G  0 raid1 /var/log
|-sdb3    8:19   0     1G  0 part
|-sdb1    8:17   0    70M  0 part
| `-md0   9:0    0    70M  0 raid1 /boot
`-sdb6    8:22   0  57.5G  0 part
  `-md3   9:3    0  57.5G  0 raid1 /tmp
sr0      11:0    1  1024M  0 rom
sdc       8:32   0   3.7T  0 disk
`-sdc1    8:33   0   3.7T  0 part  /home
sda       8:0    0 223.6G  0 disk
|-sda4    8:4    0     1K  0 part
|-sda2    8:2    0   140G  0 part
| `-md1   9:1    0   140G  0 raid1 /
|-sda5    8:5    0    25G  0 part
| `-md2   9:2    0    25G  0 raid1 /var/log
|-sda3    8:3    0     1G  0 part
|-sda1    8:1    0    70M  0 part
| `-md0   9:0    0    70M  0 raid1 /boot
`-sda6    8:6    0  57.5G  0 part
  `-md3   9:3    0  57.5G  0 raid1 /tmp

速度oflag=direct还可以,但问题是应用程序不使用直接 io,所以即使是普通的速度也cp很慢。

/sys/block/sdc/queue/hw_sector_size : 512
/sys/block/sdc/queue/max_segment_size : 65536
/sys/block/sdc/queue/physical_block_size : 512
/sys/block/sdc/queue/discard_max_bytes : 0
/sys/block/sdc/queue/rotational : 1
/sys/block/sdc/queue/iosched/fifo_batch : 16
/sys/block/sdc/queue/iosched/read_expire : 500
/sys/block/sdc/queue/iosched/writes_starved : 2
/sys/block/sdc/queue/iosched/write_expire : 5000
/sys/block/sdc/queue/iosched/front_merges : 1
/sys/block/sdc/queue/write_same_max_bytes : 0
/sys/block/sdc/queue/max_sectors_kb : 256
/sys/block/sdc/queue/discard_zeroes_data : 0
/sys/block/sdc/queue/read_ahead_kb : 128
/sys/block/sdc/queue/discard_max_hw_bytes : 0
/sys/block/sdc/queue/nomerges : 0
/sys/block/sdc/queue/max_segments : 64
/sys/block/sdc/queue/rq_affinity : 1
/sys/block/sdc/queue/iostats : 1
/sys/block/sdc/queue/dax : 0
/sys/block/sdc/queue/minimum_io_size : 512
/sys/block/sdc/queue/io_poll : 0
/sys/block/sdc/queue/max_hw_sectors_kb : 256
/sys/block/sdc/queue/add_random : 1
/sys/block/sdc/queue/optimal_io_size : 0
/sys/block/sdc/queue/nr_requests : 128
/sys/block/sdc/queue/scheduler : noop [deadline] cfq
/sys/block/sdc/queue/discard_granularity : 0
/sys/block/sdc/queue/logical_block_size : 512
/sys/block/sdc/queue/max_integrity_segments : 0
/sys/block/sdc/queue/write_cache : write through

答案1

请求大小(avgrq-sz)很小,因为您发出小的写入请求。您的dd命令虽然指定了 1 MB 的块大小,但还是会命中页面缓存,因此每个 1 MB 请求实际上是 256 * 4 KB 请求的集合。这反映在 中avgrq-sz,以 512 字节为单位表示,与 4 KB 大小的页面条目完全一致。此外,即使是 SSD 在同步写入时也可能性能不佳,如 所请求的oflag=dsync。话虽如此,请注意 I/O 调度程序应该将这些 4 KB 大小的小请求合并到更大的请求中,但这并没有发生。

要检查的一些事项:

  • 您看到什么问题cat /sys/block/sdc/queue/scheduler?如果noop是选定的调度程序,请尝试选择deadline
  • 你的/sys/block/sdc/queue/max_sectors_kb至少是 1024 吗?
  • 尝试执行dd if=/dev/zero of=tst bs=1M oflag=direct:I/O性能应该高很多,对吧?

相关内容