ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

PSIをLXCのコンテナで試す: その(1) CPU Pressure

あらすじ

PSIという新しいシステムプレッシャーの指標が Linux 4.20 から利用できます。という内容を前回のブログに書いた。

udzura.hatenablog.jp

今日はこのPSIについて、実際にシステムに負荷をかけたりして変動を眺める。

下準備として cgroup v2 をシステムで利用可能にする

大前提として:

  • デフォルトの設定のままではsystemdがcgroup v1を利用する
  • あるプロセスがcgroup v1で制御されているとcgroup v2では制御出来ない

こういう仕様があり、普通に起動してもcgroup v2のルートの cgroup.controllers は空っぽである。回避策はカーネルの起動パラメータ等でsystemdにcgroup v2のみを利用させること。以下の記事に詳しい。

qiita.com

この手順そのままに systemd.unified_cgroup_hierarchy=1 を追加。

コンテナの準備をして負荷をかける

以下のような感じでLXCのコンテナを用意する。一応、debianのテンプレートにapache2を素のまま入れて立ち上げたものを用意した。トップのindex.htmlも素のまま。

root@ubuntu1804:~# lxc-ls -f
NAME            STATE   AUTOSTART GROUPS IPV4     IPV6 UNPRIVILEGED 
cg2-test-apache RUNNING 0         -      10.0.1.2 -    false        

CPU利用率上限は変更なしとする(追記、cpu.maxは記憶違いがあるかも。次回記事に書いた)。weightがあるのでホスト全ては使わない(という認識でOKでしょうか...)。

root@ubuntu1804:~# echo 'max 100000' > /sys/fs/cgroup/lxc/cg2-test-apache/cpu.max
root@ubuntu1804:~# cat /sys/fs/cgroup/lxc/cg2-test-apache/cpu.max
max 100000
root@ubuntu1804:~# echo '100' > /sys/fs/cgroup/lxc/cg2-test-apache/cpu.weight
root@ubuntu1804:~# cat /sys/fs/cgroup/lxc/cg2-test-apache/cpu.weight
100

このコンテナに以下のようにapache benchを流す。

ab -c 1000 -n 500000 http://10.0.1.2/ # 時間がかかり過ぎたので 300000件前後で中止

別のターミナルで1秒ごとに cpu.pressure を眺める。

while true; do cat /sys/fs/cgroup/lxc/cg2-test-apache/cpu.pressure; sleep 1; done

結果

まずはベンチはこう。

root@ubuntu1804:~# ab -c 1000 -n 500000 http://10.0.1.2/                                                                                                                      
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>                                                                                                                       
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/                                                                                                      
Licensed to The Apache Software Foundation, http://www.apache.org/                                                                                                            
                                                                                                                                                                              
Benchmarking 10.0.1.2 (be patient)                                                                                                                                            
Completed 50000 requests                                                                                                                                                      
Completed 100000 requests                                                                                                                                                     
Completed 150000 requests                                                                                                                                                     
Completed 200000 requests                                                                                                                                                     
Completed 250000 requests                                                                                                                                                     
Completed 300000 requests                                                                                                                                                     
^C                                                                                                                                                                            
                                                                                                                                                                              
Server Software:        Apache/2.4.25                                                                                                                                         
Server Hostname:        10.0.1.2                                                                                                                                              
Server Port:            80                                                                                                                                                    
                                                                                                                                                                              
Document Path:          /                                                                                                                                                     
Document Length:        10701 bytes                                                                                                                                           
                                                                                                                                                                              
