4

私は次のように独自のシャーディング戦略を構築しようとしています。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サイトではかなりうまく機能する可能性があります(私は思います)。

4

1 に答える 1

4

ノードを追加すると、すべてのレコードを別のデータベースに移動する必要があるため、MOD 戦略が最適だとは思いません (これは悪いオプションだと理解しています)。

より良いオプション (Cassandra のようなもの) は、キーをハッシュし、キースペース全体をチャンクに分割することです。

例として、ハッシュが 16 進数で 0 から FFFF までの回答を返す場合 (これは完全な md5 または sha1 である必要があります)

  • ノード 1 で 0 から 0FFF まで。
  • ノード 2 で 1000 から 4FFF まで
  • ノード 3 で 5000 から 8FFF まで
  • ノード 4 で 9000 から CFFF まで
  • ノード 5 の D000 から FFFF まで

これは、単一のレジスターを探し、そのノードでのみ要求し、さらにレジスターが必要な場合はすべてのノードを要求することになるためです。データを見つけるためのキーとして何を選択したかによって異なります (pk と一致する必要はありません)。

さらにノードを追加する必要がある場合は、たとえばノード 3 にあるものを分割するだけで、上記の例では、5000 から 6FFF がノード 3 に残り、7000 から 8FFF が新しいノード 6 に移動します。

于 2013-03-24T19:37:34.283 に答える