はじめまして。開発部のid:guitarrapc_tech です。
今回、黒騎士と白の魔王を例にモニタリングをどのようにしているのか、どのように考えてサービス監視を行っているのか紹介したいと思います。
目次
モニタリング
「黒騎士と白の魔王」の開発からリリースにかけて、大きな課題であり続けたのが「どのようにサービスのモニタリングを行うか」でした。ここでいうモニタリングは、次の意味を持たせています。
役割 | 意味 |
---|---|
現状把握 | サービスが今置かれている状態を把握し維持、改善する |
将来の予測 | 傾向から未来を予想し対策のきっかけにする |
異常発生の気づき | 異常時に適切にアラートを投げる |
この観点でモニタリングを考えたときに従来グラニが行ってきた方法では不十分であると気づき、モニタリングを改善するいい機会と捉えて取り組みました。
モニタリングの不足
従来、グラニはアプリケーション監視に最も力を注ぎ、「快適にゲームをプレイできているか」を可視化することにこだわってきました。そのツールとして、Application Performance Monitoring (以降APM)*1 の New Relic を全監視の中心と位置づけ、New Relic さえ見れば大丈夫なモニタリング体制を作ってきました。
ブラウザを主体とする別サービスでは「New Relic でうまく改善が回る状態を作り維持」することができました。*2
黒騎士と白の魔王でも、New Relic に加えてさらなる向上を目指してAWS X-Ray を用いたりなど試行錯誤を繰り返してきましたが、リリース前に行ったクローズドβテスト(CBT)で「モニタリングを中心とした改善がうまく回らない」ことに気づき見直しを行いました。
CBT で気づいたモニタリング不足
黒騎士と白の魔王では、サーバーサイドがgRPC、クライアントサイドは Unity (+gRPC)です。*3
サーバーサイドgRPC は、「ステートレスなgRPCサーバー (Service2)」と「ステートフルなgRPCサーバー(BattleEngine)」の2種類を使ってゲームロジックを制御しており、モニタリングの要となる対象です。
CBTで、New Relic を用いて監視したところ次の課題が見つかりました。
- Service2 / BattleEngine ともに CPU バウンドな状況、ゲームロジックの処理増加と共に負荷が加速
- Windowsサービスで起動したgRPC では、IISを使った従来よりも New Relic の自動プロファイリングによって取得できる情報の密結合価値が希薄化
- CPU バウンドな状況における、New Relic Profiler が及ぼす CPU 負荷比率が50%と判明し見過ごせないレベルと再認識
- 自動プロファイラで取れる情報ではない、アプリケーションロジックの取得を可視化するためのダッシュボード機能が不足
New Relic の素晴らしいポイントでもあり課題と考えているのが、自動プロファイリングです。特にIISで動かしている場合はかなりのメトリクスが自動的に取得されます。一方で、プロファイラが有効になっているときのアプリケーションパフォーマンス負荷は極めて高くアプリの処理能力低下に直結します。
CBT においてはそれが更に際立った結果になりました。次のグラフは実際のCBTにおける、同程度のユーザーアクセス負荷をかけたインスタンスCPU負荷です。New Relicが無効なインスタンス(赤)に比較して、New Relicプロファイラが有効なインスタンス(緑/オレンジ)は明確にCPU負荷が上昇しています。
加えてnon-IISなアプリケーションへのプロファイリング機能が薄く取得できる情報が減少、カスタムメトリクス可視化も、APM Custom Dashboard / New Relic Insight といったダッシュボード機能が弱いこともあり、本当に必要な情報が可視化できない現実に直面しました。
モニタリングサービスの要件と選定
これまでのグラニの監視とCBTの結果から、実現しなければいけないものは明確です。
- 任意のメトリクスを投げ、ダッシュボードが生成できる
- New Relic Insight と同等以上のダッシュボードが作成できる
- 任意のダッシュボード状態でアラートを投げることができる
- 自動Instrumentation による強制的なプロファイリングではなく、手動Instrumentationによって負荷を制御できる余地がある
- 同一ダッシュボード上に、インフラ指標も表示して何が問題なのかが判断できる
このAPM/インフラ/ミドルウェアを包括したモニタリング基盤の構築にあたり、 Datadog を利用することにしました。
選定理由はいくつかありますが、SaaSであること、強力なダッシュボード機能、関数による分析制御、モニタ基盤、APMサービスなど将来への動きを総合的に評価しました。
モニタリングの分類
グラニで監視基盤を再構築するにあたり、モニタリングを次のように分類してメトリクスを扱っています。*4
その概要を示します。
分類 | モニタリングサービス | 種類 | 概要 |
---|---|---|---|
Application Metrics | DataDog | Performance, Throughput, Duration | ユーザーからみたときのサービスの状態に直結します。アプリケーション、gRPCの各種状態を示します。 |
Resource Metrics | DataDog | Utilization, Availability | スレッドプール、サーバーCPU、DB、Redisなど各種リソースの状態を示します。 |
Events | DataDog | ServiceStatus, Error, Success, Alert | サービスのイベント、バッチ、AWS障害などの把握すべきイベントを示します。 |
Logs | DataDog + BigQuery | Exceptions, Application Log, Response, Queries | 例外ログ、アプリケーションログ、レスポンス情報など各種ログ情報を示します。 |
※ ログは、常時みるべきException情報の可視化/検索はDatadogで賄えるようにして、詳細の調査はBigQuery で行っています。New Relic でExceptionsの把握が非常に重要と認識していたため、欠かせない調整でした。
さて、モニタリングの対象となるメトリクスは特定時点のデータを指し示す値にすぎないため、連続的に時系列で保持することに意味があります。
そのため、Datdogのメトリクスリテンション期間 15ヶ月は非常に魅力的です。*5さらにタグをメトリクスに付与することで、複数メトリクスに対するフィルタ、合成、関数による操作を容易に行なえます。メトリクス + タグという属性を用いた多角的な分析を長期的に行える、グラニにとってDatadog はメトリクスをどれだけ意味のある情報に変えられるかにフォーカスしている素晴らしいサービスです。
モニタリングをレイヤー分けして可視化する
モニタリングしたデータを可視化するにあたり情報のレイヤ分けしています。*6
Layer | 概要 | 閲覧頻度 | 詳細度 |
---|---|---|---|
1 | サービスの全般的な状態 | 常時 | 低-中 |
2 | アプリケーションと相互関係にあるリソース状態 | 障害時、最適化時 | 中-高 |
3 | アプリケーションの詳細なメトリクス状態 | 障害時、最適化時 | 高 |
4 | 各ロールの詳細メトリクス状態 | 障害時、最適化時 | 高 |
1. サービスの全般的な状態
Layer1 は、サービスの状態、おおまかなトレンドが包括的に把握できるダッシュボードレイヤです。基本的にはこのダッシュボードさえ見ていれば状態は把握できるようにしています。
フロント -> バックエンドとデータが流れるため、ゲームプレイに直結するApplication Metrics、Resource Metrics の順にグラフを配置しています。
また、グラフや数値が並んでいても何が異常なのかは経験に頼りがちです。より視覚的に異常に気づけるように、注意/危険域のデータをmaker でボーダーライン表示、数値の背景色を緑/オレンジ/赤 と変化させるようにしています。
ダッシュボードは、さらに抽象化して status.io のように単純な状態表示にするとエンジニア以外にもシンプルで優しいと思います。しかしグラニにおいては、モニタリングはエンジニア自身が行う、10秒に一回程度とほぼリアルタイムにメトリクスが更新されていく環境なことから、「現時点のデータが示す意味よりも時系列の変化がもたらす意味のほうが重要」な場合が多いと判断してトップレベルグラフであっても時系列グラフを多めにしています。最も重要視したのは、このダッシュボードから動かなくても何が原因であるか状態が把握/推測できる状態を作ることです。そのため、ダッシュボードの遷移は非常にコストが大きい作業とみなしています。
2. アプリケーションと相互関係にあるリソース状態
Layer2 は、ユーザーからのリクエストを受け付けるアプリケーションと関連するバックエンドリソースメトリクスを把握できるダッシュボードレイヤです。黒騎士でいうと、Service2 や BattleEngine という gRPC アプリケーションそれぞれの状態が正確に把握できるようにしています。
Datadog は、Teamplate Variables機能を使うことで、ダッシュボードをテンプレート化することができます。
テンプレート化の何が嬉しいかというと、同じgRPCアプリである Service2/BattleEngine のようなダッシュボードの場合、グラフそれぞれの内容は同じで Templateに指定した$role変数*7を変えるだけでグラフの表示を入れ替えることができる点です。同様に 本番環境、開発環境、ステージング環境も$stack変数を切り替えるだけで、同一ダッシュボードのまま表示を変えることができます。一点だけ注意があるとすると、$role 部分を変更するだけで同じダッシュボードなのにグラフ内容が Service2 から BattleEngine に変わるようにグラフそれぞれがフィルタできるようにグラフを設計、メトリクスのタグ設計を行う必要があります。
Template Variables を使うことでダッシュボードの数の増加を防ぎ、特定のインスタンスの調査も同じダッシュボードで変数に指定するだけなのは本当に楽です。インスタンスレベルのダッシュボードも不要なため、素晴らしい機能だと思います。
3. アプリケーションの詳細なメトリクス状態
Layer3 は、アプリケーションからのインターフェース/メソッドの呼び出しを把握できるダッシュボードレイヤです。Datadog の APM は現状 .NET対応していません。*8 そこで、グラニでは弊社CTO作のDatadogSharpを用いて、gRPCアプリケーション内部からメトリクスを送っています。その際に呼び出しRPCメソッドレベル毎にタグを分けて、分類可能にしました。このタグ付きメトリクスにより、どの処理がどの程度呼ばれているのか、どういう問題が発生しているのかを把握できるようにしています。
RPCメソッドレベルで呼び出し状態が可視化されるため、障害時、最適化時に絶大な力を発揮します。
4. 各ロールの詳細メトリクス
Layer4 は、各ロール別に状態を把握できるダッシュボードレイヤです。例えば、データベースのグラフをみれば、データベースの全状態が把握できるようにしています。
これら全レイヤのダッシュボードは、TimeBoard で作成しています。これは時系列の変化をみたいときに、タイムボードならダッシュボードの時間でまとめて切り替えができるためです。スクリーンボードは現状はグラフ一つ一つを編集しながらでないと時間軸を変更できないため個人レベルの使用にとどめ、タイムボード同様に切り替えができるようにフィードバックとリクエストをしています。*9
イベント
ダッシュボード以外に、Exceptionの詳細なスタックトレースやバッチ実行をイベントに飛ばすようにしています。Eventは全文検索が可能なこともあり、探したいExceptionなどの情報を絞ることが簡単、高速で調査が捗ります。
イベントによる例外調査は、目の前でゲームに起こっている異常とアプリケーションコードを結びつける重要な役割を果たしています。Markdown 表示できるため、見た目を加工できるのもいいですね。更に深い調査が必要な場合は、BigQuery によるログ調査が可能です。
アラート
Datadogで可視化されたデータは、そのままアラート通知にも利用します。
グラニでは「本当に必要なアラートしか通知しない」ことを前提に、モニタリングするアラートは作成するようにしています。なんでもアラート流すのは簡単ですが、必要でないアラートは受け手の感度を鈍らせて本当に見逃しては行けないアラートを見逃すきっかけになるので難しいものがあります。
まとめ
New Relic から完全に Datadog 一本に乗り換えた現状をまとめて紹介しました。まだまだ考えが甘く、調整に調整を重ねていますが、間違いなくDatadog を採用しなければゲームを安定させることは難しかったと言わざるを得ません。引き続き多くの先達、諸先輩に学びつつ、楽しんでくださっているファンのみなさんにより快適なゲームを提供するためにグラニのモニタリングも進化させていきます。
参考
モニタリングは他の技術にかすみがちな気がしますが、どんどん変化を重ねています。実は検討時にPrometheus も興味深くみていたのですが、「可能な限りサービスに寄せていく」という考えのもと見送りました。
*1:インフラやミドルウェアよりもアプリケーションに特化したパフォーマンス測定を指します。詳細に関しては https://newrelic.com/application-monitoring や https://www.datadoghq.com/blog/announcing-apm/ をご参考にどうぞ。
*2:課題はありつつ、です。
*3:gRPCについて本記事では細かく記載しません。別記事で少し紹介しているので、ご興味のある方は別途御覧ください。Unite 2017 Tokyo講演「「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術」 - Grani Engineering Blog
*4:多くの公開されている知見に学びました
*5:これは同時にNew Relicではデータリテンションが短く、利用していて難しかった部分です。
*6:これも多くの知見に学びました
*7:グラニの付与した任意のタググループです
*8:Datadog社と弊社CTOで協力して.NET向けAPMクライアントを開発中です
*9:いくつか使う案があるのでその際にまた紹介したいと思います。