「1億台の常時接続」を実現せよ! Nintendo Switchのプッシュ通知システム全面刷新の裏側

AI要約

アマゾン ウェブ サービス ジャパンがAWS Summit Japanで行った講演「Nintendo Switch向けプッシュ通知システムのリプレイス事例」を報告。

Nintendo Switch向けのプッシュ通知システムのリプレイスに伴う課題や解決策、システムの機能強化について解説。

大規模な常時接続実現に向けたサーバーレスサービスの活用やデプロイツールの自作など、さまざまな取り組みを紹介。

「1億台の常時接続」を実現せよ! Nintendo Switchのプッシュ通知システム全面刷新の裏側

アマゾン ウェブ サービス ジャパンは、国内最大の年次イベントである「AWS Summit Japan」を開催。本記事では、ニンテンドーシステムズによる講演「Nintendo Switch向けプッシュ通知システムのリプレイス事例」をレポートする。

 アマゾン ウェブ サービス ジャパンは、2024年6月20日と21日、国内最大の年次イベントである「AWS Summit Japan」をハイブリッドで開催。150を超えるセッションが展開された。

 

 本記事では、ニンテンドーシステムズによるセッション「Nintendo Switch向けプッシュ通知システムのリプレイス事例」をレポートする。登壇したのは、同社 システム開発部の林愛美氏と坂東聖博氏だ。

 

 2017年のNintendo Switchの発売とあわせてリリースされた「プッシュ通知システム」。同社は、長期運用を見据えて、よりクラウドネイティブなシステムへのリプレイスを決定するが、大量のTCP接続を維持するための様々な課題が立ちふさがった。

 

 本セッションでは、AWS FargateやNetwork Load Balancer(NLB)といったAWSのマネージドサービスを用いて、“最大1億台”級のスケーラビリティを持つ大規模常時接続の実現までの道のりが紹介された。

 

増え続ける同時接続、長期運用を見据えてリプレイスを決意

 Nintendo Switch向けのネットワークサービスは、本体と常時接続される「プッシュ通知システム」を経由して、任意のタイミングで通知を送信している。フレンドがゲームを遊び始めた時のオンライン通知、本体更新の通知、ニュース配信などが同システムを利用しており、ゲーム購入時にダウンロード開始を指示する機能も同システムによるものだ。

 

 既存のプッシュ通知システムは、XMPPサーバーである「ejabberd」を利用して、複数クラスタで構成。AWSのAmazon EC2やAmazon RDSなど、実績のある安定したサービスを採用していたという。

 

 一方で、Nintendo Switchでプレイするユーザー数は年々増加しており、2023年4月から2024年3月の期間には“1億2300万人”に到達。もちろんプッシュ通知システムへの同時接続数も増え続けていた。

 

 このような実情を踏まえ、今後の長期的な運用を見据えたリプレイスを決定。課題にあわせた以下の“4つのコンセプト”のもとで刷新が進められた。

 

・柔軟に機能追加できるよう、カスタマイズしたOSSの利用を止め、独自のアプリケーション開発に移行

・開発者の流動性を確保するべく、他システムで採用実績のある「Go」で開発

・開発/運用の効率を高めるべく、クラスタ構成を止めてシンプルなアーキテクチャーに

・運用工数を削減するために、サーバーレスサービスを積極的に採用

 

 本セッションでは主に、4つ目のコンセプトに関わる大規模常時接続実現に向けたサーバーレスサービスの活用について解説した。

 

常時接続サービスの性能要件は“一億台の同時接続”

 リプレイス後のシステムでは、ロードバランサーには「ELB(Elastic Load Balancing)」を、コンピューティングリソースにはサーバレスの「AWS Fargate(ECS on Fargate)」を、データベースには「DynamoDB」を採用した。

 

 Nintendo Switchがプッシュ通知システムに接続する流れは次のとおりだ。まず、ID払い出しサービスにアクセスして、プッシュ通知システム用のIDを作成する。その後、接続先振り分けサービスへアクセスし、接続する常時接続サービスのURLを取得する。そして、常時接続サービスが、Nintendo SwitchとTCPコネクションを確立、長時間接続を維持する。接続中には、HTTP/2を利用した独自プロトコルで双方向通信する。

 

 この常時接続サービスは、NLB(Network Load Balancer)とECSサービスをひとつのUnitとして、複数のUnitに分割されている。本サービスの性能要件は、“最大1億台の同時接続”に耐えうるスケーラビリティだ。

 

 「この要件をAWSに相談したところ、NLBに障害が発生した場合の影響範囲という観点から分割を推奨された」と林氏。あくまでNLB観点でのUnitの分割であるため、すべてのUnitは同じDynamoDBのテーブルを参照しており、シャーディングのようなデータベースの負荷分散はしていないという。

 

 逆に、Nintendo Switchに通知が送られる流れは次のようになる。まずネットワークサービスが、プッシュ通知システムが用意する通知送信用APIを利用して通知を送信。正常に受け付けられた通知は、メッセージキューイングサービスである「Amazon SQS」に保存される。

 そして通知振り分けサービスがSQSから通知を受け取り、DynamoDB上のセッション情報を用いて、対象のNintendo Switchが接続する常時接続サービスのFargateのタスクを特定して通知を送る。最後に、通知を受け取った常時接続サービスが、対象のNintendo Switchに対して通知を届ける。

 

