ElastiCache MemcachedのCPU使用率が急上昇し、DatabaseConnectionエラーが発生した時に対応したこと

システムAWS, EC2, Memcached, php-fpm, RDS

どうもUT(@ut_1029)です。
久々のシステム関係のブログになります。

ElastiCache MemcachedのCPU使用率が急上昇し、DatabaseConnectionエラーが発生した時に対応したこと
ElastiCache MemcachedのCPU使用率が急上昇し、DatabaseConnectionエラーが発生した時に対応したこと

とある企業のシステム監視をしていたところ

  • ElastiCache MemcachedのCPU使用率が急上昇
  • Database Connectionの急上昇
  • PHP-fpmがseems busyのWARNINGが発生
  • Database Connectionに失敗

などにより、急激に負荷高まりシステムが激重になる事象が発生しました。
その時に調べたことや対応したことを残します。

今のところ事象は改善されたので、同じ事象で困っている人は参考にしてみてください。
※対応したこと全部載せているので、原因だったボトルネックが改善された対応がどれかは不明です。

環境/構成

まずは、環境構成についてです。
AWSで環境を構築されており、詳細な構成は以下の様になります。

  • Webサーバ(Web Servers)
    • AWSEC2を利用
  • Webシステム(Web System)
    • Nginxを利用
    • php-fpm5系CakePHP2系を利用
  • データベース(Database)
    • AWSRDSAuroraを利用
  • キャッシュ(Cache)
    • AWSElastiCacheMemcachedを利用
    • Nodeは3つ

事象について

RDSのDatabaseConnectionが急上昇

AWSCloudWatchでグラフを確認すると、
DatabaseConnectionが急上昇
していた。

それで事象に気づいていろいろと調査すると色々とエラーが起こっていた。

ElastiCacheのMemcachedのCPUが急上昇

ElastiCacheMemcachedのグラフを確認すると
CPU使用率が急上昇
していた。

CakePHP2のエラーログでCache書き込みエラーやDatabaseConnectionエラー

CakePHP2のエラーログを確認すると
Cacheへの書き込みに失敗
していた。

****-**-** **:**:**.*** Warning: (PID=****) (UUID=*********) (()) Warning (***): _cake_core_ cache was unable to write '******' to Memcached cache in […./lib/Cake/Cache/Cache.php, line 328]

他にも
DatabaseConnectionに失敗
が起こっていた。

****-**-** **:**:**.*** Error: (PID=****) (UUID=*********) ) (…./lib/Cake/Error/ErrorHandler.php(118)) [MissingConnectionException] Database connection "Mysql" is missing, or could not be created.

PHP-fpmのエラーログでWARNING

PHP-fpmのエラーログを確認すると
忙しい(seems busy)状態
になり
Process数が足りていない
WARNING発生。

[**-***-**** **:**:**] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning * children, there are * idle, and * total children

事象の原因調査

まず時系列でどのサーバどの時間何が発生しているのかを整理しました。

そうすると、
ElastiCacheのCPUが急上昇

RDSDatabaseConnectionが急上昇

PHP-fpmseems busyのWARNING発生
という具合になっているようでした。

対応内容

CakePHP2のエラーログにあるDatabaseConnectionエラー

AWSEC2のインスタンスを複製して、インスタンスを新しく構築しました。

そうすると、
CakePHP2のエラーログに出力される

****-**-** **:**:**.*** Error: (PID=****) (UUID=*********) ) (…./lib/Cake/Error/ErrorHandler.php(118)) [MissingConnectionException] Database connection "Mysql" is missing, or could not be created.

は、解消されました。

ただ、
長い間再起動していない状態だったのがダメだったのか、再起動していないのでカーネルのアップデート(kernel update)されていなかったことが原因だったのかもです。

なので、
こちらの事象に悩まされている方は、サーバ再起動することをおススメします。

ElastiCacheのMemcachedのCPU使用率が急上昇

これには2つ対応を行いました。

ElastiCache Cluster Client for PHP

AWSElastiCacheでnodeのエンドポイントを指定して接続を行っていたので、クラスター(Cluster)のエンドポイントを指定するよう変更しました。

それに伴い
AWSで用意されている「ElastiCache Cluster Client」を使うようにしました。

使用する理由としては、
ElastiCache Cluster Clientを使用することで、クラスターのエンドポイントを指定すると自動でぶら下がっているnodeを検出して接続するようです。

ElastiCache Cluster Clientをインストール

