systemd 资源控制 - IOWriteIOPSMax 不起作用?

systemd 资源控制 - IOWriteIOPSMax 不起作用?

我试图限制特定单元的 IO,但 IOWriteIOPSMax 属性似乎没有影响。

我最初尝试了 IOWeight,但这测试起来更具挑战性,IOPSMax 上的文档表明这是一个纯粹的限制。

pops 操作系统、systemd 249、cgroupv2

默认运行

user@x1:~/tmp$ systemd-run --user --same-dir --pipe --wait \
dd status=progress if=/dev/zero of=loadfile bs=1k count=5000024 

Running as unit: run-u233.service
4876370944 bytes (4.9 GB, 4.5 GiB) copied, 32 s, 152 MB/s 
5000024+0 records in
5000024+0 records out
5120024576 bytes (5.1 GB, 4.8 GiB) copied, 32.914 s, 156 MB/s
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 33.592s
CPU time consumed: 16.924s

有限制地运行 - 故意设置得非常低:

user@x1:~/tmp$ systemd-run --user --same-dir --pipe --wait \
-p IOAccounting=yes \
-p IOWriteIOPSMax="/dev/nvme0n1 5" \
-p IOReadIOPSMax="/dev/nvme0n1 5" \
dd status=progress if=/dev/zero of=loadfile bs=1k count=5000024 

Running as unit: run-u234.service
5090277376 bytes (5.1 GB, 4.7 GiB) copied, 19 s, 268 MB/s
5000024+0 records in
5000024+0 records out
5120024576 bytes (5.1 GB, 4.8 GiB) copied, 19.2141 s, 266 MB/s
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 19.899s
CPU time consumed: 16.838s

两次运行似乎花费相同的时间。systemctl show unit | grep IO确认两个属性均已设置。

在另一个窗口中观看iostat -xd 1/ dev/nvme0n1显示 300w/s ,我预计应用的属性会将其减少到 < 10,我的方法有什么问题吗?

编辑:添加/proc/self/cgroup信息:

user@x1:~$ systemd-run --user --same-dir --pipe --wait -p IOAccounting=yes -p IOWriteIOPSMax="/dev/nvme0n1 5" -p IOReadIOPSMax="/dev/nvme0n1 5" cat /proc/self/cgroup
Running as unit: run-u282.service
0::/user.slice/user-1000.slice/[email protected]/app.slice/run-u282.service

编辑:以 root 身份运行

root@x1:~# systemd-run  --same-dir --pipe --wait \
-p IOAccounting=yes \
-p IOWriteIOPSMax="/dev/nvme0n1 5" \
-p IOReadIOPSMax="/dev/nvme0n1 5" \
dd status=progress if=/dev/zero of=loadfile bs=1k count=5000024 

Running as unit: run-u1099.service
4847981568 bytes (4.8 GB, 4.5 GiB) copied, 17 s, 285 MB/s
5000024+0 records in
5000024+0 records out
5120024576 bytes (5.1 GB, 4.8 GiB) copied, 17.9437 s, 285 MB/s
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 17.945s
CPU time consumed: 16.748s
IO bytes read: 0B
IO bytes written: 0B

编辑:并作为标准单位。以 root 身份运行

root@x1:/etc/systemd/system# systemctl cat testme.service
# /etc/systemd/system/testme.service
[Service]
IOAccounting=yes
IOReadIOPSMax=/root 10
IOWriteIOPSMax=/root 10
ExecStart=dd status=progress if=/dev/zero of=/root/loadfile bs=1k count=5000024 


root@x1:/etc/systemd/system# journalctl -u testme.service -f
Nov 05 14:20:25 x1 systemd[1]: Started testme.service.
Nov 05 14:20:50 x1 dd[56684]: [1.3K blob data]
Nov 05 14:20:50 x1 dd[56684]: 5000024+0 records in
Nov 05 14:20:50 x1 dd[56684]: 5000024+0 records out
Nov 05 14:20:50 x1 dd[56684]: 5120024576 bytes (5.1 GB, 4.8 GiB) copied, 24.6735 s, 208 MB/s
Nov 05 14:20:50 x1 systemd[1]: testme.service: Deactivated successfully.
Nov 05 14:20:50 x1 systemd[1]: testme.service: Consumed 17.352s CPU time.