ECS on Fargateの機能強化で満たされた一部要件

 林氏は、「ECS on Fargateで大規模な常時接続システムを実現するためには、様々な要件が求められる。旧システムをリリースした当初のECS on Fargateではそのための機能が不足していた」と説明する。だがその後、ECS on Fargateの機能強化によって、一部の要件は実現可能になっていく。

 

 そうしたECS on Fargateの機能強化のひとつが、「TCP接続を維持するためのチューニング」機能だ。

 

 プッシュ通知システムは、スリープ中でもNintendo Switchとの接続を維持している。スリープ中のバッテリー消耗を防ぐため、「TCP keepalive」で負担を軽減したり、TCP再送関連の挙動に気を配ったりという工夫が必要だった。

 

 ECS on Fargateでは、こうしたTCPの挙動を細かくコントロールするためのカーネルパラメーターの調整が、2023年8月より可能になった。

 

 もうひとつのアップデートが、NLBの「クライアントIPの保存」だ。

 

 インフラコストの観点から、1タスクあたり数十万の同時接続が求められる中では、NLBの「ポートアロケーションエラー」の発生がボトルネックになる。

 

 クライアントIPの保存が“無効”になっていると、NLBによってソースのIPアドレスとポートが付け替えられる。その結果、ロードバランサーノードへの同時接続数が5万5000を超えたあたりでポートアロケーションエラーが発生してしまうという。

 

 このクライアントIPの保存が2021年に可能になったことで、このボトルネックを回避できるようになった。

 

 ただし、クライアントIPの保存を有効にするとポートの共有という問題が発生してしまう。

 

 NLBは、AZごとにロードバランサーノードを作成して、それぞれ別のIPアドレスを割り当てる。クライアントが名前解決をした際には、これらのIPを複数返答することで負荷分散を実現している。この仕組みにより、複数のNintendo Switchが同一のNATを経由して異なるロードバランサーノードに接続すると、宛先のIPが異なるためNATがソースポートを共有し、通信が切断されてしまう可能性があるのだ。

 

 同社はサービスの品質低下と天秤にかけ、AZをまたいだ「クロスゾーン負荷分散」を無効化することで、この問題を回避した。

 

 このように、ECS on Fargateの機能強化で一部の要件は満たされた。それでも足りない要件は、補完する独自の仕組みを実装することになった。その仕組みのひとつが「デプロイツール」の自作である。

 

