AWS MySQL on EC2でEBS SSD(gp2)のI/Oクレジットが空になった。

先日、僕が関わっているとあるECサイトのレスポンスが、長時間悪化する現象が発生しました。
その原因が「EBSでSSD(gp2)のI/Oクレジットが空になっていたから」だったというお話。

isdサーバーの情報

  • EC2 1台でAmazon Linux, Nginx, PHP, MySQLの構成。(RDSは使用していない。)
  • ルートボリュームはEBS。追加ボリュームなし。
  • EC-CUBEによるECサイト。

isd経過

  1. EBSに対して激しいReadアクセスがあり、SSD(gp2)のI/Oクレジットが空になった。
  2. ECサイトのレスポンスが悪化した。
  3. mysqldumpの定期実行が開始され、I/Oがかかり続け、長時間終了しなかった。
  4. サーバーを再起動して少したつと、Webレスポンスが通常時に戻った。

1. EBSに対して激しいReadアクセスがあり、SSD(gp2)のI/Oクレジットが空になった。

該当時間帯のEBSのI/O数とI/Oクレジットは以下。
(CloudWatchメトリクス EBS VolumeReadOps/VolumeWriteOps/BurstBalance)


 

14:00ごろから、ストレージの読み込み(VolumeReadOps)が増えるに従って、I/Oクレジット(BurstBalance)が減り、14:40ごろには0になったことがわかります。

※EBSのSSD(gp2)は、I/Oクレジットの蓄積と消費のしくみにより、I/O最大性能(3,000 IOPS)の継続時間が制限されています。以下のAWSブログ記事に詳しい説明があります。

・【AWS発表】新しいSSDベースのElastic Block Storage
http://aws.typepad.com/aws_japan/2014/06/new-ssd-backed-elastic-block-storage.html

2. ECサイトのレスポンスが悪化した。

ディスク性能が大きく劣化したことにより、ECサイトのレスポンスタイムは、通常時は1秒~2秒なのに、5秒から10秒となった。

3. mysqldumpの定期実行が開始され、I/Oがかかり続け、長時間終了しなかった。

SSD(gp2)のI/Oクレジットが0の状態のまま、DBデータバックアップのためにcronで定期的に実行しているmysqldumpが実行された。
EBSはボリューム50GBだったため、I/O性能はベースライン性能の150 IOPSのままで継続された。
このため、mysqldump処理の進行が遅く、長時間終了しなかった。
この間、ECサイトのレスポンスタイムはずっと遅いままだった。

※DBデータのサイズは合計3.6GB程度。

4. サーバーを再起動して少したつと、ECサイトのレスポンスが通常時に戻った。

サーバーは翌日早朝に、計画的に再起動された。
mysqldumpのプロセスがクリアされたことでI/Oがほとんどかからなくなった。
これにより、EBS SSD(gp2)のI/Oクレジットが溜まり、バースト性能が出るようになって、ECサイトのレスポンスタイムも通常時のレベルに戻った。

※サーバーの再起動は、EC-CUBEの何らかの処理でメモリリークが発生しているため、週次で実施している。

ECサイトのレスポンス悪化については、監視ツールのアラートで気づきました。
何が起こっているのか調査していて、ディスク性能がよくないところまではわかったものの、EBSのI/Oクレジットまでは思い至らず、それがわかったのは翌日になってからでした。

今思えば、とりあえずは、mysqldumpのプロセスをkillすればよかったのですね。

isd根本的な原因は不明

14:00から14:45ごろにかけて、EBSに対して激しいReadアクセスが発生したため、EBS SSD(gp2)のI/Oクレジットが空になってしまったのですが、その激しいReadアクセスの発生源は、わかっていません。

EC2のネットワークIn/Outや、sar -b, sar -d は、普段と大きな違いはありませんでした。

該当時間帯のEC2のネットワーク転送量(In/Out)は以下。
(CloudWatchメトリクス EC2 Network In/Out)


 

sarコマンドの結果は次のとおり。

 $ sar -b -f /var/log/sa/sa26

00時00分01秒       tps      rtps      wtps   bread/s   bwrtn/s
...
13時30分01秒      2.53      0.00      2.53      0.00     57.61
13時40分01秒      3.30      0.01      3.29      0.16     81.46
13時50分01秒      3.04      0.00      3.04      0.00     71.39
14時00分01秒      2.29      0.00      2.29      0.00     50.47
14時10分01秒      3.12      0.00      3.12      0.00     72.75
14時20分01秒      4.36      0.00      4.36      0.05    116.08
14時30分01秒      2.61      0.00      2.61      0.00     59.40
14時40分01秒      4.49      0.00      4.49      0.00    122.60
14時50分01秒      2.66      0.01      2.66      0.21     64.14
15時00分01秒      3.06      0.32      2.74      4.27     71.19
15時10分01秒      2.60      0.00      2.60      0.00     66.55
15時20分01秒      2.52      0.00      2.52      0.01     62.55
15時30分01秒      3.06      0.00      3.06      0.00     82.77
15時40分01秒     10.24      3.60      6.64    151.76   1041.63
15時50分01秒      5.91      2.26      3.64     72.38    117.70
16時00分01秒      5.66      2.27      3.40     72.50    102.02
16時10分01秒      5.14      2.27      2.87     72.72     81.14
16時20分01秒      5.52      2.34      3.18     76.63     92.67
16時30分01秒      4.93      2.28      2.65     72.77     69.06

 

 $ sar -q -f /var/log/sa/sa26

