ContractS開発者ブログ

契約マネジメントシステム「ContractS CLM」の開発者ブログです。株式会社HolmesはContractS株式会社に社名変更しました。

AWSでWebSocketのネットワーク構成を考えてみる

Holmesでエンジニアをしているid:w-miuchiです。

先日弊社のサービスでリアルタイム通知の構築がトピックに上がりました。
リアルタイム通知の手段としてWebSocketに着目し、そのネットワーク構成を考えてみました。

今回はその考えた中から構成案をいくつかピックアップして紹介します。

条件

考える上で、以下を条件としました。

  1. データベース(Amazon RDS)の更新をきっかけにし、エンドユーザーに通知を行う
  2. 負荷分散を可能とする
  3. 仮定として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

f:id:w-miuchi:20200703173730p:plain
構成1

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

f:id:w-miuchi:20200703173734p:plain
構成2

構成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

f:id:w-miuchi:20200703173738p:plain
構成3

構成2との違いはALBをAmazon API Gatewayに変えています。

ステートフルなフロントエンドとして、WebSocket API を作成できます。

API Gatewayペイロードサイズやリクエスト数等の制限をかけたいならこちらがおすすめです。
またWebsocketをServerlessのサービスとして独立させることが可能です。

メリット

  • Lambdaに加えAPI Gatewayというマネージドサービスを利用するため負荷分散が容易
  • API Gatewayの制限が活用できる

デメリット

  • API Gateway, Lambda, DynamoDBのコスト計算が必要

4. API Gateway + Lambda + RDS for PostgreSQL(RDS Proxy)

f:id:w-miuchi:20200703173741p:plain
構成4

こちらは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になったばかりのためこちらはかなり検証が必要です。

メリット

  • マネージメントサービスにおける負荷分散が利用できる
  • RDBPostgreSQLの場合はそのまま使うことができる

デメリット

  • RDS ProxyがGAになったばかりで、コストもかかる

最後に

いかがだったでしょうか。

RDS Proxyを利用した構成はかなりチャレンジングですが、個人的興味で加えさせていただきました!
今後は実際に構築し検証も行ってみたいと考えています。 その結果はまた記したいと思います。

Websocketの導入検討をしている方の一助になりましたら幸いです。


Holmesはエンジニア・デザイナーを募集しています
興味がある方はぜひこちらからご連絡ください!

lab.holmescloud.com

lab.holmescloud.com