hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

sarコマンドの%stealの意味について



1 はじめに

1.1 概要

sarコマンドやvmstatコマンドを使用すると、「%steal」という項目が表示されます。この項目は、仮想マシンのvCPUがホストの物理CPUに割り当てられない割合を表しています。この記事では、意図的にvCPUが物理CPUに割り当てられない状況を作り出し、「%steal」がどのように変化するかを検証してみます。

1.2 出力例

sarコマンドを実行すると、右から2列目に「%steal」が表示されていることがわかります。なお、sarコマンドの使い方は、sarコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# sar 1 -P ALL
19時22分50秒	CPU	%user	%nice	%system	%iowait	%steal	%idle
19時22分51秒	all	0.00	0.00	0.00	0.00	0.00	100.00
19時22分51秒	0	0.00	0.00	0.00	0.00	0.00	100.00
-snip-

vmstatコマンドを実行すると、右端に「st」(%steal)が表示されていることがわかります。なお、vmstatコマンドの使い方は、vmstatコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# vmstat 1 -w
   r    b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
   0    0            0      3368808         1636       185800    0    0    47     2   44   32   0   1  97   2   0
-snip-

1.3 検証方針

「%steal」の変化を確認するため、以下の手順を実行します。
1. 仮想マシンのvCPU(X)を物理CPU(Y)に固定的に割り当てる。
2. vCPU(X)で実行するプロセスより優先度の高いプロセスを物理CPU(Y)で実行して、vCPU(X)で実行するプロセスの時間を少なくする。

2 検証環境

2.1 版数の確認

仮想マシンのAlmaLinux版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
AlmaLinux release 9.2 (Turquoise Kodkod)

仮想マシンカーネル版数は以下のとおりです。

[root@server ~]# uname -r
5.14.0-284.11.1.el9_2.x86_64

2.2 搭載CPU数の確認

仮想マシンはCPUを4個搭載しています。なお、lscpuコマンドの使い方は、lscpuコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# lscpu -xe
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
  0    0      0    0 0:0:0:0          yes
  1    0      1    1 1:1:1:1          yes
  2    0      2    2 2:2:2:2          yes
  3    0      3    3 3:3:3:3          yes

kvmホストはCPUを8個搭載しています。

[root@kvm ~]# lscpu -xe
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
  0    0      0    0 0:0:0:0          yes
  1    0      1    1 2:2:2:2          yes
  2    0      2    2 4:4:4:4          yes
  3    0      3    3 6:6:6:6          yes
  4    0      4    4 8:8:8:8          yes
  5    0      5    5 10:10:10:10      yes
  6    0      6    6 12:12:12:12      yes
  7    0      7    7 14:14:14:14      yes

3 実験1

以下の方針で検証環境を作成します。
1.アフィニティ
・vCPU0を物理CPU6に固定的に割り当てる。vCPUと物理CPUを固定的に割り当てることができれば、どのように割り当ててもかまいません。
2.CPU負荷
・物理CPU6でCPU使用率90%のリアルタイムプロセス(優先度99)を実行する。
・vCPU0でCPU使用率90%のタイムシェアリングプロセス(優先度120)を実行する。

3.1 事前準備

virsh vcpuinfoコマンドを使用すると、vCPU0が物理CPU6に割り当てられていることがわかります。しかし、CPUアフィニティが物理CPU0から物理CPU7に設定されているので、物理CPUの負荷状況によっては、vCPU0が物理CPU6以外に割り当てられる可能性があります。

[root@kvm ~]# virsh vcpuinfo --pretty 01_server_alma92
VCPU:           0
CPU:            6
状態:         実行中
CPU 時間:     33.6s
CPU アフィニティー: 0-7/8
-snip

そこで、vCPU0を物理CPU6に固定的に割り当てるため、virsh vcpupinコマンドを使用してvCPU0を物理CPU6に固定します。

[root@kvm ~]# virsh vcpupin 01_server_alma92 --vcpu 0 6

仮想マシンを再起動します。

[root@kvm ~]# virsh reboot 01_server_alma92
ドメイン '01_server_alma92' は再起動されています

