Distribution Awareness
提供:MySQL Practice Wiki
概要
Distribution Awarenessとは、MySQL Cluster 6.3から有効な機能で、データを保持しているデータノードをTCとして選択するためのテクニックである。
MySQL ClusterのSQLノードにおいてトランザクションを開始すると、SQLノードは一つのデータノードを「トランザクションコーディネータ」として選択する。そして、トランザクションの開始から終了までを、トランザクションコーディネータ(以下TC)がSQLノードに対する窓口となって対応するのである。
SQLノードはどのようにしてTCを選択するのだろうか?バージョン6.2ではラウンドロビン(順繰りに)でTCを選択する。特定のデータノードをTCとして選択したら、そのノードを立て続けに8回TCとして選択し、すると9回目は次のノードをTCとして選択する。そしてその次のノードを8回TCとして選択し・・・という具合だ。この方法はもちろん最適なノード選択法ではない。TCとして選択されたデータノードに目的の行が存在しなかった場合などは性能上のペナルティが発生するからだ。例えば次のようなクエリを考えよう。
mysql> SELECT ...略... FROM t1 WHERE ID=123456;
このクエリの何が問題なのだろうか?IDがPRIMARY KEY(以下PK)だとすると、ID=123456の条件に合致する行は1行だけである。テーブルt1のデータはPKのハッシュ値を元にして各ノードグループに水平パーティショニングで分散しているので、ID=123456の条件に合致する行を持っているノードグループは一組だけである。もし、TCが ID=123456の行を持っていたならば、このクエリはとても高速である。そうでない場合は、TC--->行を持っているデータノードという無駄なネットワークトラフィックが発生してしまう。そして、TCがID=12345の条件に合致する行を持っている確率は、データノードが増加するにつれ下がってしまう。つまり、データノードが増加すると無駄なネットワークトラフィックが増え、ネットワークがボトルネックになってしまうのである。
このような問題を解消するには、SQLノードがID=123456の行がどのデータノード上に存在するかを知っている必要がある。SQLノードがどのデータノード上に目的の行が存在するかを知るための仕組みが、Distribution Awarenessなのである。PK以外のカラムに対してDistribution Awarenessを利用するには、テーブル定義を少し工夫する必要がある。(デフォルトではPKによってパーティショニングされているため、PKに対する等価比較でSELECTする場合にはDistribution Awarenessが有効である。)具体的な例を挙げると、上記のクエリでDistribution Awarenessを利用するには次のようにPARTITION BY KEY句によって、明示的にパーティションを設定する必要がある。
mysql> CREATE TABLE t1 (...略..., PRIMARY KEY (ID)) ENGINE NDB PARTITION BY KEY (ID);
従って、ただ単にベンチマークツールを用いただけではDistribution Awarenessのメリットを享受することは難しいが、実際のアプリケーションで利用する場合や、チューニングを施した上でベンチマークを行う場合には有効な手法であると言える。また、Distribution Awarenessは、範囲検索などではその効果は得られない。(ハッシュ値を使った場合に出来る操作は等価比較だけで、範囲検索を行う事が出来ないからだ。)
このように、Distribution Awarenessはキーの値によってパーティション(データノード)を選択するという意味で、Partitioning Pruningに似た概念であると言える。
クエリで利用されていることの確認
Distribution Awarenessが有効利用されているかどうかは、SQLノードにおいてEXPLAINを実行することで確認できる。確認方法は至って簡単で、EXPLAIN PARTITIONS...である。
mysql> EXPLAIN PARTITIONS SELECT * FROM t3 WHERE a=10000; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | t3 | p0 | const | PRIMARY | PRIMARY | 8 | const | 1 | | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec)