Create  Edit  Diff  FrontPage  Index  Search  Changes  History  Source  Site Map  RSS  wikifarm  Login

hatena-tech

月刊DBマガジン 2007/10

特集2 「はてな」の達人ワザを大公開! より

負荷分散の話

負荷分散というと、複数のサーバーに処理を分担させることだけに目がちだが、実際にはそれぞれのサーバー、つまり単一ホストの性能をどこまで引き出せるかも重要な項目となる。本来1台のサーバーで十分なところを、その性能を引き出す努力をせずに10台のサーバーで運用するというのは本末転倒な話である。

負荷分散と冗長性は切っても切り離せない関係、いわば表裏一体だ。負荷分散のためにサーバー台数が増えれば、その分故障確立は上昇する。負荷は分散できても、しょっちゅう壊れて止まるシステムでは意味がない。つまり、負荷を分散し、故障しても動き続けるシステムを構築する必要がある。負荷分散はトラフィックとの戦いであると同時に、SPOFとの戦いでもある

  • SPOF: Single Point of Failure 、単一障害点。そこが壊れるとシステムが止まる箇所。

性能分析 - ボトルネックを調べるテクニック

ボトルネックといってもいろいろなレイヤがあるが、今回はOS(Linux)に関する範囲を考える。ボトルネックに関して調査する場合はOS=Linuxカーネルと思ってよい。Linuxカーネルの動作について知ることは大切。こと単一ホストの性能分析に関しては、次の2項が重要となる。

  • OSがプログラミングタスクをどのようにCPUに割り当てるか(プロセススケジューリングの仕組み)
  • ディスクI/Oはどのように発生し、どのようにキャッシュされるか(仮想ファイルシステムの仕組み)

負荷測定に使えるツール

  • ps (プロセス情報の表示)
  • top (稼働中システムのリアルタイムレポート)
  • sar (OS情報の収集、表示)
  • vmstat (仮想メモリの統計情報)

その他

  • strace (システムコールを追跡する)
  • netstat (ネットワーク状況を把握する)
  • gdb (デバッガ)
  • oprofile (プロファイラ)
  • tcpdump / wireshark (パケット解析)

ps

これはもはや慣用句。

ps auxw

表1:auxwのオプション一覧

オプション意味
a端末に結び付いている、自分が実行しているもの意外も含めたすべてのプロセスを表示
uユーザー指向出力(USE, %CPU, %MEM, VSZ, RSS, STARTカラムを追加したもの)を利用する
x端末に結び付いていないプロセスも表示
wプロセス名を長めに表示する(wwで無制限)

psはどのような場合に使うのか

  • プロセスの本数を数えて極端な増加がないか確認する
  • サーバーの負荷を計測する場合、どのプロセスがリソース消費の主な原因になっているかを調査する
  • 異常な動作をしているプロセス(メモリが極端に増えている、CPU時間を消費しすぎている)を見つける

障害時や過負荷時に、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を見るべきかの判断が行えるだろう。

仮想メモリ機構

  • 仮想メモリ機構によって、物理メモリ上は不連続な領域を、プロセスに対して連続したメモリ領域として見せることができる
  • それぞれのプロセスに対して、プロセスごとに独立したメモリ空間を持っているように見せかけられる。ほかのプロセスによる不正なメモリの変更から、プロセスを保護できる
  • 本来物理メモリに搭載されている容量以上のメモリを扱えるかのように、プロセスに見せかけられる

最後の点が、VSZとRSSの差につながっている。

表2:auxwのカラムの意味

USERプロセスを実行しているユーザー名
PIDプロセスID
%CPU現在のCPU使用率
%MEM現在のメモリ使用率
VSZ仮想メモリに割り当てられたメモリ容量(KB)
RSS実際に物理メモリに割り当てられたメモリ容量(KB)
TTYプロセスに紐付いている意味
STATプロセスの状態
STARTプロセスの開始日時
TIMEプロセスのCPU使用合計時間
COMMANDプロセス名(コマンド名)

STATが示すプロセスの状態

実際に負荷が高くなったとき、プロセス全体がどのような状態になっているのか、負荷上昇はどのプロセスが原因なのかを判定するのに役立つ。

表3:STAT項の意味

STAT項意味
Rそのプログラムが今まさにCPU上で実行されている
S仕事がない、あるいは何かの事象を待ってスリープしている
DディスクI/Oなどを待って仕事ができない状態
Tデバッグのためにトレースされている
Zゾンビになってしまった

TIMEの「時間」の意味

