メタデータの末尾にスキップ
メタデータの先頭に移動
Icon

This section describes some of the more sophisticated controls that are available for managing data distribution. The default behavior for replicas and distribution is sufficient for many workloads.

By default, ClustrixDB uses a hash-based algorithm to distribute data. In addition, ClustrixDB enables you to control data placement in the cluster. 以下の章では、デフォルトのやりかたを説明し、データ分散を設定する方法を教えます。

Icon

以下の助言は一般的なものです: 最適化戦略を選択する時は常にアプリケーションに特有の負荷を考慮してください。

このトピックの例は、以下のテーブルに基づいています。

CREATE TABLE user_posts (
  post_id int AUTO_INCREMENT,
  user_id int,
  posted_on timestamp,
  data blob,
  KEY (user_id, posted_on)
);
Icon

デフォルトのデータ分散

By default, ClustrixDB uses all the columns of an index to distribute data. ハッシュ値は (user_id, posted_on) について計算されます。両方の列上の正確な制約を指定するクエリについて、データベースはクラスタ内のどのノードを使用するかを決定します。

しかし、以下のクエリを考えてみましょう:

SELECT post_id, posted_on, data
  FROM user_posts
 WHERE user_id = 2
   AND posted_on < '10-11-2009'
 ORDER BY user_id, posted_on
 LIMIT 20;


posted_on 列には、正確な(均等)制約はありません。クラスタはそのような列に対して全てのありえる場所を検索しなければなりません。その結果、クエリのパフォーマンスとスケーラビリティは低くなります。クラスタはまだインデックスの順番を利用しそれぞれのノードで制限を適用することができますが、クエリは特定のユーザについて何もデータを持たないノードに行くかも知れません。

しかしながら、もしクエリが複数のユーザ間で共通のプロパティをもつ投稿を見つける必要がある場合には、複数のノードでクエリを評価することは都合がいいかも知れません。そのようなクエリは複数のノードを並行して使用し、とても計算を高速化します。たとえクエリが複数のノードに行く必要があったとしても、DBMSは最適化を続け、全体のクエリの評価のコストを下げるためにそれぞれのノードの限界を下げます。

データ分散の設定

データ分散を制御するために、複数の行キーのどのキーをデータ配置のために使われるかを定義することができ、インデックス単位分散に使われるキーの数を指定することができます。データ分散を設定するには、DISTRIBUTE節を指定します。例えば、ハッシュの最初の行に制限するには、以下のコマンドを発行します:

CREATE TABLE user_posts (
  post_id int AUTO_INCREMENT PRIMARY KEY,
  user_id int,
  posted_on timestamp,
  data blob ,
  KEY (user_id, posted_on) DISTRIBUTE=1
);


インデックスの両方の行を使う代わりに、クラスタは最初の行だけを使います。このレイアウトは一つのノード上に特定のユーザの全ての投稿を配置します。そしてクラスタは興味のあるデータを持つそのノードだけを調査する必要があるでしょう。データ分散のためにハッシュ化された列は隣接しているに違いありません; つまり、列をスキップすることはできません。

例えば、三つの列のインデックス(a,b,c)について、bをスキップして(a,c)を分散することはできません。次のものが有効です: (a), (a,b) あるいは (a,b,c)。

インデックスが極度に偏っていれば、インデックスの分散も同じように偏っているでしょう。分散を等しくするために、インデックスの中の列の数より一つ大きなDISTRIBUTE値を使用してください; 例えば:

CREATE TABLE user_posts (
  post_id int AUTO_INCREMENT PRIMARY KEY,
  user_id int,
  posted_on timestamp,
  data blob,
  KEY (user_id, posted_on) DISTRIBUTE=3
);


このやり方は分散をテーブルのプライマリキーに基づかせ、均等な分散を確実にします。ハッシュ値は(PK, user_id, posted_on) で計算されます。このやり方の短所は全てのクエリがインデックス内の全てのスライスに一斉送信されるに違い無いということです。

Icon

前の例で注意したように分配にプライマリキーを含めるためにDISTRIBUTE節を使う代わりに、グローバル変数distribute_include_primary_keyを使うことができます。これはDISTRIBUTEが指定されない場合にデフォルトとして使われます。分配にプライマリキーを含めるには、変数にtrue(デフォルトはfalse)を設定します。

プライマリキーとインデックスの分配の修正

テーブルが作成された後でプライマリキーの分配を修正するには、以下のようにALTER TABLEコマンドを発行します:

mysql> ALTER TABLE <table_name> PRIMARY KEY DISTRIBUTE=N;

混合(複数カラム) プライマリキーについて、分散のカウントはキーを構成するカラムの数を超えることはできません。


テーブルが作成された後でインデックスの分配を変更するには、以下のようにALTER TABLEコマンドを発行します:

