memcached 奮闘記
はじめに
そこそこな規模のゲームを運営しているサーバーエンジニアです。
サーバーはLAMP環境で、I社のクラウドサーバーを利用しています。
キャッシュ機構はmemcachedとPHPのapcuを併用しており、その中で苦労した問題が起こったので自分の備忘録的に。
事の発端
apcuキャッシュにDBデータと、yamlデータを大量にキャッシュしている機構で、データ変更の際は、キャッシュ全クリアの為にhttp reloadをしていました。
ただ、運営期間も長くなり、データが肥大化され、http reloadをすると
大量のキャッシュ生成の影響によりスパイクが発生し、マシンが耐えきれずCPUが100%に・・・。
10分ぐらい経つと復旧する場合もありますが、その間はロード時間が長くなったり、通信障害起こってしまうので
もうオンメンテでデータ更新できないじゃん!?となり何とか解決しようと走り出しました。
解決案
色々な解決案をエンジニア内で協議し、結局「apcuをやめて、memcachedに移管する」
ってな事になりました。
(redisを使ってもよかったのですが、既にmemcachedを利用しており既存ロジックの流用で移管するのもスムーズなので)
apcuキャッシュしている箇所のほとんどをmemcachedに載せ替えるように内部ロジックを書き換え
いざ本番反映!
しかし問題が・・・
本番反映後
本番反映し問題なくキャッシュが溜まっている事は確認しつつ、支障もなさそうに見えましたが・・・
反映後30分後から画面のロードにかなり時間がかかるようになってしまい、お問い合わせも急増することに。
原因究明へあれこれ
監視ツールで見ても特にアラートも出ておらず、一番怪しかったDB周りも特にスロークエリも出ていない。。。
CPU、メモリも正常で、DBの遅延も検知していない。
となると、memcached側の設定でチューニング出来ていない?
チューニングはリリース初期にしていたはずだが・・・
改めてコネクション数のあたりを見直してみました
net.core.somaxconn = 65535
MAXCONN="262144"
うーーーん、、、十分に設定されてるし、実際の測定値を比べても捌けているはず。
じゃ、ポートレンジの範囲が足りていない??
net.ipv4.ip_local_port_range = 32768 60999
ここもしっかり範囲あるし、別途行ったテストでも問題はなさそう・・・。
他にもmemcachedの設定だけでなく、linuxのカーネルパラメータも色々見直して試しましたが、
一向に改善せず・・・。
結局原因は
結論からいうと、単純な話でクラウドマシンの1台あたりの転送量の上限に引っかかってました。
(そんなん初めから気づけよ!ってな話ですが、言い訳すると、一番最初にここが怪しいとクラウドサービスに確認を投げていましたが、その時は上限に言ってないって誤回答されてて・・・)
調査に1週間ぐらい時間かけてちゃったのでなんじゃそりゃという結論でしたが、何かしら上限に行ってたら通知する仕組みがほしかったですね。
解決策
つまり、apcuキャッシュをやめてmemcachedに変更したことで、memcachedサーバーへの転送量が極端に増えたということなので、単純にmemcachedサーバーの台数を増やして解決。
これからは、ちゃんとクラウドサービス側の設定や上限も視野に入れて対応していかないといけない・・・。