デプロイツールの自作で、大量接続を安定かつ高速に再接続

 システム開発部の坂東氏は、「デプロイツールを自作した一番の目的は、デプロイ時の負荷分散を行うこと。常時接続で最も負荷の高い処理は“接続の開始処理”だ」と強調する。デプロイ時には、すべてのタスクが入れ替わって再接続処理されるため、すべてのタスクに対して均等かつ、接続処理が重ならないよう分散させることが理想になる。

 

 接続のタイミングを分散させる方法については、リプレイス前から実装している、一定の速度で再接続を促す「ドリップ処理」を踏襲(参考記事:Nintendo Switchのプッシュ通知を支えるテクノロジー)。新たに取り組んだのは、不均等な接続先のタスクを分散させることだ。

 

 タスクが不均等に接続される要因は2つある。ひとつは、AZにおいてタスク数が均等に配置されないことだ。例えば、5つのAZを横断して50台のタスクをデプロイした場合、あるAZにはタスクが1台しか配置されないのに、ほかのタスクには16台が配置されるといった事態が起こりうる。「このような不均等な配置は容易に起こり得る」と坂東氏。

 

 もうひとつの問題は、起動タイミングのばらつきによる問題だ。NLBでは負荷に応じて動的にリクエストを割りあてる「least connection」アルゴリズムをサポートしておらず、かつ常時接続サービスは、一度接続が開始されるとリバランス(再配置)の機会が発生しない。そのため、一部のタスクの起動が遅いと、早く起動したタスクに接続が偏ってしまう。

 

 これらの要因から、常時接続サービスのデプロイでは「再接続はゆっくりしてほしい」「タスクはAZに均等であってほしい」「タスクはなるべく同時に起動してほしい」という3つの要求を満たす必要がある。古いタスクを新しいタスクに切り替える手順に沿って解決策が解説された。

 

 デプロイが始まる前は、すべての接続が古いタスクに向いている。ここで新しいタスクを立ち上げると即座に新規接続が流れてしまうが、新しいタスクは、AZによって不均等な状態である可能性がある。

 

 そこで、「ヘルスチェックの状態を制御する」仕組みを実装し、AZに対して均等にタスクが配置されているかをチェックできるポイントを設けた。具体的には、新しいタスク内のアプリコンテナをヘルスチェックさせ、Amazon S3上に特定のオブジェクトが存在しない限り失敗させることで、タイミングを制御した。

 

 新しいタスクが起動すると、デプロイツールはタスクが均等に配置されているかを確認し、過剰なタスクを停止させることで均等になるよう調整する。「感覚的には、1、2回停止して回ることで、均等にタスクを並べることができる」と坂東氏。

 

 しかし、NLBに登録されたタスクを停止すると、ECSサービスが、NLBの登録解除の遅延設定の時間だけ待機して、リバランスに大幅な時間を要してしまう。この問題の解決には、ECSサービスが、タスクのすべてのコンテナが起動完了するとNLBに登録するという仕組みを利用した。タスクのアプリに、ヘルシーになるまでペンディング状態を維持するサイドコンテナを追加することで、NLBの登録を意図的に防いだ。

 

 タスクがAZに均等配置されると、S3上にオブジェクトを置いて、アプリのヘルスチェックが成功し、ペンディングしていたサイドコンテナが起動して、NLBにタスクが登録される。そして、新しいタスクに新規の接続が流れる。

 

 一方で、新しいタスクへのルーティングが開始されると、古いタスクの停止処理が開始される。ここで古いタスクへのすべての接続が、瞬時に切断されてしまうと、分散されない再接続処理が発生してしまう。この問題の解決には、タスク内のアプリがNLBからの登録解除を検知する機能と、前述のドリップ処理を実装することで解決した。

 

 古いタスクを停止すると、まずはNLBから登録解除される。アプリは自身のタスクが登録解除されたことを検知すると、つながっているNintendo Switchに対して、一定速度で再接続要求を出すことで再接続処理を分散させる。再接続要求を出し終えると、アプリのプロセスが終了して、ECSサービスによって削除されるという流れだ。

 

 ここまでのデプロイのプロセスは、もちろん手動ではなく、GitHubのCI/CDツールである「GitHub Actions」のワークフローとしてすべて自動で実行される。デプロイは約30分で完了し、接続中に届いた通知も、再接続が完了すると受け取る仕組みで、ユーザーへの影響もない。負荷試験では、実際に1億台の接続を維持した状態で、挙動に問題ないかどうかを確認したという。

 

数々の問題を乗り越え、サービス無停止で無事リリースは完了

 これらの数々の課題を乗り越えて構築されたシステムは、サービス無停止で無事リリースが完了し、順次移行が進んでいる。

 

 今回は、全面的なリプレイスだったため、別のAWSアカウントに新規でシステムを構築、接続先システムを切り替える方式をとっている。初回アクセス時に旧システムから新システムに対して、接続デバイス情報の移行処理が行われる。

 

 2024年前半にNintendo Switchに配信されたシステムバージョン更新から、順次リプレイス先のシステムに接続され、既にネットワークに接続している多くのデバイスが移行を完了しているという。

 

 Amazon EKS(Elastic Kubernetes Service)を利用したk6による本番規模負荷試験やAWS FIS(Fault Injection Service)を利用した障害試験などで備えたこともあり、リリース後も安定運用を達成しているという。

 

 今後の展開としては、Fargateを次世代プロセッサーであるGravitionベースに移行することを検討中だ。常時接続サービスのインフラ費用が占める割合が大きく、大幅なコスト削減につながることを期待しているという。坂東氏は、「これからも様々な改善を通じて、お客様の体験をよりよいものにしていきたい」とセッションを締めくくった。

 

文● 福澤陽介/TECH.ASCII.jp