00時00分01秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util

13時30分01秒  dev202-0      2.53      0.00     57.61     22.73      0.00      0.87      0.63      0.16
13時40分01秒  dev202-0      3.30      0.16     81.46     24.76      0.00      1.21      0.57      0.19
13時50分01秒  dev202-0      3.04      0.00     71.39     23.47      0.00      0.79      0.52      0.16
14時00分01秒  dev202-0      2.29      0.00     50.47     22.06      0.00      0.85      0.59      0.14
14時10分01秒  dev202-0      3.12      0.00     72.75     23.32      0.00      1.00      0.63      0.20
14時20分01秒  dev202-0      4.36      0.05    116.08     26.61      0.01      1.27      0.68      0.30
14時30分01秒  dev202-0      2.61      0.00     59.40     22.76      0.00      0.89      0.60      0.16
14時40分01秒  dev202-0      4.49      0.00    122.60     27.31      0.01      1.34      0.64      0.29
14時50分01秒  dev202-0      2.66      0.21     64.14     24.15      0.46    173.63     97.19     25.90
15時00分01秒  dev202-0      3.06      4.27     71.19     24.65      1.32    430.05    209.04     63.99

15時00分01秒       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
15時10分01秒  dev202-0      2.60      0.00     66.55     25.58      1.09    420.35    228.40     59.42
15時20分01秒  dev202-0      2.52      0.01     62.55     24.83      1.07    422.86    237.09     59.75
15時30分01秒  dev202-0      3.06      0.00     82.77     27.06      1.29    422.62    239.92     73.38
15時40分01秒  dev202-0     10.24    151.76   1041.63    116.55     10.22    997.61     97.59     99.92
15時50分01秒  dev202-0      5.91     72.38    117.70     32.19      2.67    452.37    169.39    100.04
16時00分01秒  dev202-0      5.66     72.50    102.02     30.81      2.47    436.55    176.62    100.06
16時10分01秒  dev202-0      5.14     72.72     81.14     29.92      2.23    432.91    194.56    100.05
16時20分01秒  dev202-0      5.52     76.63     92.67     30.66      2.45    444.67    181.22    100.06
16時30分01秒  dev202-0      4.93     72.77     69.06     28.79      2.11    428.94    203.06    100.03

 

※15時40分の値が大きいのは、mysqldumpによるものです。

これらの情報を信用すれば、OS上のプロセスや、EC2 VMからEBSへの、I/Oクレジットを使い果たすほどの激しいReadアクセスはなかったはずです。

EC2以外からのEBSへのI/Oアクセスは存在するのでしょうか?
(存在するのであれば、どなたか教えてほしい。。)

なお、この時間帯は、スナップショット作成やAMI作成は行っていません。

isdMySQL on EC2とRDS for MySQL

このサーバーは、お客様のご要望により、RDSを使用せずにEC2上でWebアプリケーションとともにMySQLサーバーを稼働させていました。
しかし、DBデータバックアップのためのmysqldumpは大量のI/Oアクセスを行うため、今回のサーバーのベースライン性能である「150 IOPS」では、3.6GBのデータのバックアップも到底処理し切れないことがわかりました。

EC2上でMySQLサーバーを稼働させる「MySQL on EC2」のケースでは、mysqldumpによるバックアップは、I/O性能に注意して運用したほうがよさそうです。

対策としては、

  • ディスクサイズを大きめにして、ベースライン性能を上げる。
  • mysqldumpは使用せずに、EBSのスナップショットをDBデータバックアップとする。

といったことが考えられます。
特に後者については、EBSのスナップショットは差分で取得しますから、バックアップの頻度を増やしても、それほどコスト増はないはずです。

また、特別な理由がない限り、MySQL(等のDBサーバー)はできるだけRDS for MySQLを使ったほうがよいと思います。
(今回は、お客様を説得できなかった自分の力不足を感じました。。。)

RDSでのバックアップ機能である「スナップショット」は、DBインスタンスのストレージボリュームのスナップショットですので、mysqldumpと違って、RDSのI/Oを消費しないはずです。

(参考)
・Amazon Relational Database Serviceユーザーガイド, DBスナップショットの作成
http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_CreateSnapshot.html

DBサーバーの管理の手間が減るほか、リカバリーについても、「Point in time recovery」で、任意の時点のデータを取り出せて便利です。

isdまとめ

  • アクセス数が増えたわけではないのに、Webサイトやシステムのレスポンスが悪化したときは、EBS SSD(gp2)のI/Oクレジットが空になった可能性もある。
  • mysqldumpは、EBS SSD(gp2)バースト性能が出ないと処理しきれない可能性がある。
  • 特別な理由がない限り、MySQLサーバーはEC2に載せずに、RDS for MySQLを使おう。