2

クライアントが特定の顧客のすべてのデータ (およびその顧客のデータのみ) を地理的に分散したデータベース サーバーに格納する必要がある状況を解決する方法を研究しています。

たとえば、顧客 ID 92 に関連するすべてのデータを除いて、すべてのデータをメイン クラウドのデータベース サーバーに格納する必要があります。これらのデータは、別の場所にある別のクラウドのサーバーに格納する必要があります。

私が取り組んでいるいくつかの制約により、これが少し難しくなっていますが、これまでのところ、MySQL Clusterが最良のアプローチのようです。

ただし、クエリの実行時にデータ ノードを選択する方法は不明です。たとえば、顧客 ID 92 のデータを必要としないクエリを送信した場合でも、他のクラウドのデータ ノードに ping を実行し、レイテンシが発生しますか?

MySQL Cluster は、クエリ中に検索するデータ ノードをどのように決定しSELECTますか? 特定のデータノードを無視できることをクエリで示唆する方法はありますか?

4

3 に答える 3

6

ああ..それはMySQL Clusterの仕組みではありません。

デフォルトでは、MySQL Cluster は PRIMARY KEY でデータを分割します。ただし、PRIMARY KEY の一部でユーザー定義のパーティショニングとパーティションを使用することは可能です。これは、関連するデータをまとめてグループ化し、1 つのパーティション内でデータの局所性を確保するのに非常に役立ちます。関連するデータは 1 つのパーティションに保持されるため、パフォーマンスを犠牲にすることなく 2 から 48 のデータ ノードにスケーリングできます。これは一定です。詳細については、http://dev.mysql.com/doc/refman/5.5/en/partitioning-key.htmlを参照してください。

デフォルトでは、API はクエリを送信するパーティションを決定するために、PRIMARY KEY (または主キーの定義済み部分) でハッシュ (md5 を使用する LH3* アルゴリズムを使用) を計算します。計算されるハッシュは 128 ビットであり、64 ビットがパーティションを決定し、64 ビットがパーティション上のハッシュ インデックス内の位置を決定します。ユーザーとして、どのノードがデータを持っているか (または誰がデータを保存するか) を正確に把握することはできませんが、実際にはそれは重要ではありません。

1 つの MySQL Cluster を 2 つのクラウドに分散し、データを分割することに関する元の質問について。データ ノードは相互に信頼性の高い低レイテンシ アクセスを必要とするため、相互の距離が 50 ~ 100 マイル未満でない限り、ノードを分散させたくないでしょう。

于 2013-07-01T07:05:42.980 に答える
4

最初に、Mysql Cluster は WAN 用に設計されていないことに注意してください。通常は、ノード間の伝搬遅延が 20 ミリ秒未満であることが最適です。

Mysql Cluster は、シャーディング (データ ノード間でデータを均等に分散) + レプリケーション (データのすべてのフラグメントを 2 回保存) を行います。

とてもシンプルなテーブルのように、

| test  | CREATE TABLE `test` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `v1` char(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=ndbcluster AUTO_INCREMENT=1871780 DEFAULT CHARSET=latin1

information_schema を確認すると、このテーブルのパーティションが表示されます

mysql> select partition_name,table_rows from information_schema.PARTITIONS where     table_name='test' and table_schema='test1';
+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0             |     518667 |
| p1             |     518900 |
| p2             |     517385 |
| p3             |     519050 |
+----------------+------------+
4 rows in set (0.02 sec)

パーティション p0,p2 はデータ ノード 1 を表し、p1,p3 はノード 2 を表します。データは PRIMARY KEY (または、現在主キーが定義されている場合は人工キー) に基づいて分散されます。

Select は、このパーティショニングに基づいて読み取るノードを選択するため、explain を使用する場合

mysql> explain partitions select id,v1 from test where id=1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: p3
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
        Extra: NULL
1 row in set (0.00 sec)

mysql> explain partitions select id,v1 from test where id=2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
   partitions: p2
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
        Extra: NULL

id=92 のレコードは 1 つのデータ ノード (地理的に分散したノードの場合もあります) からのみ読み取られますが、残念ながら id 92 だけではありません。

最善の方法は、顧客 ID 92 の別のテーブルを (別のノードに) 作成し、そのテーブル/ノードから読み取るようにアプリケーションを書き直すことです。アプリに対して透過的なソリューションを実現するには、 Mysql Proxyを使用できます。

于 2013-09-11T09:52:45.697 に答える
2

こんにちは、申し訳ありませんが、答えは「いいえ」です。MySQL クラスターはシャーディングと呼ばれることもありますが、実際にはそうではありません... PK によるすべてのテーブルからのデータの任意の分散であり、どのデータが一緒にアクセスされるか、すべてのアクセスとすべてのクエリまたはトランザクションにどのノードが必要かについては制御も考慮もされていません。

シャーディング、および優れたデータ分散ポリシーは、一緒にアクセスされるデータを同じデータベースに保持するものです。そのため、トランザクションがデータを必要とする場合、この 1 つの DB を使用することになり、処理 (結合、グループ) がプッシュされます。このデータベースに(データに近い、良い!)、他のデータベースは他のトランザクションを処理するために残されます(そしてたくさんあります........)。

したがって、一緒にアクセスされるデータを 1 つのデータベースに格納することで、次の 2 つのことが得られます。

  1. このデータを必要とし、それを 1 つのノードで見つけるクエリ/トランザクションの待ち時間が短縮されます
  2. クエリ/トランザクションは分散され、すべてのデータベースで乗算されません

だから私があなたの質問を理解していれば、これはあなたが達成したいことです.MySQL Clusterはそれを与えることができません.今のところ問題がなければ、データ/同時実行性/書き込みが成長すると戻ってきてあなたを噛むでしょう.....

おそらく古き良きシャーディングが必要か、今日ではシャーディングプロセスを実際に自動化するツールがあります(免責事項:私はScaleBaseで働いています。そのための1つのオプションで、必要なデータベースだけを使用し、ヒントもサポートしています(通常は必要ありません))。

于 2013-06-24T20:23:42.530 に答える