mysql> ALTER TABLE <table_name> [SLICES=n][,INDEX <index_name> [DISTRIBUTE=n] [SLICES=n]][,INDEX <index_name> [DISTRIBUTE=n] [SLICES=n]];

ユーザがインデックスの分配を変更する時に、デフォルトでシステムは多数の小さなスライスを作成するかも知れません。SLICES 引数はシステムのデフォルトの挙動を上書きします。

スライスの最適な数を決定するには、以下のようにsystem.table_sizeとsystem.index_sizeを調べてください:

mysql> select * from system.table_sizes where Database = 'test';
+----------+----------------------------+-----------+
| Database | Table                      | Size      |
+----------+----------------------------+-----------+
| test     | a                          |    196608 |
| test     | aaron_1                    |    327680 |
| test     | aaron_2                    |    196608 |
| test     | ai                         |    327680 |
| test     | altercation                |    196608 |
| test     | analyzer_tmp               |    196608 |
| test     | b                          |    294912 |
...
 
mysql> select * from index_sizes where Database = 'test';
+----------+----------------------------+-------------------------------------------+-----------+
| Database | Table                      | Index                                     | Size      |
+----------+----------------------------+-------------------------------------------+-----------+
| test     | a                          | __base_a                                  |    196608 |
| test     | aaron_1                    | __base_aaron_1                            |    327680 |
| test     | aaron_2                    | __base_aaron_2                            |    196608 |
| test     | ai                         | __idx_ai__PRIMARY                         |    327680 |
| test     | altercation                | __idx_altercation__PRIMARY                |    196608 |
| test     | analyzer_tmp               | __base_analyzer_tmp                       |    196608 |
| test     | b                          | __base_b                                  |    294912 |
| test     | bar                        | __idx_bar__PRIMARY                        |    393216 |
...

Size カラムはインデックスのバイト数です。テーブルとインデックスのために最適なスライスの数を計算する時に、もしテーブルが著しく成長することが予想される場合は、約1GB以下のスライスにするように努めてください。テーブルとインデックスが最低3つのスライスを持つようにしてください。

Modifying the Number of Replicas for a Table

When creating a table, you can explicitly specify the number of replicas

CREATE TABLE <table_name> <column_defs> [REPLICAS = n]

If no value is specified for the number of replicas, Clustrix creates tables with a default number of replicas = 2. The default number of replicas can be configured via the global variable default_replicas. Once a table has been created, you can use an ALTER statement to modify the number of replicas:

ALTER TABLE <table_name> REPLICAS = <number of desired replicas>

This will automatically copy your data across slices and nodes so that the desired number of replicas are created as part of the DDL operation. You can view the number of replicas that a table has via SHOW CREATE TABLE.

Lazy Protect

You can also create replicas in an asynchronous fashion by using the ALTER TABLE command with the LAZY PROTECT option. 

Example of LAZY PROTECT
ALTER TABLE <table_name> LAZY PROTECT [REPLICAS = n]

Lazy protect allows the SQL command to return instantly, and the reprotection to be performed in the background by the rebalancer. For larger tables, this could result in a longer reprotection time, but less immediate impact to the database. If no value for the number replicas is supplied, the default value will be applied. 

Icon

While the protection process is in progress, there may be warnings in the logs about ALERT PROTECTION_LOST WARNING. These will no longer appear once the reprotect process is complete.

Icon

To optimize performance of bulk data load:

  1. Create tables with REPLICAS = 1 (and no secondary indexes)
  2. Perform the data import
  3. Create secondary indexes
  4. ALTER TABLE <table_name> LAZY REPROTECT REPLICAS = <number of desired replicas>

To track progress of a lazy reprotect operation, see Managing the Rebalancer.

Replicas = Allnodes

This feature was introduced in v6.0 and offers the option to specify that every node should maintain a full copy of the table.

Allnodes is best applied to tables that:

  • are relatively small, are written to infrequently (e.g. metadata lookup tables)
  • are used frequently in joins to other, larger tables. 

Since copies of an Allnodes table is maintained on each node, writes are expensive. The result of Replicas = Allnodes is that Clustrix is able to utilize local copies of an allnodes table to minimize the cost of joining to larger tables. 

Caveats of Replicas = Allnodes

  • Replicas = Allnodes should not be applied to tables that take frequent writes
  • Replicas = Allnodes cannot be used in conjunction with partitioned tables
  • Specifying Replicas = Allnodes cannot be used in conjuction with LAZY PROTECT

Allnodes usage

例:

CREATE TABLE foo (
     one INTEGER,
     two CHAR(256)
  ) REPLICAS = ALLNODES;
ALTER TABLE bar REPLICAS = ALLNODES;

 

 

  • ラベルなし
TOP
inserted by FC2 system