virsh vcpuinfoコマンドを実行すると、CPU アフィニティーが物理CPU6となっているので、vCPU0が物理CPU6に固定的に割り当てられていることがわかります。

[root@kvm ~]# virsh vcpuinfo --pretty 01_server_alma92
VCPU:           0
CPU:            6
状態:         実行中
CPU 時間:     58.4s
CPU アフィニティー: 6/8
-snip-

3.2 動作検証(kvmホストのCPUに負荷をかける)

stress-ngコマンドを以下の条件で実行します。なお、stress-ngコマンドの使い方は、stress-ngコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
・物理CPU6でCPU使用率90%のstress-ngプロセスを実行する。
・stress-ngプロセスは、ラウンドロビン(RR)のスケジューリングポリシーでリアルタイムプロセスとして実行する。

[root@kvm ~]# stress-ng -k -l 90 -c 1 --taskset 6 --sched rr --sched-prio 99 -q &

psコマンドでstress-ngプロセスの状態を確認します。物理CPU6でCPU使用率90%程度で動作していることがわかります。また。ラウンドロビン(RR)のスケジューリングポリシーで優先度99のリアルタイムプロセスとして動作していることがわかります。なお、psコマンドの使い方は、psコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@kvm ~]# ps -C stress-ng -o comm,pid,ppid,psr,%cpu,cls,ni,rtprio
COMMAND             PID    PPID PSR %CPU CLS  NI RTPRIO
stress-ng          2476    2209   6  0.0  RR   -     99
stress-ng          2477    2476   6 89.0  RR   -     99

仮想マシンでsarマンドを実行すると、CPU全体(all)の「%steal」が約7%、vCPU0の「%steal」が22%であることがわかります。

[root@server ~]# sar -P ALL 1
22時01分16秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
22時01分17秒     all      0.00      0.00      0.00      0.00      6.76     93.24
22時01分17秒       0      0.00      0.00      0.00      0.00     22.48     77.52
22時01分17秒       1      0.00      0.00      0.00      0.00      0.00    100.00
22時01分17秒       2      0.00      0.00      0.00      0.00      0.00    100.00
22時01分17秒       3      0.00      0.00      0.00      0.00      0.00    100.00
-snip-

さらに、ターミナルを開いてvmstatコマンドを実行してみます。sarコマンドとvmstaコマンドを同時に実行して結果を見比べると、vmstatコマンドの「st」列はsarコマンドのCPU全体の「%steal」に相当することがわかります。

[root@server ~]# vmstat 1 -w
--procs-- -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
   r    b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
   2    0            0      3379184         1636       185656    0    0    21     1   23   22   0   0  94   0   5
   0    0            0      3379184         1636       185656    0    0     0     0   73   92   0   0  93   0   7
   0    0            0      3379184         1636       185656    0    0     0     0   56   75   0   0  89   0  11
-snip-

3.3 動作検証(仮想マシンのCPUに負荷をかける)

さらに、kvmホストでもstress-ngプロセスを実行します。kvmホストで優先度の高いstress-ngプロセスを実行すると、仮想マシンで実行するstress-ngプロセスが実行されにくくなります。

[root@server ~]# stress-ng -k -l 90 -c 1 --taskset 0 -q &

psコマンドを使用して、stress-ngプロセスの状態を確認します。stress-ngプロセスをCPU使用率90%で起動していますが、仮想マシンで実行しているプロセスよりも優先度の高いプロセスがkvmホストで実行されているので、vCPU0のCPU使用率が約7%であることが確認できます。また、このプロセスがタイムシェアリングプロセス(TS)として実行されていることも確認できます。

[root@server ~]# ps -C stress-ng -o comm,pid,ppid,psr,%cpu,cls,ni,rtprio
COMMAND             PID    PPID PSR %CPU CLS  NI RTPRIO
stress-ng          1303    1271   0  0.0  TS   0      -
stress-ng          1304    1303   0  7.4  TS   0      -

sarコマンドを実行します。vCPUでstress-ngプロセスを実行すると、vCPUが物理CPUに割り当てられる割合が少なくなるので、「%steal」の値が大きくなることがわかります。

