AWS DynamoDBを使ってDBの負荷を軽減した話

こんにちは。鹿島です。今年の3月よりリクルートライフスタイルに入社し、受付業務をサポートする受付管理サービス「Airウェイト」のエンジニアとして活動しております。

今回はAirウェイトのインフラ構成とAPIのロジックを見直し、APIのなかでもDB負荷の高い処理を外部に出してDBの負荷を減らした話です。

Airウェイトは店舗の列整理や受付表管理の煩わしさ、呼出しの手間などの業務負荷を解決する受付管理サービスです。刻々と変化するお客さんの待ち受け状況や案内状況を店舗のスタッフさんがリアルタイムで管理し、共有できるシステムを提供しています。

Airウェイトの同期

例えば、お店の状況は次のような操作で変化します。

  • お客さんが来店して受付
  • お客さんがWebから受付
  • 店舗スタッフさんがお客さんをご案内

このようなお店の状況の変化に気づいてお店に置かれた各端末がリアルタイムで同期をとるために、端末は頻繁にAirウェイトのサーバーに更新の有無を問い合わせ、もし状況に変化があれば最新情報を取得する動きをしています。

更新確認を返すAPIのDB負荷が課題に

AirウェイトのWebサーバーは各端末からの更新確認の問い合わせを受けるAPIを提供していますが、このAPIに対するリクエスト数はサーバーで受ける全リクエスト数の約8割を占めるほど頻繁に問い合わせを受けています。

サービス開始当初はどれだけユーザー数が伸びるか予想できないこともあり、一般的なインフラ構成でリクエストを受けていました。ですが、嬉しいことに順調にユーザー数が増加すると当然リクエスト数も線形に増加し、全てのリクエストを捌き切れないことが起きるようになりました。

具体的には、以前のインフラ構成とリクエストの処理フローは↓のようでした。

構成before

一般的な構成ですし、実際、サービス開始後しばらくはこの構成でも何も問題が起きませんでしたが、徐々にユーザー数が増加してくると、このAPIの性質上、

  • リアルタイム性を求めるサービスのため高頻度にリクエストを受ける
  • 複数テーブルを比較・集計する重めのSQLを発行する

ので、タイミング悪く一斉にリクエストが押し寄せるとDBのコネクションプールが枯渇してしまい、エラーが起きるようになりました。

対策の検討

そこで、DBのコネクションプールの枯渇を防ぐため、更新確認用のAPIのロジックとインフラの構成を見直すことに。対策として次のようなアイデアが出ました。

説明 メリット デメリット
DBハード増強 DBサーバーのハードを増強する Web、iOS、ブラウザアプリとも開発工数なし 定期的なインフラ作業が必要。今後もユーザー数が増加するとハード費用も増加
更新確認の周期変更 端末が更新を確認する周期を大きくする 開発工数小。DBへのアクセス数は周期の長さに反比例して現象。 リアルタイム性が落ちるためUX低下。タイミングが悪いと大量アクセスのリスクは残存
push通知 変更のタイミングで端末にpush通知送信 無駄なリクエストが減。DBへのアクセス数が8割減る見込み APNSは到達が保証されない。Web、iOSアプリの開発工数がかかる。ブラウザアプリは救えない。
WebSocket WebSocketを使って端末に変更通知 同上 Web、iOS、ブラウザアプリとも開発工数大。利用端末分だけコネクション増。インフラの構成の見直しも必要
クラウドDBの利用 クラウド環境にデータを置いて社内DBアクセスを減らす 社内DBへのアクセス数が最大8割減る見込み Webアプリの開発工数かかる。クラウド利用費用が発生

上記について、

  • UXは落としたくない
  • ユーザー増と売上増が必ずしも一致しないので、ユーザー増によるハード費用の増加は最小にしたい
  • 少ない開発工数で高い効果を得たい

という方針で比較検討したところ、高い効果を期待でき、開発工数・運用工数が比較的少ない「クラウドDBの利用」案を採用することになりました。

DynamoDBでDBアクセスを逃す

クラウドは社内で利用環境が整備されているAWSを採用し、DBサービスには下記のような理由からDynamoDBを利用することになりました。

  • 高可用性(Multi-AZ:Availability Zone単位の障害では死なない)
  • スケールが設定変更レベルのため容易
  • NoSQL DBで速度が出そう(複雑な集計は不要。一意なkeyでの検索のみ)

変更後のAPIのデータフローは↓のようになりました。

構成After

更新確認の度に問い合わせていた部分はDynamoDBに問い合わせる処理になっています。もともとDBが返していた集計結果については、その値が変わる操作をユーザーが行ったタイミングで集計してDynamoDBに結果を置くようにしています。

結果、このAPIでの社内のDBへのアクセスは不要になり、Webアプリによる社内DBへのアクセス回数を約7割程度削減できるようになりました。(古いバージョンのiOSアプリなどは昔の構成のAPIを呼ぶので、多少はDBアクセスが残ります。)

また、クラウドを利用することでインフラの調達が早く、SDK利用によりWebアプリの開発も容易のため、2人のエンジニアで2週間程度という短い開発期間で大きな効果が上げられました。

まとめ

Airウェイトの利用端末が高頻度で問い合わせる更新確認用のAPIについて、AWSのDynamoDBでデータアクセスを受けるように構成を見直した結果、DB負荷を大幅に減らすことができました。

クラウドの魅力は言うまでもなく早く、柔軟なリソースを調達できることだと思います。今回は短い開発期間で大きな効果を得られましたし、もし今後ユーザーが増えてもDynamoDBの増強は容易に、柔軟に対応できます。

ただ、今回の構成では今後ユーザーが増えると今度はWebサーバーの負荷が上がっていくので、将来的にはAPI Gateway + Lambda + DynamoDBを使った、「サーバーレス」な構成もチャレンジしたいです。

最後に、リクルートライフスタイルでは一緒に働く仲間を募集中です!クラウド使ってもっとイケてる構成を作りたい!という方も是非ページ下のバナーをクリックしてみてくださいね!