先日、会社ブログに "広告配信サーバーにおける DynamoDB Accelerator (DAX) 活用事例の紹介" というタイトルの記事を寄稿した。DAX の技術選定における注意点や活用結果、および運用保守を巡っての導入事例について紹介した。
https://techlife.cookpad.com/entry/dynamodb-accelerator-usecase-adserver
DAX というのは、一言で言うなら「DynamoDB 専用の in-memory キャッシュストア」だ。DynamoDB 自体、様々な制約(e.g. クエリオペレーションの制限、Index の付け方、Transaction、結果整合性、etc.)をユーザーに課す代償として、Write もスケールできる高パフォーマンスな NoSQL としての貴重な選択肢を提供してくれている。そして、DAX 自体にも先のブログで述べたような様々な制約(e.g. Global TTL, Single-leader, SDK の品質, etc.)をユーザーに課す代償として、かなり高パフォーマンスな Read Workload を実現できる選択肢を提供してくれている。
したがって、アプリケーションの要件がマッチするなら、DynamoDB + DAX というのは、Read も Write もスケールでき、かつインフラコストも抑えられるなかなか良い選択肢になりうるのではないだろうか。
インフラコストが抑えられるというのは、DynamoDB は On-Demand or Provisioned での課金になっている。On-Demand であればリクエスト数によって、Provisioned であれば Read Capacity Unit (RCU) または Write Capacity Unit (WCU) の消費数によって、従量課金されていく。そこで、Read Workload が heavy な要件においては、すべてのリクエストが DynamoDB にいってしまうと、どちらの課金体系をとるにしろ、想定以上の金額を支払っている可能性がある。そこで、ある一定以上のリクエストをさばくタイミングから、DAX Cluster を立ててキャッシュしていた方が総合的にお得になる、ということである。
もちろん、インフラコストを抑えるという意味でなら、別のキャッシュストアでも同じことは実現できるであろう。Elasticashe (Redis/memcached) なり、in-memory なり、お好みのものを使えば良い。
したがって、世の中的には「まず DynamoDB を入れてサービスインしたが、サービスの成長に伴って Read も Write もリクエスト数が増えてきてインフラコストが増えてきた。Read Workload へのパフォーマンス要求がそれなりに高いので、インフラコストを抑えつつ Latency も高めるために、DAX を入れるのも有り」という流れで入れる場合も多いのではないだろうか。
今回の場合、アプリケーションの実装初期から DAX を入れているが、それは過去の広告配信サーバーにおける DynamoDB の実績から、RPS が増えるに従ってレイテンシが不安定になっていったこと、及び要求パフォーマンスが p95 で 15ms となかなかにチャレンジングだったことから、最初から DAX を入れるに至った。
その他の要望としては、DAX instances に格納されている working sets や partition key ごとのアクセスパターンの可視化が提供されていないことである。基本的にこれらの情報は通常時には不要だし、気にしなくてよいのがシンプルな設計を実現できている証拠だが、とはいえ障害発生時など何らかの理由でこれらのデータが欲しくなることはあるであろう。CloudWatch Contributor Insights for DynamoDB が現在 Preview 機能で実装されているが、DAX に対してはまだ有効になっていない。個人的には、同等の機能が DAX に実装されることを望んでいる。