はじめに
こんにちは、バックエンド/インフラ担当の森井です。
先日、NPNS(Nintendo Push Notification Serviceの略?)のリプレイス事例がAWS Summit Japan 2024で公開されました。 NPNSは、Nintendo Switchにおける通知を行うシステムで、iOSにおけるAPNs、AndroidにおけるFCMのようなサービスです。 2018年の資料では今後の展望としてNLBとFargateの導入が挙げられていたので、システムの一部をリプレイスする話かと思いましたが、なんとシステム全体をリプレイスしていました。 2018年の資料も面白かったのですが、今回のリプレイス事例はさらに興味深い内容です。内容を要約しても仕方がないので、個人的に面白いと思ったポイントを紹介します。
アーカイブ動画は現在AWSのサイトに掲載されています。ぜひご覧ください。 おそらく今から登録しても閲覧できるのではないかと思います。
リプレイス前の情報も公開されています。 こちらも合わせて確認することで、さらに楽しめると思います!
- Nintendo SwitchTM 向けプッシュ通知システム「NPNS」
- Erlang/OTP と ejabberd を活用した Nintendo Switch(TM)向け プッシュ通知システム 「NPNS」の 開発事例 - Speaker Deck
面白ポイント1:規模がすごい
常時接続サービスはオフラインでもコネクションを維持するそうで、求められる性能要件は1億以上にスケールすることだそうです。1億台の常時接続要件なんて見たことありますか…?
インフラコストの観点から、1タスクあたりの同時接続数は数十万程度が求められるそうです(2019年の発表資料によると、負荷試験で75万接続を維持できたそう)。 このレベルになるとNLBで何が起きるか想像できますか?55,000接続あたりからポートアロケーションエラーが起きるそうです。この制約を乗り越えるためにNLBのクライアントIP保持機能がサポートされたことによりこの制約を回避できたとのこと。しかし、クライアントIP保持を有効にしたことで、クロスゾーン負荷分散を無効にせざるを得なくなり、それによりデプロイで更なる工夫を求められることとなります。
クロスゾーン負荷分散が必要な理由は、ぜひセッション動画で確認してみてください。
面白ポイント2:デプロイの課題
さて、クロスゾーン負荷分散は無効にしました。NLBは最小の未処理のリクエストをサポートしていません。そして、AZごとのタスク数は均等に配置されません。つまりTaskが少ないAZに許容量以上のリクエストがルーティングされてしまうわけです。
この課題に対して、タスクが多いAZのタスクを停止することでリバランスする戦略をとられたそうですが、今度は登録解除の遅延が1時間になっているためNLBからの切り離しに時間がかかり、リバランスに時間がかかりすぎる問題が発生してしまいます。この問題も巧妙な工夫で回避されています。
面白ポイント3:お手本の様なモダナイズ戦略
2018年のセッションでもAurora、ElastiCache for Redis、SQSなどのマネージドサービスは利用していましたが、XMPPクラスタごとにAurora、ElastiCacheを配置するため高コストかつ管理コストが高いのではと感じていました。おそらくejabberdを高可用に稼働させる上で必要だったのだと思いますが、今回常時接続プログラムをGoで書き直したことによりDynamoDBに移行することができたのでしょう。 DynamoDBはID管理に使用しているようなので、IDとその状態を示すシンプルなkey valueで表現できると思われ、置き換えることでかなりコスト削減ができているのではないかと思っています。
プッシュ通知受付サービス、通知振り分けサービスについても、セッションではあまり深掘りされていませんが、よりシンプルな構成となっています。ここについてもAurora、ElastiCacheが排除され、DynamoDBに一本化されています。しかも、通知の受付側と振り分け側がSQSが挟まっており、より疎結合なアーキテクチャとなっています。
大規模システムにおけるサーバーレスとマネージドサービス、サービス分割のお手本のような構成です。
おわりに
これらの難しい課題を乗り越え、しかも無停止でリリースされています。ちょっとすごすぎますね。 こんなブログは早く閉じて、セッション動画を見に行きましょう。
今回はインフラ面の設計を深掘りした内容になっていましたが、個人的にすごく気になっているのは常時接続プログラムの中身です。 常時接続の通信は、ejabberdによるXMPPから、Go言語によるHTTP/2ベースの独自プロトコルに乗り換えたそうです。HTTPで双方向通信するなら、普通はWebSocketやgRPCを使用するので、独自プロトコルを採用するということはここにも何か課題があったのだろうと思います。どこかのイベントで公開されることを期待しつつ、このブログを締めくくりたいと思います。