Concurrency Level:      1000                                                                                                                                                  
Time taken for tests:   24.302 seconds                                                                                                                                        
Complete requests:      340403                                                                                                                                                
Failed requests:        0                                                                                                                                                     
Total transferred:      3737876546 bytes                                                                                                                                      
HTML transferred:       3644547762 bytes                                                                                                                                      
Requests per second:    14007.34 [#/sec] (mean)                                                                                                                               
Time per request:       71.391 [ms] (mean)                                                                                                                                    
Time per request:       0.071 [ms] (mean, across all concurrent requests)                                                                                                     
Transfer rate:          150206.03 [Kbytes/sec] received                                                                                                                       
                                                                                                                                                                              
Connection Times (ms)                                                                                                                                                         
              min  mean[+/-sd] median   max                                                                                                                                   
Connect:        0   34 139.6     17    3053                                                                                                                                   
Processing:     1   37  35.2     33     866                                                                                                                                   
Waiting:        0   21  34.8     15     849                                                                                                                                   
Total:          1   71 145.8     50    3297                                                                                                                                   
                                                                                                                                                                              
Percentage of the requests served within a certain time (ms)                                                                                                                  
  50%     50
  66%     53
  75%     56
  80%     57
  90%     62
  95%     67
  98%    277
  99%   1065
 100%   3297 (longest request)

並列数がすごいので割と刺さっているのだけれど、実際、 cpu.pressure の中身はこういう風に遷移した。avg10がぐんぐん上がる。

vagrant@ubuntu1804:~$ while true; do cat /sys/fs/cgroup/lxc/cg2-test-apache/cpu.pressure; sleep 1; done
some avg10=0.00 avg60=0.00 avg300=0.00 total=52240816  
some avg10=0.00 avg60=0.00 avg300=0.00 total=52240816  
some avg10=0.00 avg60=0.00 avg300=0.00 total=52240816  
some avg10=0.00 avg60=0.00 avg300=0.00 total=52369789  
some avg10=4.70 avg60=0.85 avg300=0.17 total=52765463  
some avg10=4.70 avg60=0.85 avg300=0.17 total=53110314  
some avg10=10.01 avg60=1.93 avg300=0.40 total=53465880 
some avg10=10.01 avg60=1.93 avg300=0.40 total=53874391 
some avg10=15.08 avg60=3.11 avg300=0.66 total=54271535
some avg10=15.08 avg60=3.11 avg300=0.66 total=54718949
some avg10=19.96 avg60=4.38 avg300=0.94 total=55099476
some avg10=19.96 avg60=4.38 avg300=0.94 total=55429605
some avg10=22.50 avg60=5.35 avg300=1.17 total=55719477
some avg10=22.50 avg60=5.35 avg300=1.17 total=55972911
some avg10=23.13 avg60=6.03 avg300=1.34 total=56250113
some avg10=23.13 avg60=6.03 avg300=1.34 total=56600171
some avg10=24.74 avg60=6.88 avg300=1.55 total=56939663
some avg10=24.74 avg60=6.88 avg300=1.55 total=57277269
some avg10=26.23 avg60=7.73 avg300=1.77 total=57640146
some avg10=26.23 avg60=7.73 avg300=1.77 total=58041730
some avg10=28.37 avg60=8.72 avg300=2.01 total=58429190
some avg10=28.37 avg60=8.72 avg300=2.01 total=58770530
some avg10=29.57 avg60=9.58 avg300=2.24 total=59105989
...

グラフにすると、確かに「負荷が上がっている」「abを止めたら落ち着く」ということが可視化できているように見える。

f:id:udzura:20190214194007p:plain

一方、メモリやIOはこのようなグラフを描かない。そもそも軽量なトップページの配信であるし、メモリも肥大しなかったのでそれぞれのリソースの負荷はあげられなかったのであろう。

ところで、cgroupであるので、もちろん他のcgroupのプレッシャーの値には影響を及ぼさない。例えば、同じ手順で負荷をかけた時に、 system.slice などの別のcgroupの値は全く変化しない。

vagrant@ubuntu1804:~$ while true; do cat /sys/fs/cgroup/system.slice/cpu.pressure; sleep 1; done                                                                             
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
some avg10=0.00 avg60=0.00 avg300=0.00 total=225848
...

また、同様の手順でシステム全体のLoad Averageを観察したが、もう少し上がり方が緩やかではありそう。同じホストでベンチを取ってるのでabの負荷がある気もする...。ベンチマシンを用意するなどもうちょっと環境を整えるのは宿題。

vagrant@ubuntu1804:~$ while true; do uptime; sleep 1; done
 02:23:24 up  3:32,  2 users,  load average: 0.63, 1.49, 1.57
 02:23:25 up  3:32,  2 users,  load average: 0.58, 1.46, 1.56
 02:23:26 up  3:32,  2 users,  load average: 0.58, 1.46, 1.56
 02:23:27 up  3:32,  2 users,  load average: 0.58, 1.46, 1.56
 02:23:28 up  3:32,  2 users,  load average: 0.58, 1.46, 1.56
 02:23:29 up  3:32,  2 users,  load average: 0.58, 1.46, 1.56
 02:23:30 up  3:32,  2 users,  load average: 0.85, 1.51, 1.57
 02:23:31 up  3:32,  2 users,  load average: 0.85, 1.51, 1.57
 02:23:32 up  3:32,  2 users,  load average: 0.85, 1.51, 1.57
 02:23:33 up  3:32,  2 users,  load average: 0.85, 1.51, 1.57
 02:23:34 up  3:32,  2 users,  load average: 0.85, 1.51, 1.57
 02:23:35 up  3:32,  2 users,  load average: 9.83, 3.36, 2.17
 02:23:36 up  3:32,  2 users,  load average: 9.83, 3.36, 2.17
 02:23:37 up  3:32,  2 users,  load average: 9.83, 3.36, 2.17
 02:23:38 up  3:32,  2 users,  load average: 9.83, 3.36, 2.17
...

こんな感じで、PSIは確かに何かに使えそう?という感じがしてきた。次はコンテナの種類を変えて、メモリバインド/IOバインドなアプリケーションを考えて負荷を掛けて見てみたい。


2019/02/15 ABのコマンドと結果が、掲載したグラフの時のベンチのものではなかったので修正。