mixi大規模障害について その2
こんにちは。システム本部技術部たんぽぽGの森本です
補足を追記しました (2010/08/20 15時)
先日のmixi大規模障害についての続報です 今回は小ネタはありませんはじめに
まず初めにtwitter/blogなどを通じて今回の問題の解析を行っていただいたみなさんに感謝の言葉を捧げたいと思います- kzk_moverさん
- stanakaさん
- mala(bulkneets)さん
- llameradaさん
memcachedはすごい
今回の件でmemcachedに対して不安感を持たれた方もおられるとお聞きしました 説明不足だったせいで誤解を与えてしまい申し訳ありません きちんと設定および監視を行っていれば通常の使用にはまったく問題はありません 弊社にて -c 30万で起動したmemcachedに対して、先のテストスクリプトにて28万接続を頻繁にくりかえす負荷テストを行いました 19:00から翌朝の10:00まで何の問題もなく1行のエラーも吐くこともなく17時間動作したことを確認しました詳細
今回のmemcached不具合の内容をまとめましたmain thread
- accept()で新しいクライアント接続を受け取るが失敗する
- errno は EMFILE なので "Too many open connections" と判断する
- 新しい接続要求を受け付けなくするためにaccept_new_conns(false); を呼び出し、listen()のbacklog数を0にする
- update_event(next, 0)経由でevent_set()監視対象イベントも0にする
worker thread
- クライアントが接続を切断したので conn_close() を呼び出して後始末を行う
- 1本接続が減ったので新しい接続を受け付けられるはずなのでaccept_new_conns(true) を呼び出す
- update_event(next, EV_READ | EV_PERSIST)経由で、main threadにaccept用socketのイベント監視を再開させる
再発防止策
memcached を -c 30万で設定しました 実際の接続数を監視してしきい値を超えるとアラートメールが飛ぶように設定しました 長期的にはアーキテクチャの変更が必要なので下記の項目について検討中です- サービス単位での個別のmemcachedを使用
- memcached proxyの使用
- UDPの使用
- 不揮発なキャッシュシステム
まとめ
私見ですが、memcachedを運用する場合には -c による接続数の制限はできるだけ大きくするのが望ましいと思います 大事なのはmemcachedがきちんとサービスを提供できていることなので、CPU/Load/Memory/cache hit/response timeなどをきちんと監視していれば実際の接続数がいくらなのかは問題ではないかと思います ちなみに現在 mixi では -c 30万で運用中です -c を大きく設定するにはいくつかのカーネルパラメータの変更が必要です 詳しくはググってください また、実際の接続数が大きくなるとネットワークバッファなどのリソースに影響がでますので、適宜監視が必要です補足
「-c 30万は対症療法」「patchは書かないのか」とのご意見をいただきましたので若干の補足です
-c 30万
今回のmemcachedの不具合は単なる高負荷状態では発生せず、接続限界数に達したときのみ発生します -c で設定した接続数に達して新しい接続が受けられなくなった時点でキャッシュしている値に不整合がでる可能性があるので、memcachedが落ちなくなったとしても、mixiというサービスとしては問題となります 以下のような場合にキャッシュ値に不整合がでます- ユーザーがmixiにアクセス
- httpd Aがニックネーム(たろう)をMySQLから取得
- httpd Aがmemcachedに保存
- ユーザーがニックネーム(たろう => 太郎)を変更
- httpd Bが新しいニックネーム(太郎)をMySQLに保存
- httpd Bがmemcached上のニックネームを削除または更新
- 接続限界数に達しているため処理が失敗する 不整合発生
- ユーザーがmixiにアクセス
- httpd Aがニックネーム(たろう)をmemcachedから取得 ※MySQL上のニックネームは太郎です
この様に一部のサーバーだけがmemcachedにつながった状態だとキャッシュしている値に不整合がでます
特に接続限界数に達するのが一時的なものであり、その後は正常に接続が行われる場合にはアラートにひっかかりにくく発見するのが困難になります
memcachedが完全に落ちた場合は自動的に再起動が行われるので一時的にMySQLの負荷が上昇するだけですみます
上記のようなことから、そもそも「接続数限界に達すること」自体が(memcachedのではなくmixiサービスを提供する上での)問題だと判断し、「-c 30万」および「十分に余裕を持たせた接続数の監視」をもって解決策としました