「何がボトルネックか」を特定し、性能を改善する
負荷クライアントの完成後、負荷試験がスタートした。だが、ここで衝撃の事実が判明する。なんと前回の負荷試験の2割程度しか処理できなかったのだ。いったい何が原因なのか。究明のための戦いが始まった。
ログファイルの分析やインフラチューニング、OSのネットワークバッファチューニングなどを行ったものの、状況は改善しなかったという。最終的には、プロファイリングツールを用いて「どんな関数が呼び出されているか」の調査が行われた。ここで、ようやく原因特定に至ったそうだ。
「なんと、デバッグ用の関数がたくさん呼び出されていました。つまり、私はデバッグモードをオンにしたまま負荷試験をしてしまったのです(笑)」と叶氏はちゃめっ気たっぷりに話す。
デバッグモードをオフにし、負荷試験が再開された。すると、前回の負荷試験と同様に秒間10万メッセージをさばくことができたという。セッション数の増加スピードも安定しており、メモリの使用量も1GB未満。目標のQoS測定をクリアした。だが、ここで負荷試験は終わらなかった。なぜだろうか。
「その理由は、『もっと性能を出せるでしょう』と上司からのメテオフォールが降ってきたからです(笑)」と叶氏は笑顔で語る。さらなるパフォーマンス改善のため、処理の最適化が検討されていった。
「Ark内部のプロセスは、メッセージを受け取るたびにオンメモリのストレージにある共有カウンターをインクリメントします。しかし、この集計方法では10万回のメッセージにつき10万回の更新が発生します。ここを改善したいと考えました」
改善策はこうだ。共有カウンターを毎回インクリメントする代わりに、プロセス内部にカウンター変数を作ってその値を加算する。そして、一定の頻度で加算後の値を共有カウンターに反映させることで、更新頻度を減らすのだ。しかし、この方法ではカウンターの差分計算やリセットの処理などが各プロセスのボトルネックになり、うまくいかなかった。
叶氏は別の方法で、処理性能の改善を模索する。これまでの分析では、Arkサーバの平常稼働時に異常な動きは見当たらなかった。そこで、さらに限界以上の負荷をかけ、サーバのクラッシュ分析を行った。するとサーバがクラッシュする際に、プロセス間の通信タイムアウトエラーが頻発していることが判明したという。
Arkでは通信のセッションを維持するために内部で複数のプロセスを立てている。そのなかに、セッション全体のライフサイクル管理・TCPメッセージのルーティングを担当するセッションプロセスと、UDP通信のライフサイクルを管理するUDPセッションプロセスがある。この2プロセス間で、タイムアウトエラーが発生していた。
Arkサーバへの負荷が大きくなると、全体を管理するセッションプロセスのタスクが多くなる。このとき、UDPセッションプロセスがセッションプロセスを同期呼び出しすると、レスポンスの待ちが発生する。そして、一定時間が経過しても返信がない場合、UDPセッションプロセスがタイムアウトエラーを起こしてしまうのだ。
「この課題を解決するため、UDPセッションプロセスが行っていた同期呼び出しを、すべて非同期呼び出しに変更しました。この結果、サーバへの負荷が大きくなった場合でも大量のタイムアウトがなくなり、Arkサーバが秒間あたりに処理できるメッセージ数が10万から11万に改善したのです」
![「負荷試験においては、上図のような点を守ることが大切」と叶氏は結んだ。](http://cz-cdn.shoeisha.jp/static/images/article/11320/11320_003.png)
サービスの処理性能を把握し、可用性をさらに高めていくために、負荷試験は欠かせない工程である。本セッションは、その重要性やノウハウが十分に伝わるものとなった。
お問い合わせ
株式会社gumi