背景:
適切にスケーリングできるようにしたいWebアプリケーションを作成しました。私はGoogleやTwitterではないことを知っていますが、私のアプリはユーザーごとにかなり大量のデータを使用するため、かなり高いデータ要件があります。後ですべてを再構築する必要なく、適切に拡張できるように準備したいと思っています。
私はデータベースの専門家ではなく、ソフトウェア開発者だと思っています。それが私がここに投稿する理由です。うまくいけば、より多くのデータベースの専門知識を持つ誰かが私に助言を与えることができます。
比較的多数のユーザーがいるが、Facebookの番号のようなものは何もないので、私は次のようなDBを期待しています。
1つの「大きなテーブル」:
- 2億5000万件のレコード
- 20カラム
- 約100 GBのデータ
- インデックス付きのbigint(20)外部キーがあります
- インデックス付きのvarchar(500)string_id列があります
- int(11)の「値」列があります
他の4つのテーブル:
- それぞれ1,000万件のレコード
- それぞれ約2〜4 GBのデータ
- これらの各テーブルには4〜8列があります
- 1つの列はdatetime date_createdです
- 1つの列はvarchar(500)string_id列です
- これらの各テーブルから1つまたは2つの列が結合で選択されます
これらのテーブルの1つは平均を格納するために使用されます-そのスキーマはbigint(20)id、varchar(20)string_id、datetime date_created、float average_valueです。
私がやりたいこと -2つの比較的高価なクエリ:
新しい平均値を計算します。
- 外部キーを使用して、大きなテーブルから最大数百万の個別のレコードを選択します。
- string_idでグループ化して、新しい平均を計算します。
- 結果を平均表に挿入します。
- 現在作成されているように、このクエリは2つの結合を使用します。
ユーザーにサービスを提供するための非正規化された読み取り専用レコードを作成します。
- 外部キーを使用して、大きなテーブルから1,000〜40,000レコードのいずれかを選択します。
- 文字列id列を持つ最新のレコードで他の4つのテーブルのそれぞれと結合します。
- 結果を非正規化テーブルに挿入します。
- これらのレコードは、フロントエンドがユーザーに情報を表示するために使用されます。
- 現在作成されているように、このクエリは4つの結合を使用します。
ユーザーからのリクエストを処理するリアルタイムのフロントエンドDBサーバーに結果をプッシュするバッチバックエンドデータベースで、これらの高価なクエリをそれぞれ実行する予定です。これらのクエリは定期的に実行されます。頻度はまだ決めていません。平均的なクエリは、おそらく1日に1回行うことができます。非正規化クエリは、より頻繁に、おそらく数分ごとに実行する必要があります。
これらの各クエリは現在、MySQLの「ビッグテーブル」に100Kレコードのデータセットを持つ非常にローエンドのマシンで数秒で実行されます。私のスケーリング能力とスケーリングのコストの両方が心配です。
質問:
- このアプローチは健全に見えますか?全体像の観点から、明らかに問題はありますか?
- RDBMSは適切なツールですか、それともHadoopファミリのような他の「ビッグデータ」ソリューションを検討する必要がありますか?データは構造化されており、リレーショナルモデルにうまく適合しているため、RDBMSを使用する傾向があります。ただし、ある時点で、RDBMSを使用できなくなる可能性があるというのが私の理解です。本当?このスイッチが必要になるのはいつですか?
- うまくいきますか?これらのクエリは妥当な時間内に実行できますか?クエリ#1はおそらく数時間待つことができますが、クエリ#2は数分で完了するはずです。
- ハードウェアの観点から何を考慮すべきですか?RAMとCPUのボトルネックになる可能性があるのは何ですか?RAMにインデックスを保持することが重要だと思います。他に考慮すべきことはありますか?
- ある時点で、おそらくデータを分割して複数のサーバーを使用する必要があります。私のユースケースはすでにそのカテゴリにあるように見えますか、それともしばらくの間、1台のマシンを垂直方向にスケーリングできますか?これはデータの10倍で動作しますか?100倍?