2020/3/4「OZV勉強会LT」「Linux」niceコマンドで知るプロセスと優先順位
2020年03月04に作成された記事です。
オズビジョン社内勉強会LT資料です。
Niceとは
変更したスケジューリング優先度でプログラムを実行する
man page : https://linuxjm.osdn.jp/html/GNU_coreutils/man1/nice.1.html
nice [OPTION] [COMMAND [ARG]...]
-n, --adjustment=N
優先度に整数値 N を加える (デフォルト: 10)
--help
この使い方を表示して終了する
--version
バージョン情報を表示して終了する
Niceの使い方
# -n [niceness value] オプション必須
# nicenessの範囲は, 19 ~ -20 ※nicenessが低いほど、優先順位は高くなる
nice -n /something/default_nicevalue_is_10
nice -n 0 /batch_sh/something.sh #niceness valueを0
nice -n 5 zgrep "something text" very_huge_data.log.gz
nice -n 10 mysqldump -u user -p DBNAME TABLE_NAME > OUTPUT_FILE
nice -n -10 /something/this_is_high_priority_execution
プロセスの優先順位確認
psで確認
# PRI, NIを確認
[vagrant@comics ~]$ ps l
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
0 1000 22121 22120 20 0 124924 4256 - Ss pts/0 0:00 -bash
0 1000 22647 22121 20 0 160236 2204 - R+ pts/0 0:00 ps l
topで確認
# PR, NIで確認
[vagrant@comics ~]$ top
top - 18:36:27 up 2:22, 1 user, load average: 1.15, 0.77, 0.66
Tasks: 167 total, 3 running, 90 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.4 us, 2.9 sy, 0.0 ni, 94.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1009004 total, 263660 free, 337808 used, 407536 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 508032 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22255 apache 20 0 523200 30656 11248 R 20.6 3.0 0:00.69 httpd
3018 mysql 20 0 2050332 121596 19976 S 0.7 12.1 0:11.54 mysqld
8 root 20 0 0 0 0 R 0.3 0.0 0:03.04 rcu_sched
3217 root 20 0 236900 22764 4652 S 0.3 2.3 0:02.13 fluentd
22867 vagrant 20 0 171112 4592 3896 R 0.3 0.5 0:02.46 top
PRとNI
NIとは
プロセスのniceness値、優先順位補正値(ユーザースペース設定値)
PR(PRI)とは
カーネルススケジューラーで参考する、実際のプロセス優先順位
一般プロセスのPRの計算式 : 20 - NI
※ niceを指定せず実行する一般プロセスのPRは20になる。
※ リアルタイムプロセス(rt)の説明はここではしない。
プログラムとプロセス
プログラムとは?
コンピューターが解釈し実行できる命令語コードの集合。
一般的にはファイル形式で保存されている状態。
プロセスとは?
プログラムに対し、実行命令がくだされたタイミングから、生成される資源。
一般的人はプロセス資源はメモリーにロードされ、
OSのプロセススケジューリングのコントロールの制御下で、
上位のメモリと演算装置によって命令が処理される。
プログラムとプロセスの関係
プロセス優先順位の必要性
なぜ、OSは多数のプログラムを実行・処理できるのか?
基本的に、1CPU(1CORE)は1回1個の命令しか処理できない。(1回 = 1hz, 3Ghz = 1秒で30億回、命令を処理できる)
この制約条件下で、プログラムが同時に処理されていると感じる理由は
- OSの「プロセススケジューラー」のプロセスコントロール
- プロセスのステータス変化(Life Cycle)
の概念があって、成り立っている。
プロセススケジューリング
大体のOSは、複数のプロセスを処理するためにいろんなアルゴリズムを採用しているが、基本的にTime Sharingの概念を使っている。複数のプロセスが、優先順位によって、自分の順番で処理可能な時間が設定される。
わかりやすい例が、round-robinアルゴリズム
プロセスの状態変化(Life Cycle)
- creation : あらたらプロセスの生成
- dispatch : OSスケジューラーがCPUの計算時間を割り当て、処理を実行させること。Running状態に移行
- timeout : 割り当てられた計算時間の切れ。リソースを返却し、Ready状態に移行
- blocking/unblocking : プロセスのIO作業発生時にIO処理を待つためblock状態で待機、プロセサで制御
優先順位とスケジューリングがなかったらどうなるか?
複数のプロセスが、同じ時間の割当で、プロセスが増えるほど、全体の処理時間が遅延される。
問題は、重要なプロセス・システムプロセスにも影響が響きシステムの制御命令系が働かなくなること。
実務では
OS環境で何かを実行することは、プロセスになるということを意識する
サーバーで何らかのコマンド、プログラムを実行するということは、コンピューターの限られたリソースの一部を時間という形で占有することを意味する。
一般プロセスの優先順位は指定しない限りは、同じ比率のリソースを当て貼れられるので、プロセスが増えれば増えるほど他のプロセスの処理時間にも影響を及ぼすことになる。
niceは、この時間占有程度を指定し、プロセスごとの処理優先順位を制限的にコントロールできる。
# ありえる?
本番ウェブサーバーで、バッチ処理を追加したら、ウェブサイト全体の応答速度が落ちた。
>>> APACHE(prefork setting)の場合、1リクエストがプロセスになるので、当然プロセス優先順位の影響を受ける。
>>> バッチ処理が、時間に重要な処理じゃなければ、優先順位を下げて実行するようにする(サーバーを分けるまでではない場合)
本番バッチサーバーで、何らかのバッチを手動実行したら、
何時まで絶対周り終わらなきゃいけない、他のバッチの処理時間が遅延された。
>>> 手動で実行するバッチは特別な理由がない場合は、適切に優先順位を下げて実行する
niceの活用例
前提としては、リアルタイムの必要性が低く、重い処理を前提としている。
本番のバッチサーバーで、手動バッチ実行作業が必要
nice -n 10 /batch_sh/huge_time_and_low_priority.sh
mysqldumpで、大容量データのダンプ
nice -n 10 mysqldump -u xxxx -p DBNAME > all_db_dump.sql
本番のウェブサーバー、本番ログサーバーのgrep
nice -n 10 zgrep -E `^\d+$` 1GB_FILE.log.gz
# zgrepと正規表現の処理はCPUに負荷がすごくかかる作業
phpの中でのシステくコールによるバイナリ実行
exec('nice -n 10 /something/command', $result, $ret);
# バッチ処理の中でのシステムコールか、非同期処理の中で必要な場合
# システムコールを使うのに対しては推奨しないため、参考までに見ておくこと
結論
- APACHEも、バッチも、Shell Commandも、何ら化を実行したら、それはプロセス。
- プロセスは、限られた時間内で処理・待機を繰り返す。
- プロセスが増えるほど、全体プロセスの待機時間が伸び、処理自体が遅延される。
-
nice
コマンドで、プロセスに当てる時間を制限的にコントロールできる - 実行するプログラムの優先度・サーバーへの影響度を考え、
nice
を活用してみよう
※PS : プログラムの軽量化も大事。
renice
補足: 既存のプロセスのnicenessを変更
Discussion