(相同的结果替换/root/dev/nvme..

答案1

答案分为两部分:

  • 设置时IOWriteIOPSMax,限制是通过io.maxcgroups 文件强制执行的。当以模式运行时--user,您无法更改 cgroup,因此该选项无效。
  • dd按照你的方式运行时,默认是使用异步I/O,这意味着在数据实际写入磁盘之前进程不会阻塞。这就是为什么IOWriteIOPSMax不会影响运行。为了真正测试它,您需要使用同步 I/O,以便数据实际上写入磁盘。您可以通过将oflag=sync标志添加到命令中来做到这一点dd

测试脚本

为了测试和确认这些条件,我创建了一个执行以下操作的脚本:

  1. 检查io.maxcgroup 文件是否存在,以及它是否确实有任何限制。
  2. 运行两个dd命令;第一个具有异步 I/O,第二个具有同步 I/O。
cat systemd_io.sh
#!/bin/bash
CGROUPS="$(</proc/self/cgroup)"
echo "/proc/self/cgroup: '$CGROUPS'" 
IO_MAX_FILE="/sys/fs/cgroup/${CGROUPS#0::/}/io.max"
if [ -f "$IO_MAX_FILE" ]
then
        IO_MAX="$(<$IO_MAX_FILE)" 
        if [ -z "$IO_MAX" ]
        then echo "$IO_MAX_FILE exists but is empty."
        else printf "Content of %s:\n%s\n" "$IO_MAX_FILE" "$IO_MAX"
        fi
else
        echo $IO_MAX_FILE does not exist.
fi
echo
echo Writing file without sync:
dd if=/dev/zero of=loadfile bs=1k count=10 2>&1 |tail -1
rm -f loadfile
echo
echo Writing file WITH oflag=sync:
dd if=/dev/zero of=loadfile bs=1k count=10 oflag=sync 2>&1 |tail -1
rm -f loadfile
echo

systemd-run带着--user旗帜奔跑

  • cgroupio.max文件甚至没有创建,因此 IO 没有限制。
root:~/tmp$ systemd-run --user --same-dir --pipe --wait -p IOWriteIOPSMax="/dev/vda 5" ./systemd_io.sh 2>/dev/null
/proc/self/cgroup: '0::/user.slice/user-0.slice/[email protected]/app.slice/run-u18.service'
/sys/fs/cgroup/user.slice/user-0.slice/[email protected]/app.slice/run-u18.service/io.max does not exist.

Writing file without sync:
10240 bytes (10 kB, 10 KiB) copied, 0.000142996 s, 71.6 MB/s

Writing file WITH oflag=sync:
10240 bytes (10 kB, 10 KiB) copied, 0.00483422 s, 2.1 MB/s

systemd-run--user旗运行和无旗运行IOWriteIOPSMax

  • cgroup文件io.max已创建但为空,因此没有任何限制。
  • 同步 I/O 的写入比率与用户的写入比率相同。
root:~/tmp$ systemd-run --same-dir --pipe --wait  ./systemd_io.sh 2>/dev/null
/proc/self/cgroup: '0::/system.slice/run-u187.service'
/sys/fs/cgroup/system.slice/run-u187.service/io.max exists but is empty.

Writing file without sync:
10240 bytes (10 kB, 10 KiB) copied, 0.000144849 s, 70.7 MB/s

Writing file WITH oflag=sync:
10240 bytes (10 kB, 10 KiB) copied, 0.00446492 s, 2.3 MB/s

systemd-run不带标志运行--user且带IOWriteIOPSMax

  • cgroupio.max文件具有由IOWriteIOPSMax.
  • 异步 I/O 不受影响(由于我上面提到的原因),但这次同步 I/O 比以前慢得多(1.8 kB/s,而不是 ~2 MB/s),确认有效IOWriteIOPSMax
root:~/tmp$ systemd-run --same-dir --pipe --wait -p IOWriteIOPSMax="/dev/sda 5" ./systemd_io.sh 2>/dev/null
/proc/self/cgroup: '0::/system.slice/run-u189.service'
Content of /sys/fs/cgroup/system.slice/run-u189.service/io.max:
253:0 rbps=max wbps=max riops=max wiops=5

Writing file without sync:
10240 bytes (10 kB, 10 KiB) copied, 0.000136314 s, 75.1 MB/s

Writing file WITH oflag=sync:
10240 bytes (10 kB, 10 KiB) copied, 5.78732 s, 1.8 kB/s

相关内容