私は次のように独自のシャーディング戦略を構築しようとしています。BOXESテーブルとITEMSテーブルがあり、各ボックスに複数のアイテムを含めることができると仮定します。同じBOXに関連するアイテムを1台のマシンに入れました。
box_id主キーには次のものが含まれます:(server_type
例:100)+ shard_id
+total_amount_of_boxes_per_user
はtotal_amount_of_boxes_per_user
ユーザーごとにユーザーのデータベースに保存され、ユーザーが新しいボックスを挿入するたびに1つずつインクリメントします。
サーバータイプ100は、ボックス+アイテムデータを格納するサーバーのリストとラインナップされます。このserver_type->shard関係のリストは中央の場所にあるはずです。私は、それをDynamoDBにドキュメントとして保存することを考えました。
DynamoDBの設定ドキュメント:
boxitems_servers[
{shard_id: 1, is_locked: false, hostname: 127.0.0.1}
{shard_id: 2, is_locked: false, hostname: 127.0.0.2}
{shard_id: 3, is_locked: false, hostname: 127.0.0.3}
{shard_id: 4, is_locked: false, hostname: 127.0.0.4}
]
データベースとアプリケーション層をモデル化したので、結合する必要はありません。せいぜい、DBに対していくつかのクエリを実行しますが、それらはサーバー側とクライアント側でキャッシュされます。MySQLを使用しており、ASP.NET4.5でアプリケーションを開発しています。
ユーザーがページにアクセスしたとき:
http://domain.com/1000014294967295
そのデータを読み取り、分割して、次のデータを取得できます。
- server_type = 100
- shard_id = 001
- total_amount_of_boxes_per_user = 4294967295(もちろん、はるかに少ない場合もありますが、整数値です)
DynamoDBからboxitems_serversドキュメントを取得し、server_typeのドキュメントのみを取得します。だからserver type 100 = boxitems_servers
。
ホスト名に基づいてシャードに接続し(資格情報はweb.configにあります)、主キーに基づいてデータをクエリします1000014294967295
。
is_locked: true
構成ドキュメントを挿入することで、特定のシャードをロックすることを決定できます。したがって、データを書き込む(更新しない)場合、ロックされていないシャードにのみ書き込みます。
shard_id%number_of_active_shardでMODULUを使用してデータを書き込み、データを複数のシャードに均等に分散します。
ここで、別のAmazon RDSデータベースを追加して水平方向にスケーリングする場合は、前に作成したAmazon AMIを介して同じスキーマでデータベースを作成し、サーバーをシャードリストに追加します。
boxitems_servers[
{shard_id: 1, is_locked: false, hostname: 127.0.0.1}
{shard_id: 2, is_locked: false, hostname: 127.0.0.2}
{shard_id: 3, is_locked: false, hostname: 127.0.0.3}
{shard_id: 4, is_locked: false, hostname: 127.0.0.4}
{shard_id: 4, is_locked: false, hostname: 127.0.0.5} <- NEW ONE
]
Amazon RDSにはすでにレプリケーションがあるので、それについて心配する必要はありません。戻る/復元も簡単です。
私の唯一の懸念は:
- データが均等に分散されていないことを考慮して、異なるシャードからページングされたデータを読み取る
- ソートされたデータの取得
必要なもの:その戦略についてあなたの意見が欲しいです。Amazon RDSを使用して、マシンを追加し、構成ファイルを更新することで簡単に拡張できる、ある種のプラグアンドプレイアーキテクチャを作成したいと考えています。これは、ダウンタイムなしでオンザフライで機能するはずです。
私はそこにあるすべてのそれらの高価なソリューションに数千ドルを払いたくありません。私は、アプリケーションのニーズに合う優れたシャーディングソリューションを構築できると信じています。このソリューションには、いくつかのテーブルと、結合を防ぐためにすでに非正規化されているテーブルがあります。Amazon RDSは、私が必要とするレプリケーションをすでに提供しています。
論理的なシャードを作成することもでき、各shard_idを変更して別のDBマシン(IPアドレス)を指すようにすることもできますが、「リーフ」にクエリを実行すると、そこにデータが見つからない場合は、上に移動してクエリを実行する必要があります。データが見つかるまで、他のシャード。
これは、制限のある優れたシャーディング戦略につながる可能性があると思いますが、トラフィックの多いWebサイトではかなりうまく機能する可能性があります(私は思います)。