WebSocket接続のスケーリング:学んだ教訓

1万以上の同時接続を処理するためのWebSocketインフラストラクチャスケーリングからの実践的な知見

WebSocket Scaling Redis Architecture

課題

XRプラットフォームが成長し始めたとき、約5,000同時接続で典型的なWebSocketスケーリングの壁にぶつかりました。それをどう解決したかをご紹介します。

問題1: 接続制限

各サーバーインスタンスにはファイルディスクリプタの制限があります。インスタンスあたり約4,000接続でこの問題に直面しました。

解決策: ulimit設定を増やし、ロードバランサーによる水平スケーリングを実装しました。

# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

問題2: スティッキーセッション

WebSocket接続は同じサーバーに留まる必要がありますが、従来の負荷分散ではこれが考慮されていません。

解決策: ロードバランサーでのIPハッシュベースルーティング:

upstream websocket_servers {
    ip_hash;
    server ws1.example.com:8080;
    server ws2.example.com:8080;
    server ws3.example.com:8080;
}

問題3: サーバー間通信

異なるサーバー上のユーザーが互いに通信する必要がありました。

解決策: メッセージブロードキャスト用のRedis Pub/Sub:

// 全サーバーにメッセージを公開
await redis.PublishAsync("room:123", message);

// 各サーバーがサブスクライブしてローカルクライアントに転送
subscriber.Subscribe("room:*", (channel, message) => {
    BroadcastToLocalClients(channel, message);
});

結果

これらのソリューションを実装した後:

  • 5Kから15K同時接続にスケールアップ
  • 6ヶ月間で99.9%の稼働率
  • 平均レイテンシを150msから45msに削減

重要なポイント

  1. 最初から水平スケーリングを計画する
  2. サーバー間メッセージングにRedis Pub/Subを使用する
  3. 接続数とメモリ使用量を綿密に監視する