プロセスが起動されてから今まで経過した時間ではなく

  • プロセスがCPUをどのくらいの時間消費したかを示す値

何か暴走しているプログラムがあった場合にはこのTIMEの絶対数、あるいは何度かpsコマンドを実行した際の差分を見ればすぐに分かる。

無限ループするプログラムならば、STAT項がR(RUNNING)状態になりTIMEの数値が目に見えて上昇するのですぐ判断できる。

ps -LオプションとLinuxのマルチスレッド実装

(mysqlの)プロセス数を以下のように調べることがよくあると思う。

ps auxw | grep mysql | grep -v grep | wc -l

実際のプロセス数より少ない場合がある。 結論から言うとこれは新しいスレッドライブラリ(NPTL)が使われている場合だ。

古いスレッドライブラリ(LinuxThreads)
古くからの実装。
新しいスレッドライブラリ(NPTL)
Red Hatの技術者が中心となって開発された。glibcに含まれたことまり最近のディストリビューションではNPTLに統一されているが、例外もまだまだ多数。
  • LinuxThreadsはスレッド1本1本を、通常のプロセスと同様、1つのプロセスとして表示する
  • NPTLは-Lオプション(スレッド数、スレッドIDを表示するオプション)を加えない限り、スレッド1本のプロセスとして表示する。

最初の例は以下のように書き換えられる。

ps auxw -L | grep mysql | grep -v grep | wc -l

top

ホストの稼働状況を定期的に更新されるスナップショットで閲覧できるツール。

topは使用中にキーボードの特定文字を押すと、表示を切り替えられる。たとえば「M」を押すと、プロセス表示をメモリ使用量順に並べ替えることができる。

topはどのような場合に使うのか

状況が刻一刻と変化している中、その全体をまとめて把握したいときに利用するのが望ましい。 例えばボトルネックがどこにあるのかをすぐに把握できない状態で、まずは調査の入り口としてtopを使うといった具合である。

時間の推移とともに変化をみたいときはsarを使うほうが望ましい。

負荷のおおよその目安になるload average

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使用率

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がソフトウェア割り込み処理に消費した時間の割合
usが高い
ユーザーモードのプログラムの処理で時間を消費している。つまりカーネル以外のところに原因がある
syが高い
カーネルモードで時間を消費している。つまり、カーネル内部での処理で時間がかかっている、もしくは何らかのプログラムからのシステムコール呼び出し回数が多い
ユーザーモード
ApacheやMySQLなどのミドルウェア、開発した通常のアプリケーションの実行時のCPUモード。
カーネルモード
カーネルの仕事を行うときのCPUモード。カーネルはシステムの中枢の働きであるディスクI/Oやネットワークパケットの解析処理、プロセスのスケジューリング、時間の計算、メモリの管理といった仕事を担う。

idleとwait

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

sarはsystem activity reporterの略。sysstatパッケージに含まれる。

yum install syssat

最も有用。各種の情報の確認が可能。

  • CPU利用率
  • メモリ使用状況
  • load average、キューに溜まったプロセスの数
  • スワップの発生状況
  • プロセス生成数

上記以外にも、各種の情報の確認が可能。 非常に多くのオプションがあり、閲覧可能なレポートもオプションの数同様に多い。ただし、負荷計測に限ればある程度見るべき項目は限られてくる。

sarはどのような場合に使うのか

sarが最も役に立つのは、後日に行う負荷分析やボトルネック分析においてである。システムのスループットに問題があった場合に、その原因を探ったり、その時間帯にシステムがどのような状況にあったかを後日調査したりするのがsarの役割だ。

「-q オプション」でload averageを閲覧して、システムが重かった時間帯を割り出し、そのほかのオプションでボトルネックがどこにあるのかを見極める。

また、リアルタイムでの閲覧も可能なので、何か問題があったら即座にpsやtopである程度原因を絞り込み、sarでボトルネックと思われる項目の数字を確認できる。

まとめ

  • ディスクI/Oがボトルネックであれば「-u オプション」で%iowait項を確認
  • CPU処理能力は「-u オプション」で%userや%system、%idleを確認
  • スワップが発生しているようなら「-W オプション」、メモリ使用率の推移は「-r オプション」で確認

sarは過去のデータを表示できる

sarはcronによって起動され、定期的にOSのデータを収集している。sarとするとデフォルトではその過去のCPU利用率を表示する。

CentOSの場合、「/var/log/sa」に過去データが蓄積されており、データは「sa + 日付」というファイル名で保存される。「-fオプション」でファイルを指定して表示できる。

