運用タイトル『JOKER』 負荷対策のあれこれ

こんにちは。サーバエンジニアのZです。

今回は、弊社「ジョーカー~ギャングロード~」(以下、ジョーカー)で行った「負荷対策」のお話を実際行った手順を元にご紹介していきたいと思います。

サービス運営していくうえで避けては通れない道なので、少しでも参考になれば幸いです。

きっかけ

2015年5月某日、ジョーカープロデューサーのBさんに個室に呼び出され「今年の夏か秋ぐらいにTVCMををやりたい」という相談を受けました。

その時の自分は…
majissuka
というのが率直な印象でした。

ただ、一気にユーザが増えた場合、各イベントで負荷が問題になってくるし、今の構成だと不安だし・・・直すのに時間足りるのか・・・と漠然と思ってしまいました。しかし、ユーザ数を一気に増やすチャンスなので負荷対策をすることになりました。

まず始めに、現状のサーバで負荷がどれくらい耐えられるのか?TVCMによってどれくらいユーザが増え、どれくらい負荷が増加するのか?を検討しました。

その結果、現状の構成だと1.5倍程度の負荷には耐えられる事がわかりました。しかしTVCMでのユーザ増加は2倍以上を見込んでいたので、さらなる負荷対策が必須という事が明確になりました。

 

負荷対策でやること

loadtest01
ざっとこんな感じです。

今回は「ボトルネック調査」「ボトルネック修正」で行ったクエリ見直しとデータ分散をご紹介していきたいと思います。

「ボトルネック調査」として Kibana を使用したスロークエリの確認。また New Relic や Jet Profiler を使用し参照や更新の多いテーブルの調査を行いました。

 

クエリの見直し

当然なのですが、クエリチューニングをすることによりパフォーマンスは向上します。
そのためまず先ほど紹介した Kibana を元にネックになっているクエリをチューニングしていきます。

スロークエリはAWS RDSのスローログをログファイル書き出す様に設定し、書き出したログファイルを定期的に elasticsearch へ突っ込んでいます。
これによりほぼリアルタイムにスローログを確認できます。

詳しい情報は載せられませんが、この様に一覧でスロークエリをチェックできます。
kibana_slowlog

あとはこのスロークエリを元にEXPLAINを掛け実行計画を見て、
・適切なINDEXを貼る
・適切なINDEXを使うように修正する
・データの取り方を変える
という方法でスロークエリを修正していきます。

cpu_db

この画像は負荷試験用DBのCPU使用率なのですが、クエリチューニングを行った瞬間にCPU使用率30%超から10%未満になっているのがわかります。

三つのうちどれかをやるだけでここまでのインパクトがあります

 

データ分割

もう1つの負荷対策として実行したのが水平分割です。水平分割はテーブルを行単位に分ける事です。

data_sharding

分散基準はレコード数が1000万以上になるものとしていますが、当時は負荷試験を実行後に New Relic や Jet Porfiler を見て下記のように決めていました。

負荷が高い特定テーブルや機能を洗い出し同じ機能であれば対象のテーブルすべてを分散(稀に分散できないテーブルも…)

そもそもレコード数が多いテーブル(ユーザ系や履歴系など)

newrelic

また、分割方法ですが基本的に「ID(数値)」を「DBの台数」で割った余りで分散しています。
分散した結果今まで1台のDBにかかっていた負荷は下がりました。ただ、分散することによりauto_increment も join句(データが別DBの場合) も使用不可になったり、一番厄介なのは、ユーザを調べるのに何番のDBにそのユーザがあるかチェックしてからじゃないとわからず管理が非常にめんどくさいです。
また、各DBにDDLを実行する際もDBの台数分実行しないといけないので(さすがにツール化してますが)これもめんどうです。
負荷は下がりましたが管理の手間が増えました。

 

まとめ。やってみて思ったこと。

すでにリリースしているものを後からいじるのが大変でした。
正直しんどかったっす・・・

やっていくうちにどうしても仕様を変更しないと直せないないなぁっていうことがあって申し訳なかったです。やはり最初から想定できることなので設計時点でこのような問題は考慮すべきですね。


コメントを残す