サービスを公開したばかり。
利用者はまだ数人。
それなのに、毎月届くAWSの請求書を見るたびに、
「この固定費、結構痛いな…。」
そう感じたことはありませんか?
私たちもRe:Linkの開発当初は、まさにその状態でした。
恐ろしく高いAurora
RDB前提でDB設計した誤り
皆さんは、新しいサービスを開発するとき、どのデータベースを選択しますか?
弊社はもともと、いわゆるオープン系システムの開発を得意としてきました。そのため、データベースといえば、MySQLやPostgreSQLといったRDBを選択するのが自然でした。
Re:Linkの開発でも、使い慣れていることや、複雑なデータの関連を扱いやすいことから、当初は、何の疑いもなくRDBを中心にシステムを設計しました。
今振り返ると、開発を始める段階で、AWS上での構成や運用コストまで、もう少し踏み込んで検討しておくべきだったと感じています。(正直、その段階では、AWSを利用すること自体まだ決まっていませんでした。。)
そうです。
システムの大部分を、RDBを前提に設計・構築してしまいました。
そして、実際にAWS上へ載せてみて驚きましした。。まだ利用者はほとんどいないのに、データベースの費用は毎月しっかり発生する。
RDBは非常に便利です。しかし、マネージドなRDBサービスを常時稼働させる場合、アクセスが少ないサービス開始直後でも、一定の固定費が発生します。
サービスの売上はまだない。登録者も少ない。それでも、データベースは24時間稼働している。スタートアップにとって、この固定費は決して小さくありません。
大きな路線変更、DynamoDB
DynamoDBの存在は以前から知っていました。実は、別プロジェクトで利用した経験もあります。しかし、その時の印象は正直あまり良いものではありませんでした。
「設計の癖が強い。」
RDBのようにSQLで自由に検索できるわけではなく、JOINでテーブル間を関連づけての抽出も行えません。最初にキー設計を間違えると、後から変更するのも簡単ではありません。そのため、Re:Linkの設計段階では、**「今回はRDBで構築しよう。」**っと迷わずとうか疑いなく、そう判断していました。
AWSに載せて気付いたこと
しかし、実際にAWSの請求を見て考えが変わりました。「これはダメだ。考え直そう。」
匿名チャットシステムで最も多く扱うデータは、チャットルームごとのメッセージです。では、実際にどのようなアクセスをしているのか整理してみました。
ルームIDを指定してメッセージを取得する。
送信日時でソートする。
それ以外は、アプリケーション側でフィルタリングすれば十分ではないか。
そう考えると、逆に
- 複数テーブルのJOIN
- 複雑な条件検索
- 集計処理
といったRDBが得意とする機能は、チャットメッセージではほとんど利用していませんでした。そこで初めて気付きました。**「これ、RDBである必要がない。」**考え方が180度変わった瞬間でした。
データベースに対する発想の転換
RDBを設計するとき、私はいつも**「どんなデータ構造にするか」**を考えていました。テーブルを分割し、正規化を行い、リレーションを組む。それが当たり前でした。しかし、DynamoDBでは発想がまったく違います。
まず考えるのは、**「どのようにデータを取得するか」**です。
つまり、
- パーティションキーは何か
- ソートキーは必要か
- GSIはどこに張るか
というアクセスパターンを先に設計します。
この考え方に切り替わった瞬間、匿名チャットシステムとDynamoDBは驚くほど相性が良いことに気付きました。
データの特性に合わせて選ぶ、それぞれに得意分野があります。私がこの記事で一番伝えたいのは、DynamoDBの使い方ではありません。
RDBは「データ構造」を設計する。
DynamoDBは「アクセスパターン」を設計する。
RDBを選択したあの頃は、後者の考えに至っておらず。本来このシステムに適していたDynamoDBという選択に至らなかった。この考え方をしたことが、Re:LinkのAWSアーキテクチャを見直す大きな転機になりました。
おまけ:大きな路線変更を支えた基本設計
「すでにRDBで構築してしまった場合、DynamoDBへの切り替えは大変ではないか」
そう思われる方もいるかもしれません。
実際にデータベースを切り替える際、特に気になるのは、呼び出し側の処理へどれだけ影響が及ぶのかという点です。
Re:Linkのチャット機能も、当初はRDBを前提に開発していました。しかし、もともとの設計でデータアクセス用のインターフェースを用意し、サービスロジックからデータアクセスの実装を独立させていました。サービスロジックが利用するのは、共通のインターフェースです。実際の保存先がRDBなのかDynamoDBなのかは、呼び出し側からは意識しない構成になっています。
そのため、今回の切り替えでは、既存のサービスロジックを大きく変更するのではなく、DynamoDB用のデータアクセス処理を追加し、利用する実装を動的に切り替えることで対応できました。
もちろん、RDBとDynamoDBではデータの持ち方や取得方法が異なります。その差異はそれぞれのデータアクセス実装の中で吸収し、サービスロジックへの影響を最小限に抑えています。
結果として、チャット機能全体を作り直すことなく、AuroraからDynamoDBへ移行できました。
まとめ
この記事は、AWSの固定費をどう削減するかという悩みから始まりました。
Auroraの固定費を見直したことをきっかけに、チャットシステムのアクセスパターンを改めて整理した結果、DynamoDBという選択肢にたどり着きました。
結果として固定費を抑えることができましたが、それ以上に大きな収穫だったのは、データベースに対する考え方が変わったことです。
RDBは「データ構造」を設計する。
DynamoDBは「アクセスパターン」を設計する。
そして、データアクセスの独立性を担保した設計にしていたことで、この大きな路線変更もサービスロジックへの影響を最小限に抑えながら実現できました。
スタートアップでは、コストを意識することが設計を見直すきっかけになることがあります。今回の経験は、Re:LinkにとってAWSアーキテクチャを見直す大きな転機となりました。

