Railsプロダクトは、最初から複雑な構成にする必要はありません。一つのアプリケーションと一つのデータベースで始め、利用者、データ量、チーム、機能が増えた段階で構成を広げます。
このロードマップでは、Railsプロダクトの成長をL0〜L6の段階で整理します。段階の境界を厳密なユーザー数やRPSで決めるのではなく、現在のボトルネックと次に必要な構成を考えるために使います。
flowchart LR
L0[L0 単一アプリ・単一DB] --> L1[L1 WebとJobの拡張]
L1 --> L2[L2 Rails取得・SQL改善]
L2 --> L3[L3 DB読み取り改善]
L3 --> L4[L4 DB分割・Replica]
L4 --> L5[L5 Partition・Shard]
L5 --> L6[L6 サービス境界]
L0:単一アプリケーション・単一データベース
Rails、ActiveRecord、単一の主要データベースを中心に開発する段階です。業務概念、ユースケース、テーブル、モデル、画面やAPIの関係を一つのアプリケーション内で把握できます。
業務データとユースケースを整理し、RailsのModel、Controller、Jobを基本構成として使います。RDBの制約、基本的なIndex、ページングを設計し、主要な処理時間とQueryを計測できる状態にします。
L1:Web・Job・Cacheの拡張
Webリクエスト、バックグラウンド処理、Cacheを分け、アプリケーション層を水平に増やす段階です。
- Webプロセスを複数化する
- Job WorkerをWeb処理から分離する
- Cache、Load Balancer、静的ファイル配信を分離する
- Web、Job、DBの負荷を個別に観測する
L2:Railsの取得処理とSQLを改善する
画面やAPIの処理が遅くなったときに、ActiveRecordの取得方法とSQLの形を見直す段階です。Railsプロジェクトで最初に調べやすい改善領域でもあります。
ActiveRecordの取得戦略、N+1、JOIN、Rails側メモリの詳しい説明は、Railsの取得戦略を、N+1・JOIN・アプリメモリの負荷から考えるを参照してください。
L2-A:ActiveRecordの取得戦略
N+1を確認し、preload、eager_load、includes、joinsを使い分けます。selectやpluckで不要な列とオブジェクト生成を減らし、ページングで一度に扱うレコード数を抑えます。
L2-B:SQLと画面取得の形
JOIN前に対象範囲を絞り、JOINによる行の増加を確認します。集計、Sort、ページングの処理場所を見直し、重い集計はAjaxやJobへ分けます。変更後はEXPLAINと実測値で結果を確認します。
L3:DB側の読み取りを改善する
Rails側の取得方法とSQLを改善したうえで、DB側の読み取り経路を見直す段階です。候補にはIndex、View、Materialized View、Read Modelがあります。
- IndexをQueryの条件、JOIN、Sort、集計と照合する
- 複雑なJOINを通常Viewへまとめる
- Materialized Viewや集計テーブルで読み取り用の結果を保持する
- 検索IndexやRead Modelを用途別に作る
L3では、読み取りの速さだけでなく、更新遅延、Refresh、データ整合性、Indexの書込みコストも確認します。
L4:DBの読み書き分離・機能分割
読み取り量や機能ごとのデータ量が増え、一つのDBに集中する負荷を分ける段階です。
Read Replicaを導入し、Railsの接続先を読み取りと書込みで分けます。必要に応じて機能単位でDBを分け、集計、検索、ログなどを専用基盤へ移します。
L5:Partition・Shard・Pod
一つのDBクラスタで容量、書込み量、IOPS、バックアップ時間を処理しきれなくなり、データを複数の単位へ分ける段階です。
時間や状態によるPartition、Tenant・User・Projectなどを基準にしたShard、アプリケーション・DB・Cache・Jobをまとめて分けるPodを検討します。
L6:サービス境界の分離
独立デプロイ、独立スケール、独立可用性、独立したデータ所有が必要な領域をサービスとして分けます。
検索、ファイル操作、Git操作、決済など、独立性の高い領域から境界を作ります。
このロードマップの使い方
- どの処理が遅いのかをユースケース単位で確認する
- Web、Job、Rails、SQL、DBのどこが詰まっているかを分ける
- 現在の段階のサブ段階から、変更コストに合った施策を選ぶ
- 変更後の処理時間、Query数、DB負荷、メモリを再計測する
- 改善後のボトルネックに応じて次の段階を選ぶ
このロードマップを使うと、Railsを中心に、必要な層から段階的に拡張できます。