月刊DBマガジン 2007/10
特集2 「はてな」の達人ワザを大公開! より
負荷分散というと、複数のサーバーに処理を分担させることだけに目がちだが、実際にはそれぞれのサーバー、つまり単一ホストの性能をどこまで引き出せるかも重要な項目となる。本来1台のサーバーで十分なところを、その性能を引き出す努力をせずに10台のサーバーで運用するというのは本末転倒な話である。
負荷分散と冗長性は切っても切り離せない関係、いわば表裏一体だ。負荷分散のためにサーバー台数が増えれば、その分故障確立は上昇する。負荷は分散できても、しょっちゅう壊れて止まるシステムでは意味がない。つまり、負荷を分散し、故障しても動き続けるシステムを構築する必要がある。負荷分散はトラフィックとの戦いであると同時に、SPOFとの戦いでもある
ボトルネックといってもいろいろなレイヤがあるが、今回はOS(Linux)に関する範囲を考える。ボトルネックに関して調査する場合はOS=Linuxカーネルと思ってよい。Linuxカーネルの動作について知ることは大切。こと単一ホストの性能分析に関しては、次の2項が重要となる。
その他
これはもはや慣用句。
ps auxw
表1:auxwのオプション一覧
| オプション | 意味 |
| a | 端末に結び付いている、自分が実行しているもの意外も含めたすべてのプロセスを表示 |
| u | ユーザー指向出力(USE, %CPU, %MEM, VSZ, RSS, STARTカラムを追加したもの)を利用する |
| x | 端末に結び付いていないプロセスも表示 |
| w | プロセス名を長めに表示する(wwで無制限) |
障害時や過負荷時に、psの出力をファイルに保存しておくと、その後の調査に役立つ。「-sort条件」でメモリ使用量順にソートしておくと、より調査が行いやすくなる。
ps auxw -L --sort=-vsz > /tmp/ps.YYYYMMDD ps auxw -L --sort=-vsz > /tmp/ps.`date +%Y%m%d%k%M%S`
メモリが足りないときは、どのプロセスが実際にメモリを使っているかを調べる必要がある。仮想メモリ機構の話を覚えておけば、ケースによってVSZをみるかRSSを見るべきかの判断が行えるだろう。
仮想メモリ機構
最後の点が、VSZとRSSの差につながっている。
表2:auxwのカラムの意味
| USER | プロセスを実行しているユーザー名 |
| PID | プロセスID |
| %CPU | 現在のCPU使用率 |
| %MEM | 現在のメモリ使用率 |
| VSZ | 仮想メモリに割り当てられたメモリ容量(KB) |
| RSS | 実際に物理メモリに割り当てられたメモリ容量(KB) |
| TTY | プロセスに紐付いている意味 |
| STAT | プロセスの状態 |
| START | プロセスの開始日時 |
| TIME | プロセスのCPU使用合計時間 |
| COMMAND | プロセス名(コマンド名) |
実際に負荷が高くなったとき、プロセス全体がどのような状態になっているのか、負荷上昇はどのプロセスが原因なのかを判定するのに役立つ。
表3:STAT項の意味
| STAT項 | 意味 |
| R | そのプログラムが今まさにCPU上で実行されている |
| S | 仕事がない、あるいは何かの事象を待ってスリープしている |
| D | ディスクI/Oなどを待って仕事ができない状態 |
| T | デバッグのためにトレースされている |
| Z | ゾンビになってしまった |
プロセスが起動されてから今まで経過した時間ではなく
何か暴走しているプログラムがあった場合にはこのTIMEの絶対数、あるいは何度かpsコマンドを実行した際の差分を見ればすぐに分かる。
無限ループするプログラムならば、STAT項がR(RUNNING)状態になりTIMEの数値が目に見えて上昇するのですぐ判断できる。
(mysqlの)プロセス数を以下のように調べることがよくあると思う。
ps auxw | grep mysql | grep -v grep | wc -l
実際のプロセス数より少ない場合がある。 結論から言うとこれは新しいスレッドライブラリ(NPTL)が使われている場合だ。
最初の例は以下のように書き換えられる。
ps auxw -L | grep mysql | grep -v grep | wc -l
ホストの稼働状況を定期的に更新されるスナップショットで閲覧できるツール。
topは使用中にキーボードの特定文字を押すと、表示を切り替えられる。たとえば「M」を押すと、プロセス表示をメモリ使用量順に並べ替えることができる。
状況が刻一刻と変化している中、その全体をまとめて把握したいときに利用するのが望ましい。 例えばボトルネックがどこにあるのかをすぐに把握できない状態で、まずは調査の入り口としてtopを使うといった具合である。
時間の推移とともに変化をみたいときはsarを使うほうが望ましい。
topの右上最上位に表示される小数点2桁の数値。 load averageはホストの負荷状況の目安となる数字。
正確には「実行したいけれども、何らかの待ち(CPUの割り当て待ちやディスクI/O待ちなど)で実行できず、待たされているプロセス(スレッド)の数」を表す。
左から順番に、1分間、5分間、15分間それぞれのスレッド数の平均。
ときおり、搭載CPU(の合計コア)数より低ければ大丈夫、つまりCPUが1個のシステムなら1.00以下、4つまであれば4.00以下までOKとされる場合があるが、鵜呑みにしてはいけない。(後述)
なお、load averageはあくまで「システム全体」の負荷を表す指標だ。決してCPUやメモリ、ディスクI/Oなど特定のハードウェアの状況を表す数字ではない。load averageからはCPUの能力が足りない、メモリが足りないといった断定ができないことに注意してほしい。
Cpu(s)は純粋にCPUの使用率を表す。
表4:Cpu(s)項の意味
| 項目 | 意味 |
| us(user) | ユーザーモードでCPUが消費された時間の割合(通常のアプリケーションの実行) |
| sy(system) | カーネルモードでCPUが消費された時間の割合 |
| ni(nice) | niceでスケジュールプライオリティを変更されたプロセスがユーザーモードでCPUを消費した割合 |
| id(idle) | CPUがディスクI/Oなどで待たされることなく、アイドル状態で消費した時間の割合 |
| wa(I/O wait) | CPUがディスクI/O待ちのためにアイドル状態で消費した時間の割合 |
| hi(hardware irq) | CPUがハードウェア割り込み処理に消費した時間の割合 |
| si(software irq) | CPUがソフトウェア割り込み処理に消費した時間の割合 |
idleはCPUがほとんど何もしていない状態を示す。idleの数字が常に高い場合は、そのシステムにはまだ十分なCPUリソースが残っている。
waitはディスクI/OでCPUが待たされてしまった時間である。この値が高いということは、ディスクI/Oがシステム全体のボトルネックになっているという証明となる。要改善のアラート。
Mem行が物理メモリ、Swap行がスワップメモリの利用状況。単位はキロバイト。 画面の出力幅が足りないのが理由で、スワップメモリと関係ないchachedの値もSwap行にあることに注意。
Mem: 8234740k total, 7216792k used, 1017948k free , 76956k buffers Swap: 2048276k total, 124k used, 2048152k free, 6571540k cached (抜粋)
メモリの使用割合の見方に注意。上記を一見すると搭載メモリ量(total)8GBのうち、7GBが使用済み(used)であり、アプリケーションに割り当てられるメモリは残り(free)1GBしかない、つまり、メモリの使用率は90%近くに見える。しかしこの見方は正確ではない。重要なのは、物理メモリに割り当てたれている7GBのうち、6GB強がキャッシュメモリとして確保されている(cached)という点だ。
Linuxはディスクからデータを読み取ると、それをメモリ上に可能な限りキャッシュする。このキャッシュは「ページキャッシュ」と呼ばれる。
Linuxはページキャッシュの上限を決めていないので、メモリに空きがある限り、その空き分をページキャッシュに確保する。アプリケーションでメモリが必要になった場合は、ページキャッシュで確保した分が優先的に開放され、アプリケーションに割り当てられる。
したがって、上記例ではメモリはまだ潤沢にあると思ってよいということになる。
表5:メモリ利用状況
| 項目 | 意味 |
| Mem: total | 物理メモリの搭載量 |
| Mem: used | 物理メモリのうちどの程度がプログラムに割り当てられているか |
| Mem: free | 物理メモリのうちどの程度が空いているか |
| Mem: buffers | カーネルバッファに割り当てられている物理メモリ量 |
| Mem: cached | 物理メモリに割り当てられているメモリのうち、キャッシュとして利用されているメモリ量。 |
sarはsystem activity reporterの略。sysstatパッケージに含まれる。
yum install syssat
最も有用。各種の情報の確認が可能。
上記以外にも、各種の情報の確認が可能。 非常に多くのオプションがあり、閲覧可能なレポートもオプションの数同様に多い。ただし、負荷計測に限ればある程度見るべき項目は限られてくる。
sarが最も役に立つのは、後日に行う負荷分析やボトルネック分析においてである。システムのスループットに問題があった場合に、その原因を探ったり、その時間帯にシステムがどのような状況にあったかを後日調査したりするのがsarの役割だ。
「-q オプション」でload averageを閲覧して、システムが重かった時間帯を割り出し、そのほかのオプションでボトルネックがどこにあるのかを見極める。
また、リアルタイムでの閲覧も可能なので、何か問題があったら即座にpsやtopである程度原因を絞り込み、sarでボトルネックと思われる項目の数字を確認できる。
まとめ
sarはcronによって起動され、定期的にOSのデータを収集している。sarとするとデフォルトではその過去のCPU利用率を表示する。
CentOSの場合、「/var/log/sa」に過去データが蓄積されており、データは「sa + 日付」というファイル名で保存される。「-fオプション」でファイルを指定して表示できる。
sar -f /var/log/sa/sa07
sarは現在の状況を調べる場合にも利用可能。 コマンドライン引数で、データの表示間隔と表示回数を指定して起動する。
sar 1 100
とすると、1秒おきに100回、CPU利用状況をリアルタイムで表示できる。
sarはデフォルトでCPU負荷を表示する。 明示的に指定したい場合は「-u オプション」を使用する。
複数のCPUが搭載されている場合(マルチコアなど)は、CPU別に閲覧しなければ状況が分からないケースがある。そんなときは「-P オプション」を使う。
「-P オプション」を付けなかった場合には、複数のCPU使用率の平均値になる点に注意。
「-r オプション」はメモリ使用状況を見ることができる。各項目はtopとほぼ同じ。
sarでメモリ使用状況が分かってうれしいのは、過去のデータが閲覧できるからだ。OSの立ち上がりからアプリケーションが安定するまで、OS全体のメモリ使用の内訳がどのように推移していくのかを後日でも確認できるし、スワップが大量に発生してシステムパフォーマンスが低下した場合も、どの程度のメモリが使われていたかなどを把握できる。
「-q オプション」ではload averageの推移に加えて、以下の2種類のプロセス数を表示できる。
load averageはシステム全体のパフォーマンスの目安になる数字である。あくまである程度の目安を確認するもの。 しかし、昨晩のパフォーマンスはどうdったか、という場合にsarの「-q オプション」を使えば、その推移をはっきりと見て取れる。
スワップが発生すると、ディスクI/Oが発生し、システム全体のスループットは急激に低下する。 スワップを発生させないよう適切にリソースを管理するのは負荷分散の基本である。
「-W オプション」では、スワップが単位時間にどの程度発生したかを表示することが可能。すべて0.00であればスワップ(ページスワップイン/ページスワップアウト)は発生していない。
スワップが発生しているかどうかは、「vmstat コマンド」でも確認できる。
「si(swap in)」と「so(swap out)」の項目がある。 この項が0以上の値で頻繁に更新されるようであれば、スワップが発生してシステム全体のスループットに影響を与えていると思って間違いない。
top
LinuxThreads(古いプロセス)
ps auxw | grep <プロセス名> | grep -v grep | wc -l
NPTL(新しいプロセス)
ps auxw -L | grep mysql | grep -v grep | wc -l
psの「VSZ」や「RSS」を見る。
psの「TIME」の値または増加ペース、「STAT」がRかを確認。
psの「VSZ」や「RSS」を確認。
メモリ使用量順にソート
ps auxw -L --sort=-vsz
sarの「-u オプション」で%iowait項を確認。
sarの「-u オプション」で%userや%system、%idleを確認。
sarの「-W オプション」。
vmstatの「si(swap in)」と「so(swap out)」。
sarの「-r オプション」で確認
Linux のメモリー管理(メモリ−が足りない?,メモリーリークの検出/防止) http://www.math.kobe-u.ac.jp/~kodama/tips-free-memory.html#memory_swap
Keyword(s):[Linux] [ボトルネック]
References: