4月に(2019.04.16) RDS のメトリックスについて拡張がアナウンスされましたが、私がメトリックスをどのような観点で見ているかについて思いつくままに書き出してみました。参考になれば幸いです。
なお、ここに書き出している見解は個人のものであり所属している組織とは異なります。
主に MySQL データベースを念頭に書き出していきますが、ディスク IO 等は他のデータベースにもおおむね妥当すると思います。
項目は RDS のマニュアル を参考にしています。
それではメトリックスのグループ毎に見ていきたいと思います。
General
ここで性能の観点から注目したいメトリックスは、numVCPUs です。cpuUtilization や loadAverageMinute などのグループを検討するときに参考にする。
cpuUtilization
各メトリックスは一定間隔、公表はされていませんがおそらく 1/100 秒間隔で、CPU の処理内容を確認し、カウントしているものだと見受けられる。
guest
仮想化ハイパーバイザで確認時にゲストOSが稼働していた時間。多分 RDS ではずっと 0 。軽くスルーする。
irq
確認時に割り込み処理が動いていた回数の割合。おもにネットワーク接続数が増えているときやディスクIOが多いときに増加する傾向がある。
system
確認時にシステムコール等カーネル処理が動いていた回数の割合。どのような処理が多いのかは別途分析が必要だが、RDS では難しいと思う。
wait
歴史的な理由から IO ウエィトと呼ばれていますが、実際に待っているわけではないので CPU 性能の観点からは無視します。確認時に実行中の IO があるとカウントされます。別途ディスク IO や、クエリの内容を確認する。
idle
確認時に idle プロセスが動作している場合にカウントします。オンプレならば多いに越したことは無いですが、クラウドだとお金がもったいないのであまりに多い場合はインスタンスサイズを再検討する必要があります。
user
ユーザプロセスが動作していた場合にカウントされます。DBMS 側の処理が多い場合に増加します。パフォーマンスインサイトなどで、クエリの実行状況の詳細を別途確認する必要があります。
total
個別の稼働状況に注意している場合は特に気にしなくてもいいと思う。
steal
ハイパーバイザや同一ハイパーバイザ上の他のゲストによって利用されていた回数です。あまりに多い場合はインスタンスの移動を検討する。
nice
優先制御されたプロセスが実行されていた回数です。RDS では特に何かできるわけではないですが、ユーザーと比較してあまりにも多くかつ通常優先度のプロセスに処理遅延が発生している場合は、優先度の見直しが必要になるかもしれません。
その他
個別 CPU のメトリックスが現在取得できていないため、100 % 以下であっても特定 vCPU を特定スレッド/プロセスを占有していて、そのスレッドに対応するクエリが遅延する可能性があります。
CPU 使用率が 100 % であっても必ずしもより大きいインスタンスに変更することが有効とは限りません。クエリの分割や、テーブルのパーティショニングがより費用対効果が大きい場合があります。あわせて、パフォーマンスインサイト や 後述の tasks の状況を確認する必要があります。 また system の割合が大きい場合は、メモリの使用状況やディスク IO の状況を確認する必要があります。
loadAverageMinute
cpuUtilization や tasks 等他の指標で代替できるので特に気にしない。
なおロードアベレージについては以下のブログエントリが大変参考になりかつ、面白いのでお時間のある時にご一読を。
Linux Load Averages: Solving the Mystery / Brendan Gregg's Blog
memory
実はこの指標も当てにしていない。 特に DBMS ではテーブルキャッシュやクエリキャッシュの状態が性能に大きな影響を与えると考えているけれど、OS 側からはこれらの状況を把握することはできない。
なので、基本的に使用率 100 % になっていても無視する。
writeback
メモリから書き出した量。あまり急に増えると瞬間的にクエリが遅延する可能性がある。
hugePagesSurp,hugePagesRsvd,hugePagesFree,hugePagesSize
ヒュージページは使っていないはずなので無視する。
cached
レガシーな指標でかつ内容が包括的すぎるので無視する。
free
利用されていないメモリの量。通常少ないと遅延すると思われているがクエリのワークロードによっては、DBMS 側でキャッシュやリザーブされているメモリが利用されるので、OS が把握している空きメモリが少ないからといって必ずしも遅延するとは限らない。
むしろ空きが多い場合はインスタンスサイズの見直しが必要となる。
inactive,active
OS のメモリ管理的には意味があるのだけれどユーザサイドからはあまり意味がないと思っているので、無視しても大丈夫だと思う。
pageTables
64 bit のシステムならばそれほど気にする必要はないと思う。メモリ割り当て管理情報が格納されている領域。
dirty
メモリの領域の内、ディスクに書き戻す必要があるメモリの量。この指標が長期にわたって継続的に増加する場合は、ストレージシステムの見直しが必要になる可能性がある。
mapped
参考になる場合はもあるが得に気にしていない。mmap されている量。
total
仮想マシンへのメモリ割り当て量
slab
カーネルが管理している一時メモリ領域の量。詳細は slabtop 等のコマンドで確認しないと意味がないが RDS ではムリなので、無視する。
buffers
レガシーな指標でかつ包括的で具体性に欠けるので無視する。
tasks
多分私が遅いといわれたときに真っ先に確認する項目がここ。要するに遅いということはプロセスが何らかの待ち状態になっているはずなので、プロセスの状態を確認すると大体の状況が分かる。
sleeping
特に何もしていないプロセスの数。多い場合はメモリが無駄なので、DBMS 側で待機スレッド数を減らすこと検討する。そのうえで他のメトリックスを確認してインスタンスサイズの変更を検討する。
zombie,stopped
多分現在ではほとんど表示されないと思受けれど、定常的に増加する場合はバグの可能性が高いのでバージョンアップをを検討する。
running
実行可能状態のプロセスの数。もしこの値が vCPU の値を上回っていてかつ、クエリに遅延が発生している場合は、より多くの vCPU を搭載したインスタンスへのスケールアップを検討する。またクエリの分割や、インデックスの再編成なども有効
total
現在実行中のプロセスの合計
blocked
IO 待ちのプロセス数。この数が相対的に多く、クエリに遅延が発生している場合は、クエリの分割、メモリ搭載量の多いインスタンスへの変更、PIOPSやストレージ量・タイプの見直しを行う。
swap
出たら負けなので、メモリ搭載量の多いインスタンスへの変更が基本となる。
以下の状態が見受けられる場合は特に注意が必要。
- free が継続的に減少する。
- in,out が継続的に観測される。
network
これだけではわかりにくいので、他のメトリックスを参照したほうがいいと思う。 rx,tx は通信量だがあくまでも参考程度とする。セッション数やパケット数が分からないと単に rx,tx が飽和していないという理由だけでネットワークがクエリ遅延の原因ではないと言い切れない。
diskIO,physicalDeviceIO
集計区分が異なるだけで、内容は同じ。ストレージシステムが遅延の原因かどうかは、physicalDeviceIO を用いて、IO 発生の要因を切り分けるためには diskIO を用いる。
writeKbPS,readKbPS
いわゆる転送速度。ただこの値が高いからといって、必ずしも遅延するわけではなくまた低いからといって、遅延しないわけでもないので注意が必要。参考程度に見るのがよいと思う。
もし不足していると判断できる場合は、インスタンスサイズの変更や GP2 タイプのディスクを利用している場合はディスクサイズの増加、PIOPS の利用を検討する。
readIOsPS,writeIOsPS
いわゆる IOPS。おそらくディスクでは一番重要な指標。ディスクの性能では一番最初に飽和する。特に GP2 タイプの EBS では、バーストできる量に制限があるため、例えば DB のダンプを取得したり、大量の初期データを投入する場合には注意が必要。
await
平均待ち時間。ディスクに対して I/O コマンドを発行してから、I/O の完了通知を受け取る時間までの平均値。主にディスク性能の指標になる。
rrqmPS,wrqmPS
システム内部で発生した I/O リクエストはそのまま都度ディスク装置に送られる訳ではなく、I/O スケジューラによってある程度まとめて送られる。
readIOsPS,writeIOsPS とほぼ同じ指標だが、rrqmPS,wrqmPS は I/O 実施前にカウントされるのに対して、readIOsPS,writeIOsPS は I/O 完了後にカウントされるという違いがある。
util
CPU 時間に対して、I/O リクエストが実行中だった割合。数値が高い場合は、I/O 待ちのプロセスが多い可能性が高いが、必ずしも数値が高いからといって遅延しているわけではないので、参考程度
avgQueueLen
平均キュー長。ここでのキューは I/O リクエストのキュー。この値が高い状態が継続すると、処理遅延が発生していると判断する。より大きな IOPS が割り当てられるようにインスタンスサイズやディスクサイズ、PIOPS を割り当てるなどの処置が必要になる。
tps
rrqmPS,wrqmPS の合計。どっちが問題なのかわからないので、rrqmPS,wrqmPSのほうを見るようにする。ただ限界値かどうかを判断するにはこちらが見やすい。
avgReqSz
平均リクエストサイズ。この値が小さいとIOPS だけを消費して、全体としてのI/Oスループットが低下する。
device
デバイス名
writeKb、readKb
読み込み、書き込みしたバイト数。参考程度
fileSys
used
使用しているディスク容量。単位は KB
name
ファイルシステムの名前。通常の RDS 利用では多分表示されない。
usedFiles
ファイル数。たくさんテーブルを作ったりすると。足りなくなる可能性がある。
usedFilePercent
maxFiles に対する usedFiles の割合。
maxFiles
作成可能な最大ファイル数
mountPoint
マウントポイント
total
パーティションの容量
usedPercent
total に対する、used の割合
processList
主要なプロセスのリストと、統計値を得ることができる。
vss
仮想メモリサイズ。単位は KB。
name
プロセスの名前
tgid
スレッドグループID
parentID
親プロセスID
memoryUsedPc
搭載メモリ全体に対する、rss の割合
cpuUsedPc
該当プロセスがCPU 時間を消費した割合。100 % になっているからといって必ずしも CPU 不足とは限らないので注意が必要。またマルチプロセッサシステムでは、値が低いからといって、プロセス遅延が発生しないというわけでもないので、注意が必要。 個人的には貧乏性なので常に 100% がいいと思っている。
id
プロセスの識別子。
rss
物理メモリ使用量。 DBMS ではプロセスの内部的にメモリを管理しているので、100%近くなっていても必ずしも問題になるとは限らない。最近の流行ではできるだけメモリにキャッシュさせて、高速なレスポンスを返すことを期待する傾向なので、むしろ使用量が少なかったらそちらを問題にしたほうがいい。
vmlimit
仮想メモリの上限だと思われるがいずれにせよ、0 とか unlimited になっているので意味が不明
cloudwatchlogs の出力例
最後にcloudwatch logs の出力サンプルを載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
{ "engine": "MYSQL", "instanceID": "metrixcheck", "instanceResourceID": "db-XXXXXXXXXXXXXXXXXXXXXXXXXX", "timestamp": "2019-04-16T03:04:46Z", "version": 1, "uptime": "00:27:10", "numVCPUs": 2, "cpuUtilization": { "guest": 0, "irq": 0, "system": 0.3, "wait": 0.1, "idle": 99, "user": 0.6, "total": 1.1, "steal": 0, "nice": 0.1 }, "loadAverageMinute": { "one": 0, "five": 0, "fifteen": 0 }, "memory": { "writeback": 0, "hugePagesFree": 0, "hugePagesRsvd": 0, "hugePagesSurp": 0, "cached": 1019124, "hugePagesSize": 2048, "free": 13576744, "hugePagesTotal": 0, "inactive": 701532, "pageTables": 6904, "dirty": 336, "mapped": 54476, "active": 1695496, "total": 16134712, "slab": 53152, "buffers": 29140 }, "tasks": { "sleeping": 117, "zombie": 0, "running": 0, "stopped": 0, "total": 117, "blocked": 0 }, "swap": { "cached": 0, "total": 8191996, "free": 8191996, "in": 0, "out": 0 }, "network": [ { "interface": "eth0", "rx": 877.57, "tx": 4294.3 } ], "diskIO": [ { "writeKbPS": 0, "readIOsPS": 0, "await": 0, "readKbPS": 0, "rrqmPS": 0, "util": 0, "avgQueueLen": 0, "tps": 0, "readKb": 0, "device": "rdsdev", "writeKb": 0, "avgReqSz": 0, "wrqmPS": 0, "writeIOsPS": 0 }, { "writeKbPS": 33.53, "readIOsPS": 0, "await": 0.67, "readKbPS": 0, "rrqmPS": 0, "util": 0.12, "avgQueueLen": 0, "tps": 5.3, "readKb": 0, "device": "filesystem", "writeKb": 2012, "avgReqSz": 12.65, "wrqmPS": 0, "writeIOsPS": 5.3 } ], "physicalDeviceIO": [ { "writeKbPS": 0, "readIOsPS": 0, "await": 0, "readKbPS": 0, "rrqmPS": 0, "util": 0, "avgQueueLen": 0, "tps": 0, "readKb": 0, "device": "nvme1n1", "writeKb": 0, "avgReqSz": 0, "wrqmPS": 0, "writeIOsPS": 0 } ], "fileSys": [ { "used": 672668, "name": "", "usedFiles": 730, "usedFilePercent": 0.06, "maxFiles": 1310720, "mountPoint": "/rdsdbdata", "total": 20496340, "usedPercent": 3.28 }, { "used": 2089420, "name": "", "usedFiles": 74628, "usedFilePercent": 11.39, "maxFiles": 655360, "mountPoint": "/", "total": 10190104, "usedPercent": 20.5 } ], "processList": [ { "vss": 988528, "name": "OS processes", "tgid": 0, "parentID": 0, "memoryUsedPc": 0.27, "cpuUsedPc": 0.03, "id": 0, "rss": 43684, "vmlimit": 0 }, { "vss": 3572528, "name": "RDS processes", "tgid": 0, "parentID": 0, "memoryUsedPc": 1.7, "cpuUsedPc": 0.53, "id": 0, "rss": 275092, "vmlimit": 0 }, { "vss": 13072904, "name": "mysqld", "tgid": 4241, "parentID": 4237, "memoryUsedPc": 7.12, "cpuUsedPc": 0.05, "id": 4241, "rss": 1148300, "vmlimit": "unlimited" } ] } |