データノード設定時のポイント!
データノード詳細
MySQL Cluster構築においてポイントとなるのは、なんと言ってもデータノードです。データノードを上手に構築するためには、その特性や基本的な仕組みを理解しておく必要があります。今回はまずデータノードの仕組みについて簡単に説明し、それから各オプションの意味と設定のポイントについて説明しますので、参考にしながらconfig.iniを書き換えてみてください。
MySQL Clusterはシェアードナッシング型の分散データベースです。シェアードナッシングとは「何も共有しない」≒「共有ストレージがない」という意味で、MySQL Clusterでは各データノードが分散してデータを格納します。テーブルのデータは行ごとに各データノードに割り振られます。
つまり「第1回:ここが新しい!MySQL 5.1(http://www.thinkit.co.jp/article/95/1/)」で説明した「水平パーティショニング」の技術が、データの分散において内部的に使われているのです。MySQL Clusterにおけるパーティションはノード数と同じです。パーティショニングは主キーの値によって行われます。よって、どのノードにどの行があるかは主キーで判別できる仕組みになっています。
各パーティションが1つのノードだけにしか存在しないとなると、あるノードがクラッシュしただけでパーティションが1つアクセスできなくなってしまいます。それではクラスタは使い物になりません。
そこで、MySQL Clusterではパーティションを複数のノード上に複製するようになっています。複製の数はNoOfReplicasオプションで指定します。指定できる数値の範囲は1~4です。1を指定すると複製なしということになり、冗長性がないため実用的ではありません。通常は2を指定します。3以上は機能としては備わっているのですが、実際の使用例はほとんどありません。
データノードは、お互いの複製を持ち合うためにノードグループというものを形成します。ノードグループに属するデータノードの数は、NoOfReplicasと同じです。すなわち各データノードはNoOfReplicasと同じ数だけのパーティションを格納していることになります。ノードグループの数はノード数をNoOfReplicasで割ったものに等しくなります。また、使用できるデータ容量(メモリ容量)も、データノードの合計をNoOfReplicasで割ったものに等しくなります。
データノード数とNoOfReplicasは後から変更できません。各ノードの搭載メモリを増やすことで容量を拡大することは可能ですが、ノード数には少し余裕を持たせておくといいでしょう。
使用するメモリ量
MySQL Clusterが使用するオプションとして「IndexMemory」と「DataMemory」を紹介します。これらのオプションは、各データノードが使用するメモリ量をコントロールするためのものです。それぞれ割り当てるメモリサイズを指定します。
MySQL Clusterでは、データの一意性を保証するために、主キーとユニークキーには例外なくハッシュインデックスが用いられます。そのための領域がIndexMemoryです。消費するメモリ量は、1行あたり25バイト+主キーのサイズです。主キーが32バイトより大きい場合には、さらに8バイト余分に必要になります。このような事情があるため、MySQL Clusterでは主キーの選択は慎重に行う必要があります(主キーを明示的に定義しない場合には、主キーが内部的に作成されます)。
DataMemoryには、データそのものと範囲検索用インデックスの情報が格納されます。ハッシュインデックスは、ハッシュ値を用いて高速なルックアップを行えるのですが、ハッシュはその性質上、等価比較しかできないため、ハッシュインデックスから2つの値のうちどちらが大きいかということは分かりません。
そのためMySQL Clusterには、ハッシュインデックスのほかにオーダードインデックス(Ordered Index)というインデックスがあります。オーダードインデックスではカラムの値が順番に並んでいるので、範囲検索が可能です。オーダードインデックスは、1行あたり10バイト程度のメモリ領域が必要です。
MySQL Clusterの主キーには、ハッシュインデックスとオーダードインデックスの両方が作成されます。これにより、高速なルックアップと範囲検索の両方が可能になっています。ただし、2つのインデックスを持つことはその分メモリを多く消費することを意味します。2つのうち、オーダードインデックスは必要がなければ作成しないように指示することが可能です。オーダードインデックスの作成を防止するには、テーブル定義においてUSING HASHオプションを使います(詳細はマニュアルを参照してください)。
DataMemoryは、そのデータ構造を管理するためにいくつかのオーバーヘッドが存在します。詳細は割愛しますが、そのオーバーヘッドを含めた必要なメモリ容量を計算するのは非常に面倒です。そこで、MySQL Clusterには必要なメモリ量を算出するためのユーティリティーであるndb_size.plというPerlプログラムがあります。
これを使用すると、MySQLの既存のテーブルをMySQL Clusterに変換した場合、各IndexMemoryやDataMemoryなどのパラメータがいくつ以上必要なのかということを見積もることができます。システムのサイジングの際にはぜひ使用しましょう(動作させるには必要なPerlモジュールを追加する必要があります。詳細はマニュアルを参照してください)。
MySQL Clusterでは、このように大量のメモリを消費するため、ほかのプログラムが起動することなどにより、スワップアウトが発生すると動作に致命的な影響を与えてしまいます。スワップアウトを防ぐために、LockPagesInMainMemory=1を指定しましょう。
またテーブルごとにメモリ消費量の上限を設定したい場合には、MaxAllocateパラメータを使用しましょう。
MySQL Clusterでは、テーブルのメタデータを格納する領域も必要です。1つのオブジェクトが消費するメモリは少ないのですが、オブジェクトの数に比例してメモリ量も増えるので、非常に多くのテーブルオブジェクトを扱う場合にはサイジングが必要です。その場合、「MaxNoOfTables」「MaxNoOfOrderedIndexes」「MaxNoOfUniqueHashIndexes」「MaxNoOfAttributes」などのオプションを変更します。
後述しますが、これらの他にもデータノードごとに割り当てられるバッファなどがあります。次は、ディスクのレイアウト設計について説明します。