sar -f /var/log/sa/sa07

sarをリアルタイムに動かす

sarは現在の状況を調べる場合にも利用可能。 コマンドライン引数で、データの表示間隔と表示回数を指定して起動する。

sar 1 100

とすると、1秒おきに100回、CPU利用状況をリアルタイムで表示できる。

  • 当日のデータを見たい場合はオプションなし
  • 当日よりも過去のデータを見たい場合は「sar -f」
  • リアルタイムに監視したい場合は「sar 1 100」

CPU負荷を見る

sarはデフォルトでCPU負荷を表示する。 明示的に指定したい場合は「-u オプション」を使用する。

複数のCPUが搭載されている場合(マルチコアなど)は、CPU別に閲覧しなければ状況が分からないケースがある。そんなときは「-P オプション」を使う。

  • 「-P ALL」でCPUごとの状況
  • 「-P 数字」で任意のCPUの状況

「-P オプション」を付けなかった場合には、複数のCPU使用率の平均値になる点に注意。

メモリ利用状況を見る(-r)

「-r オプション」はメモリ使用状況を見ることができる。各項目はtopとほぼ同じ。

sarでメモリ使用状況が分かってうれしいのは、過去のデータが閲覧できるからだ。OSの立ち上がりからアプリケーションが安定するまで、OS全体のメモリ使用の内訳がどのように推移していくのかを後日でも確認できるし、スワップが大量に発生してシステムパフォーマンスが低下した場合も、どの程度のメモリが使われていたかなどを把握できる。

load averageとランキューに溜まったプロセスの数

「-q オプション」ではload averageの推移に加えて、以下の2種類のプロセス数を表示できる。

-runq-sz
ランキュー(CPU時間割り当てを待っているプロセスが並んでいるキュー。カーネル内データ構造)に溜まっているプロセス数
-plist-sz
稼動しているプロセスの総数

load averageはシステム全体のパフォーマンスの目安になる数字である。あくまである程度の目安を確認するもの。 しかし、昨晩のパフォーマンスはどうdったか、という場合にsarの「-q オプション」を使えば、その推移をはっきりと見て取れる。

スワップ発生状況(-W)

スワップが発生すると、ディスクI/Oが発生し、システム全体のスループットは急激に低下する。 スワップを発生させないよう適切にリソースを管理するのは負荷分散の基本である。

「-W オプション」では、スワップが単位時間にどの程度発生したかを表示することが可能。すべて0.00であればスワップ(ページスワップイン/ページスワップアウト)は発生していない。

vmstat

スワップが発生しているかどうかは、「vmstat コマンド」でも確認できる。

「si(swap in)」と「so(swap out)」の項目がある。 この項が0以上の値で頻繁に更新されるようであれば、スワップが発生してシステム全体のスループットに影響を与えていると思って間違いない。

逆引き

調査の入り口として状況を把握する - top

top

プロセスの極端な増加がないか確認する - ps

LinuxThreads(古いプロセス)

ps auxw | grep <プロセス名> | grep -v grep | wc -l

NPTL(新しいプロセス)

ps auxw -L | grep mysql | grep -v grep | wc -l

どのプロセスがリソース消費の主な原因になっているかを調査する - ps

psの「VSZ」や「RSS」を見る。

CPU時間を消費しすぎているプロセスを見つける - ps

psの「TIME」の値または増加ペース、「STAT」がRかを確認。

メモリを使用しているプロセスを見つける - ps

psの「VSZ」や「RSS」を確認。

メモリ使用量順にソート

ps auxw -L --sort=-vsz

ディスクI/Oがボトルネックか調べる - sar

sarの「-u オプション」で%iowait項を確認。

CPU処理能力がボトルネックか調べる - sar

sarの「-u オプション」で%userや%system、%idleを確認。

スワップが発生しているか調べる - sar/vmstat

sarの「-W オプション」。

vmstatの「si(swap in)」と「so(swap out)」。

メモリ使用率を調べる - sar

sarの「-r オプション」で確認

その他参考サイト

Linux のメモリー管理(メモリ−が足りない?,メモリーリークの検出/防止) http://www.math.kobe-u.ac.jp/~kodama/tips-free-memory.html#memory_swap

以下、一行コメント

Name: Comment:

トラックバック

TrackBack URL: (trackback is currently disabled because of numerous SPAMs)
Last modified:2008/07/14 13:50:04
Keyword(s):[Linux] [ボトルネック]
References: