「IDOLY PRIDE」でGo、gRPC、Cloud Spannerに挑戦してみた


[QualiArts AdventCalendar](https://qiita.com/advent-calendar/2021/qualiarts) 2日目の記事は、「[IDOLY PRIDE](https://idolypride.jp/game/)」のバックエンドエンジニアをしている朝倉が担当します。

# はじめに

2021年6月にリリースした「[IDOLY PRIDE](https://idolypride.jp/game/)」では、QualiArtsのゲームバックエンドとしては初めてGo、gRPC、Cloud Spannerを採用しました。本記事では、それらの技術に挑戦した理由やリリース・運用を経験してそれぞれの技術の良かった点・苦労した点をまとめたいと思います。

それぞれの技術に対してバックエンドメンバーにアンケートを記入してもらい、そのアンケートをもとに（ゲームバックエンドでのユースケースにおける）良かった点・苦労した点を振り返りしました。次章から振り返りで話し合った良かった点・苦労した点を品質特性の軸で紹介していきます。

**アンケートの内容**
それぞれの技術に対して、次の項目を記入してもらいました。

* 5段階評価とその理由（1:次は採用しない、5:次も採用する）
* 良かった点
* 苦労した点

**品質特性とは**
ソフトウェア品質の評価に関する国際規格（ISO/IEC 9126）で、6つの特性とそれぞれの品質特性をさらに細分化した副特性が定められています。

| 品質特性 | 副特性 | 説明 |
|:-|:-|:-|
|機能性|合目的性，正確性，相互運用性，標準適合性，セキュリティ|求められる機能が満たせているか|
|信頼性|成熟性，障害許容性，回復性|正常に動作するか、障害が起こりにくいか|
|使用性|理解性，習得性，運用性|理解しやすいか、使いやすいか|
|効率性|時間効率性，資源効率性|開発効率がよいか、リソース効率がよいか|
|保守性|解析性，変更性，安定性，試験性|改修しやすいか、運用しやすいか|
|移植性|環境適用性，設置性，規格適合性，置換性|他の環境へ移しやすいか|

# Go

## 挑戦した理由

「[IDOLY PRIDE](https://idolypride.jp/game/)」のバックエンドエンジニアはJavaのプロジェクト経験者が多かったのですが、下記の理由からGoに挑戦しました。

* 言語仕様がシンプルなので長期運用でメンバーの入れ替えなどがあっても学習コストを低く抑えらる。
* 静的型付け言語でコードが追いやすいので運用開発においても品質が担保できる。
* 起動が早いなどDocker、Kubernetesなどのコンテナ技術との相性が良い。
* 単純にJavaに飽きたので別言語をやってみたかった。

## リリース・運用してみた所感

![スクリーンショット 2021-11-29 15.41.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534842/0afc93c3-9d02-f374-0c3b-edfee9346890.png)

| 品質特性 | 良かった点 | 苦労した点 |
|:-|:-|:-|
|機能性|**標準パッケージが充実＋サードパーティライブラリでゲームバックエンドで求められる要件は満たすことができた。**<br>ベンチマーク、プロファイルが標準で入っていて簡単に使える。<br>並行処理が書きやすい。<br>ダックタイピングのinterface仕様も使いやすい。||
|信頼性|||
|使用性|**言語仕様がシンプルで学習コスト低めでキャッチアップしやすかった。**<br>**情報が多い。コミュニティも活発で勉強会や資料も豊富にある。調べるとだいたい情報が見つかった。**<br>スクリプト言語的な用途でも利用できる。<br>言語自体の人気があり採用でメリットがあった。|**ジェネリクスがなく、コレクション操作が冗長になりがち。**<br>エラーハンドリングがめんどくさい。<br>三項演算子がほしい。|
|効率性||**コード量が多くなる。処理が長くなる。自動生成でカバー必要だった。**|
|保守性|**fmtが標準であり、言語仕様的にもコードが統一されやすい。**<br>**静的型付けでコードを追いやすい。レビューしやすい。**<br>エラーハンドリングも処理が明確になってよい。<br>標準パッケージやライブラリのコードもシンプルなので読んで動きを理解できる。||
|移植性|ワンバイナリにコンパイルできたり、起動速度が早いなどコンテナ環境との相性良い。<br>バージョンアップ時の互換性が高い。<br>||
**太字**は多かった意見。

## 総評

強くデメリットを感じる場面はなく高評価でした。
複数人かつ長期運用での開発でメリットを感じる意見が多くありました。
API以外のユースケースでも利用しやすく、スクリプト的な用途でも利用しています。
コードが長くなりがちなので、DB周りのコードなどを自動生成するなどで開発効率を上げる工夫をしていました。
（コードは長くなるけど、思考がシンプルなので開発スピードは早いとの意見もありました。）

# gRPC

弊社エンジニアの簗瀬が執筆した「IDOLY PRIDE」のgRPC利用に関する記事記事も合わせてご覧ください
[「IDOLY PRIDE」におけるgRPC利用とカスタマイズ](https://technote.qualiarts.jp/article/24)

## 挑戦した理由

「[IDOLY PRIDE](https://idolypride.jp/game/)」までのゲームタイトルでは、各ゲームタイトルごとにクライアント・サーバー間の通信仕様を決めて通信基盤や自動生成ツールなどを開発していました。タイトルごとの通信仕様を共通化していきたいという理由からgRPCに挑戦しました。

* IDL（protoファイル）を利用して、クライアント・サーバー間の通信内容を定義し共有することで開発スピードが上げられる。
* REST APIと比較して通信速度が速いので、ユーザ体験が良くなる。
* これまでも、Bodyサイズの削減やシリアライズ・デシリアライズの速度の向上のために、REST APIでBodyをProtocolBuffersでシリアライズすることが多かったため慣れている。

## リリース・運用してみた所感

![スクリーンショット 2021-11-29 16.39.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534842/06612641-2317-4b8e-5c9a-23163aa1096e.png)

| 品質特性 | 良かった点 | 苦労した点 |
|:-|:-|:-|
|機能性|**option、プラグイン拡張、protoのリフレクションなどでカスタマイズ、自動生成やりやすい。**<br>**RESTに比べて通信が高速でユーザ体感がいい。**|ストリーミング通信を使う機会はなかった。|
|信頼性|（静的型付け言語だと）サーバー、クライアントでコードがずれることない。||
|使用性||**マネージドのLB、WAFが使えなかったり、（istioでLoadBalancingするなど）インフラ面の考慮が必要で導入コストが高かった。**|
|効率性|**クライアントとの意思疎通や繋ぎ込みがやりやすい。**|**負荷試験、脆弱性診断の準備などHTTPと比較して導入コストが高かった。**<br>RESTに比べると周辺環境が整っておらず、APIのデバッグなどがやりにくかった。|
|保守性|IDLで情報が共有しやすい。||
|移植性|||
**太字**は多かった意見。

## 総評

クライアントとの意思疎通やカスタマイズ性の高さでAPI開発がやりやすくなったとの意見が多くありました。
一方、技術検証や基盤の準備、インフラ面の考慮など導入コストはかなり大きかったです。
GCP、AWSのマネージドサービスでも、徐々にgRPC対応されているので導入の閾値は下がってきていると感じます。

# Cloud Spanner

弊社エンジニアの島田が執筆した「IDOLY PRIDE」のCloud Spaner利用に関する記事も合わせてご覧ください
[「IDOLY PRIDE」におけるGoogle Cloud Spannerの活用](https://technote.qualiarts.jp/article/26)

## 挑戦した理由
これまではMySQLを採用することが多かったのですが、テーブルの分割やマスター/スレーブ構成などをしてスケーラビリティを確保したり、アップデート作業が必要だったり運用負荷が高いのが課題でした。データベースの運用負荷を減らしたいという理由でCloud Spannerに挑戦しました。

* フルマネージドのサービスで、設定項目もリージョンとノード数くらいで運用負荷が少ない。
* ノード数を増やすことでスループットを増加させることができる。ノード数はオンラインで増やすことができるので負荷に応じて柔軟に運用できる。
* トランザクションが利用できるのでデータの整合性を保ちやすい。
* RDBと同じように、スキーマ定義やSQLクエリが利用でき、スキーマ変更はオンラインで適応可能。

## リリース・運用してみた所感

![スクリーンショット 2021-11-29 15.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534842/d3b2b166-df9d-08a2-fde6-e4387b2eda46.png)

| 品質特性 | 良かった点 | 苦労した点 |
|:-|:-|:-|
|機能性|**周辺環境が整ってきている。（エミュレータやプロセッシングユニット等）**<br>インターリーブでデータ取得を効率化できる。||
|信頼性|**スケールとトランザクションが両立していて、レイテンシも問題になってない。**||
|使用性||**DB設計時の考慮やウォームアップなどでホットスポットへの考慮が必要。**<br>**複数ユーザで同一レコードの同一カラムを同時更新するとトランザクションリトライが発生しスループットが悪化する。**<br>**トランザクションリトライを意識した実装（冪等性の担保）が必要。**<br>**バッチ処理などではミューテーション上限の意識が必要。**<br>RO、RWトランザクションの使い分けを意識。<br>採用事例がまだまだ少なく。情報が少ない。|
|効率性|エミュレータでローカル開発ができる。|料金が高い|
|保守性|**自動スプリット分割やノード数の調整でスケールが簡単にできる。**<br>**CPUなど監視の指標がシンプル。**||
|移植性||GCPでしか使えない|
**太字**は多かった意見。

## 総評

パフォーマンス、スケール、監視などの面でとても快適に運用できています。
インスタンス料金は高いですが、負荷に応じて柔軟にノード数を調整できるため実際の料金はMySQLと比較してもそれほど高くはなっておりません。プロセッシングユニットの登場により、開発環境などの小規模環境でも安く利用できるようになりました。
「[IDOLY PRIDE](https://idolypride.jp/game/)」の開発初期（2019年頃）と比較し現在は周辺環境がかなり整ったので使いやすくなりました。直近でもプロセッシングユニット、TTL、BigQuery連携など便利な機能が追加されより使いやすくなっています。
ただ、ホットスポットの考慮やトランザクションリトライ、ミューテーション上限などの特性をきちんと理解してゲーム要件にマッチするか十分検討が必要だと感じています。

# まとめ

今回は「[IDOLY PRIDE](https://idolypride.jp/game/)」でのGo、gRPC、Cloud Spannerに挑戦した理由と実際に利用してみて良かった点・苦労した点を簡単にですが紹介させていただきました。リリースから半年経ちますが、大きな問題なく運用できておりそれぞれの技術のメリットも感じています。本記事がGo、gRPC、Cloud Spanner導入の参考になれば幸いです。