読者です 読者をやめる 読者になる 読者になる

人間とウェブの未来

「ウェブの歴史は人類の歴史の繰り返し」という観点から色々勉強しています。

コマンド実行時のCPUやIOリソースを簡単に制御するツールrconを作った

プログラミング

CPUやメモリ、IOといったリソースの制限下でとあるコマンドを実行させたい場合に、cgroup上に何かgroupを作ったりしてからcgexecを実行して、実行後はそのgroupを消す、といったような一手間かかる方法がほとんどでした。

実行後のgroupも綺麗にしたい、といった所まで考えるとなかなか手間がかかっていたので、それらを全てワンラインでできるrconというワンバイナリで動くツールを作りました。

github.com

例えば、負荷サーバでの調査ツールを流す際に、CPUとかIOとかを制限しつつドロドロ実行したい場合等に便利です。Linuxのcgroup対応した環境でのみ動きます。

使い方

ほぼREADME通りなのですが、オプションは代替以下のようになっています。

--memは変なので--memoryに変更しました!!

 ./rcon --help
Usage: rcon [options] --user username --command "yes >> /dev/null"
    --cpu VAL
      default: 30 (%)
    --memory VAL
      default: 512000000 (Byte)
    --read VAL
      defualt: 10485760 (Byte/sec)
    --write VAL
      defualt: 10485760 (Byte/sec)
    --group VAL
      defualt: rcon
    --dev VAL
      default: 202:0
    --version

例えば、CPUを制限しつつ実行したい場合に、普通に以下のようなCPUを食うコマンドを実行すると、

yes >> /dev/null

CPUがガッと100%食われます。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
27577 matsumot  20   0 98.5m  608  520 R 100.0  0.0   0:01.95 yes 

それを、rconを使って10%の使用率に制限しつつ実行すると、

sudo ./rcon --user matsumotory --command "yes >> /dev/null" --cpu 10

こんな感じでCPUが10%以下に制限されつつ実行されます。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
23941 matsumot  20   0 98.5m  604  520 R  9.6  0.0   0:00.63 yes

お手軽で便利ですね。

また、IOを制限したい場合も、普通にddを実行すると、

dd if=/dev/zero of=tempfile bs=1M count=1000 oflag=direct

こんな感じでガッツリIOが使われます。

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
27569 be/4 matsumot    0.00 B/s   22.09 M/s  0.00 % 95.93 % dd if=/dev/zero of=tempfile bs=1M count=1000 oflag=direct

それを、例えばドロドロ1Mbyte/sec以下でwriteしたい場合には、rconで以下のように実行すると、

sudo ./rcon --user matsumotory --command "dd if=/dev/zero of=tempfile bs=1M count=1000 oflag=direct" --write 1024000

綺麗に1Mbyte/sec以下でwriteが走っています。

  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
24676 be/4 matsumot    0.00 B/s  995.77 K/s  0.00 % 99.99 % dd if=/dev/zero of=tempfile bs=1M count=1000 oflag=direct  

ちなみに、IOのデバイスはIDで指定しないといけないので、以下のように対象IOデバイスのIDを取得して、

$ ls -l /dev/xvda | awk '{print $5 $6}' | sed 's/,/:/'
202:0

--devオプションに渡すと、そのデバイスでのIOを制限してくれます。

また、--groupという機能もあって、デフォルトはrconグループなのですが、これを特定のgroup名に設定して実行した場合、例えば複数のrconで同一グループ内で実行すると、そこに属するグループは、指定したリソース内で共有しながら実行されます。

例えば、CPUを50%に制限して、同一グループでrcon経由で2つコマンドを実行すると、それぞれ25%のCPUを使いつつ実行されます。

loopのような処理をSIGTERMしたりSIGINTしても、cgroupをちゃんと掃除してくれるので、その辺りも割りと便利です。

ということでなかなか便利なので、ぜひご活用下さい。