# ElastiCache Cluster ClientをPECLを使ってインストール
$ sudo pecl install /home/ec2-user/AmazonElastiCacheClusterClient-1.0.0-PHP56-64bit.tgz
install ok: channel://__uri/AmazonElastiCacheClusterClient-1.0.0
configuration option "php_ini" is not set to php.ini location
You should add "extension=amazon-elasticache-cluster-client.so" to php.ini
# PHPの拡張モジュール(Extention)の配置場所を確認
$ php -i | grep extension
extension_dir => /usr/lib64/php/5.6/modules => /usr/lib64/php/5.6/modules
# ちゃんとインストールされたか確認
$ ls -la /usr/lib64/php/5.6/modules | grep amazon
-rw-r–r– 1 root root 1213746 May 8 17:44 amazon-elasticache-cluster-client.so
# インストールしたElastiCache Cluster Clientの拡張モジュールを読み込むようにする
# 既存のmemcached.soは、コメントアウトしておく
$ sudo vi /etc/php.d/50-memcached.ini
; extension=memcached.so
extension=amazon-elasticache-cluster-client.so
# php-fpmを再起動
$ sudo /etc/rc.d/init.d/php-fpm restart

CakePHP2のエラーログにあるCache書き込みエラー

ElastiCacheMemcachedのバージョンを最新版へアップデートしました。

そして
パラメータグループのmaxconns_fastを1に設定。

maxconns_fast
最大接続制限に達したときに新しい接続リクエストを処理する方法を変更します。
このパラメータを 0(ゼロ)に設定した場合、新しい接続がバックログキューに追加され、他の接続が終了するまで待機します。
パラメータを 1 に設定した場合、ElastiCache はクライアントにエラーを送信し、すぐに接続を終了します。

https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/mem-ug/ParameterGroups.Memcached.html

そうすると、

****-**-** **:**:**.*** Warning: (PID=****) (UUID=*********) (()) Warning (***): _cake_core_ cache was unable to write '******' to Memcached cache in […./lib/Cake/Cache/Cache.php, line 328]

は、解消されました。

PHP-fpmの忙しい(seems busy)状態でProcess数が足りない

上記の対応を行ったことで、
PHP-fpmの忙しい(seems busy)状態は解消され、Process数が足りないエラーログの

[**-***-**** **:**:**] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning * children, there are * idle, and * total children

は、出力されなくなりました。

PHP-fpmの設定見直し

ちなみに
PHP-fpmのpm(Process)関係の設定についていくつか調べていたので、補足程度に乗せておきます。

/etc/php-fpm.d/www.confのプロセス設定

  • pm
    • プロセスマネージャが子プロセスの数を制御する方法
      • static
      • 子プロセスの数は固定される
      • ondemand
      • プロセスを必要に応じて立ち上げる
      • dynamic
      • 関連する設定値の内容によって、立ち上がる子プロセスの数が動的に決まる
  • pm.max_children
    • 同時に処理をする可能性がある子プロセス数
  • pm.start_servers
    • プロセス開始時に生成される子プロセス
    • デフォルト値: min_spare_servers + (max_spare_servers – min_spare_servers) / 2
  • pm.min_spare_servers
    • 待ち状態の子プロセスの最小の数
    • もし待ち状態のプロセスの数がここに設定されている数値より少ない場合、何個かの子プロセスが作成される
  • pm.max_spare_servers
    • 待ち状態の子プロセスの最大の数
    • もし待ち状態のプロセスの数がここに設定されている数値より多い場合、何個かの子プロセスが消される。
    • pm.start_servers + pm.min_spare_servers
  • pm.process_idle_timeout
    • アイドルプロセスが殺されるまでの秒数
    • pmがオンデマンドに設定されている場合にのみ使用されます
  • pm.max_requests
    • 各子プロセスが、再起動するまでに実行するリクエスト数
    • プロセスのメモリが肥大化するときの回避策として使える
    • プロセス再生成に関わるCPU利用率があがります

/etc/php-fpm.d/www.confの設定で参考にしたサイト

おわりに

サーバが障害でトラブって調査するのって疲れますよね(汗)
実は、解消するまでに1週間近く掛かってしまいました。。。

結局分からなかったことが、
ElastiCache Cluster Clientを利用した後でも、ElastiCacheのnodeが3つあるうちの1つのnodeでCPU使用率が急上昇する事象は解消されなかった。

ただ、
ElastiCacheMemcachedのバージョンを上げることで解消はされたっぽい。
これは最後までなぞのままでした。。。

この記事の内容でおかしな点があればご指摘をお願いしますm(_ _)m

余談

過去のシステム系の記事ですが、
WordPressのテーマを変更したことによってスタイルとかが変わってめちゃ見にくくなっちゃってる。。。

書き換えなくては。。。orz

システムAWS, EC2, Memcached, php-fpm, RDS