[root@server ~]# sar -P ALL 1
平均値:      CPU     %user     %nice   %system   %iowait    %steal     %idle
平均値:      all      2.26      0.00      0.25      0.00     22.56     74.94
平均値:        0      9.15      0.00      0.34      0.00     90.51      0.00
平均値:        1      0.00      0.00      0.33      0.00      0.00     99.67
平均値:        2      0.00      0.00      0.33      0.00      0.66     99.01
平均値:        3      0.00      0.00      0.00      0.00      0.33     99.67

vmstat コマンドを実行します。「st」列を確認すると、22%程度(全vCPUの25%)になっていることがわかります。

[root@server ~]# vmstat 1 -w
--procs-- -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
   r    b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
   1    0            0      3330928         1636       208972    0    0     9     0   30   20   1   0  86   0  13
   1    0            0      3330928         1636       208972    0    0     0     0  287   95   2   0  76   0  22
   1    0            0      3330928         1636       208972    0    0     0     0  151   68   2   0  75   0  22
   1    0            0      3330928         1636       208972    0    0     0     0  337  138   2   0  76   0  22

4 実験2

以下の方針で検証環境を作成します。
1. アフィニティ
・vCPU0を物理CPU6に固定的に割り当てる。
・vCPU1を物理CPU7に固定的に割り当てる。
2. 物理CPUの負荷
・物理CPU6でCPU使用率90%のリアルタイムプロセス(優先度99)を実行する。
・物理CPU7でCPU使用率90%のリアルタイムプロセス(優先度99)を実行する。
3. 仮想CPUの負荷
・vCPU0でCPU使用率90%のタイムシェアリングプロセス(優先度120)を実行する。
・vCPU1でCPU使用率90%のタイムシェアリングプロセス(優先度120)を実行する。

仮想マシンでstress-ngコマンドを実行します。

[root@server ~]# stress-ng -k -l 90 -c 1 --taskset 0 -q &
[root@server ~]# stress-ng -k -l 90 -c 1 --taskset 1 -q &

kvmホストでstress-ngコマンドを実行します。

[root@kvm ~]# stress-ng -k -l 90 -c 1 --taskset 6 --sched rr --sched-prio 99 -q &
[root@kvm ~]# stress-ng -k -l 90 -c 1 --taskset 7 --sched rr --sched-prio 99 -q &

sarコマンドを実行すると、vCPU0とvCPU1の「%steal 」の値が約90%となっていて、vCPU0とvCPU1は物理CPUにほとんど割り当てられていないことがわかります。また、allの「%steal 」は約45%になっていて、仮想マシンのvCPUの約半分が物理CPUに割り当てられていないことがわかります。

[root@server ~]# sar -P ALL 1
Linux 5.14.0-284.11.1.el9_2.x86_64 (server)     2023年12月02日  _x86_64_        (4 CPU)

20時50分55秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
20時50分56秒     all      4.31      0.00      0.25      0.00     44.92     50.51
20時50分56秒       0      8.25      0.00      0.00      0.00     91.75      0.00
20時50分56秒       1      9.28      0.00      0.00      0.00     90.72      0.00
20時50分56秒       2      0.00      0.00      0.99      0.00      0.00     99.01
20時50分56秒       3      0.00      0.00      0.00      0.00      0.00    100.00

vmstatコマンドを実行します。「st」列の値が約45%になっていて、仮想マシンのvCPUの約半分が物理CPUに割り当てられていないことがわかります。

[root@server ~]# vmstat 1 -w
--procs-- -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
   r    b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
   2    0            0      3361036         1636       193308    0    0    23     1   28   25   0   1  94   0   6
   3    0            0      3361036         1636       193308    0    0     0     0  527  194   4   0  51   0  44
   2    0            0      3361036         1636       193308    0    0     0     0  360  137   5   1  50   0  45
   2    0            0      3361036         1636       193308    0    0     0     0  395  153   5   0  50   0  45
-snip-

5 まとめ

・「%steal」項目は、vCPUが物理CPUに割り当てられなかった割合を表しています。
・vCPUでプロセスを実行していない場合より、vCPUでプロセスを実行している方が、「%steal」の値は大きくなります。

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