hirano

2013.10.15

MySQLの参照ロードバランスで最近困った2つのこと

こんにちは、インフラの担当をしております平野です。

当社では意味の分からないカードゲームが流行っているようですが、
私は「ダム」に行くともらえる「ダムカード」集めにはまっております。
大きなダムを上から覗いたときに感じる怖さからのお尻のむずむず感がたまりません。

先日、新しいサービス・アーキテクチャのインフラ構築をする際にしくじったことがあったので
記事にしたいと思いました。


1) ipvs環境化でのコネクションプーリングでMySQLがmax_connectionsに到達問題

MySQLレプリケーション機能を利用し、参照のみを利用するクエリ向けにスレーブ機を複数台並べ、
ロードバランスさせる構成を取っていました。
ロードバランサはipvs(lvs)、アプリはコネクションプール機能の利用を前提としていました。

ある程度稼働させたところ、

・負荷が大してかかってない
・サーバ上のMySQLのコネクション数がnetstatでみると異常に残っている
・lvs的にもアクティブコネクション(ActiveConn)、待機コネクション(InActConn)がほとんど存在しない
・かつ他アプリプロセスからMySQLへの接続に不安定な状態(接続できたりできなかったり)

という事象に出くわしました。

うーむ、とlvsとmysqlの接続周りで何かの閾値を踏んでいるのかなと予想をたててたところ、
こちら(http://d.hatena.ne.jp/hirose31/20110607/1307419229)のサイトを拝見しました。

■ ipvs の timeout 設定の確認

■ MySQL の timeout 設定の確認

上記の通り、MySQL側のタイムアウトが28,880秒(8時間)に対してipvs側は900秒(15分)において、
アプリからの永続化接続(コネクションプーリング)状態での無通信になると、
LVSでのTCPタイムアウトしてしまうが、MySQL側のタイムアウトにならず…ですね。

今回はMySQLのタイムアウト値をLVSのタイムアウト値より少なくしました。
#この問題はもう7〜8年前からよく言われている事のようですね。
 最近DB接続を永続化するアプリとの出会いが少なかったので私は初めて遭遇しました…

2) Amazon EC2 / Elastic Loadbalancer 配下でのMySQL ロードバランス

Internal ELB 利用して、1)と同様にMySQLをレプリしているEC2インスタンスに対して
ロードバランスをさせたところ、ある程度稼働した段階で以下のアラートがでてしまって
MySQL接続ができなくなってしまいました。

DoSなどの攻撃に対して自衛する機能が生きたようです。
「mysqladmin flush-hosts」すれば一時的には解決しますが、定期的な疎通をする何かが
原因であることがわかったので調べたところ、ELBの Health Check設定において
MySQL(3306)に対して直接pingを打ち続けるとこのアラートとなることでわかりました。

Health Check は HTTP/TCP/HTTPS/SSL のみ選択でき、他のチェック機能を差し込むことはできません。
そのため mysqladmin ping の結果によってHTTPレスポンスコードを返却するPHPを一枚作成し、
このPHPファイルをindexに設定したhttpdポートをELBの Health Check 対象に設定して事なきを得ました。

割と個人的には枯れた技術範囲であったMySQLの構築で小はまりしたことが新鮮であったとともに、
基礎的なことほどトラブルシュート時は立ち戻ることを再確認した事象でした。