Holmesでエンジニアをしているid:w-miuchiです。
先日弊社のサービスでリアルタイム通知の構築がトピックに上がりました。
リアルタイム通知の手段としてWebSocketに着目し、そのネットワーク構成を考えてみました。
今回はその考えた中から構成案をいくつかピックアップして紹介します。
条件
考える上で、以下を条件としました。
- データベース(Amazon RDS)の更新をきっかけにし、エンドユーザーに通知を行う
- 負荷分散を可能とする
- 仮定としてWebSocketコネクション情報はAmazon ElastiCache for Redisを利用
想定されるトラフィック量の算出も必要とはなりますが、今回は現在のHolmesのサービスと同じ量と仮定します。
注意
構成内容は弊社SREに確認済みです。
利用サービス
今回の条件で利用する(できる)サービスを洗い出したいと思います。
Routing | Application | DataStore | Cache |
---|---|---|---|
ELB (ALB, CLB) API Gateway |
ECS EC2 Lambda |
RDS DynamoDB |
Redis (ElastiCache) |
こちらを元に組み合わせて構成を考えます。
構成案
1. ALB + ECS + RDS + ElastiCache for Redis
ALB(Application Load Balancer)を利用する方法です。
ALBはパスベースルーティングが可能なため、例えば/websocketというパスで切り分けることができます。
またサブドメイン(例:websocket.xxxxxx.com)で切り分けるのであればCLB(Classic Load Balancer)でも可能です。
上記ではECS(Amazon Elastic Container Service)ですが、EC2でも問題はありません。WebSocket専用のサーバーを用意するのも有効かと思います。
処理としてはサーバーでElastiCacheのRedisにconnectionを保存しハンドシェイクします。
サーバーはデータベースにポーリングし更新通知を受け取ります。
ElastiCacheのRedisに保管されたSocketのconnectionからエンドユーザーに通知します。
非常にシンプルな構成で、弊社サービスではすでにALBを利用しているため比較的に導入しやすいです。 正直なところ弊社サービスを考えるとこの構成がベストプラクティスと考えます(笑)
メリット
- 現サービスと同じ構成のため導入しやすい
- コスト計算が行いやすい
デメリット
- ポーリングによってRDSの負荷がボトルネックになる可能性があり(Socketで利用するサーバ台数を制限するなど検証が必要)
2. ALB + Lambda + DynamoDB + ElastiCache for Redis
構成1との違いは2点です。
1点目はALBのターゲット先をECSからAWS Lambdaにしています。
WebSocketの通知だけであれば処理は軽量でAWS Lambdaでも可能かと考えます。
2点目はデータベースの更新をAmazon DynamoDBにし、Lambdaでイベントを受け取っている点です。
Lambdaを利用するためサーバーの負荷分散を任せることが可能です。
メリット
- Lambdaというマネージドサービスを利用するため負荷分散が容易
デメリット
- DynamoDB, Lambdaのコスト計算が必要
3. API Gateway + Lambda + DynamoDB + ElastiCache for Redis
構成2との違いはALBをAmazon API Gatewayに変えています。
ステートフルなフロントエンドとして、WebSocket API を作成できます。
API Gatewayでペイロードサイズやリクエスト数等の制限をかけたいならこちらがおすすめです。
またWebsocketをServerlessのサービスとして独立させることが可能です。
メリット
デメリット
4. API Gateway + Lambda + RDS for PostgreSQL(RDS Proxy)
こちらはAmazon RDSにPostgreSQLを利用した場合です。
PostgreSQLでは通知を受け取る機能(NOTIFY/LISTEN)があり、こちらを利用します。
接続にはAmazon RDS Proxyを利用します。
RDS ProxyはLambdaを同じVPC内に配置することでデータベースとの接続をプールすることが可能です。
Lambdaが起動するたびに発生していたデータベースとの接続を緩和します。
ただし、最大のネックがRDS Proxyがプレビューであること...と本記事を書いている時にRDS ProxyがGAになりました!
https://aws.amazon.com/jp/blogs/aws/amazon-rds-proxy-now-generally-available aws.amazon.com
GAになったばかりのためこちらはかなり検証が必要です。
メリット
- マネージメントサービスにおける負荷分散が利用できる
- RDBがPostgreSQLの場合はそのまま使うことができる
デメリット
- RDS ProxyがGAになったばかりで、コストもかかる
最後に
いかがだったでしょうか。
RDS Proxyを利用した構成はかなりチャレンジングですが、個人的興味で加えさせていただきました!
今後は実際に構築し検証も行ってみたいと考えています。
その結果はまた記したいと思います。
Websocketの導入検討をしている方の一助になりましたら幸いです。
Holmesはエンジニア・デザイナーを募集しています
興味がある方はぜひこちらからご連絡ください!