MySQL Clusterのメモリサイズ見積もり

提供:MySQL Practice Wiki

移動: 案内, 検索


目次

概要

MySQL Clusterは非常に多くのメモリを必要とする。MySQL 5.1からディスクベースのものも使用できるようになったが、元々はデータとインデックスを全てRAMに保持するタイプのものであった。そのため、依然としてメモリを多く必要とするので、どのぐらいのメモリ量が必要なのかを見積もるのが非常に重要である。

最大データ量

MySQL Clusterが保持できるデータ量は以下の式で計算出来る。

DataMemoryパラメータ × ノード数 ÷ NoOfReplicasパラメータ

例えば各ノードのDataMemoryが10GB、データノード数が8、レプリカ数が2だとすると、40GBのデータを保持することが出来る。ただし、Ordered IndexはDataMemoryから割り当てられるので注意が必要である。

IndexMemoryとDataMemory

MySQL Clusterには2種類のメモリ領域が存在する。データメモリとインデックスメモリである。インデックスメモリにはハッシュインデックスが格納される。MySQL Clusterの主キーから計算されたハッシュ値により、高速なlookupを実装している。ハッシュインデックスはlookupを実行することはできるが、範囲検索(WHERE VALUE > 1000とか)を実行することが出来ない。範囲検索を実行するには、キーを順番に並べたOrdered Indexが必要となるが、インデックスメモリに格納されるのはハッシュインデックスだけで、Ordered Indexはデータメモリに格納される。

ndb_size.pl

既存のテーブルをMySQL Clusterに移行する際はndb_size.plユーティリティプログラムが便利である。データおよびインデックスを格納するのに必要なデータ容量を、テーブルごとに自動的に見積もってくれる。しかも出力結果はHTMLなので見やすい。詳細は以下のマニュアルページを参照のこと。

マニュアル
http://dev.mysql.com/doc/refman/5.1/ja/mysql-cluster-utilities-ndb-size.html

手計算による見積もり

MySQL Clusterには様々なオーバーヘッドが存在するので、データそのもの以上に多くのメモリを消費する。容量の見積もりをする場合には以下の点に注意されたい。

レコードごとのオーバーヘッド

1行あたり16バイトのオーバーヘッドがある。

ページごとのオーバーヘッド

データメモリは32キロバイトごとのページに区切られて管理されている。そのページごとに128バイトのオーバーヘッドが存在する。

4バイト境界でのアライメント

MySQL Clusterはデータへ高速にアクセスするため、全てのデータは4バイト境界をもつようにアライメントされる。そのため、TINYINT、SMALLINT、MEDIUMINTなどはデータそのものは4バイト未満であるが、メモリ領域としては4バイト消費する。また、VARCHARやCHARなどで中途半端な長さを持つものも4バイト境界でアライメントがとられる。

可変長レコードに対するオーバーヘッド

MySQL Clusterの各レコードは、固定長部分と可変長部分に分けられる。可変長部分はデータメモリから別のページが割り当てられる。そして、固定長部分に可変長部分へのポインタが4バイト長で格納される。可変長カラムには4バイトずつのオーバーヘッドが生じる。

ハッシュインデックス(主キー)

レコードごとにおよそ31〜35バイトのメモリを消費する。領域はインデックスメモリから割り当てられる。

Ordered Index

インデックスごとに10バイト程度消費する。

ユニークインデックス

ユニークインデックスは非常に特殊である。MySQL Clusterは内部的に主キー以外のユニークインデックスを持つことができないので、隠れたテーブルを内部的に持つことによりユニークインデックスを実装している。(その隠れたテーブルはサポーティングテーブルと呼ばれる。)サポーティングテーブルは二つのカラムから構成される。一つは主キーであり、これは元のテーブルのユニークインデックスである。そしてもう一つのカラムには元のテーブルの主キーが格納される。

このように、ユニークインデックスを実装するにはもう一つのテーブルが必要となり、そのテーブルには当然上記のオーバーヘッドが全て適用されるので非常に非効率的である。

USING HASH

主キーやユニークインデックスのサポーティングテーブルは暗黙的にハッシュインデックスとオーダードインデックスが作成される。カラム値の一意性を保証したいだけの場合や、範囲検索を用いないことが分かっている場合にはオーダードインデックスを省略することが可能である。その場合にはカラムの定義においてUSING HASHオプションを使用するといい。

mysql> CREATE TABLE hoge (ID BIGINT UNSIGNED NOT NULL, .... PRIMARY KEY (ID) USING HASH) ENGINE=NDB;

DELETEとメモリの再利用

MySQL ClusterのテーブルにおいてDELETEを実行すると、それまで使用されていたメモリは同じテーブルでしか再利用することが出来ないという制限がある。一度テーブルが大きく成長してしまうと、いくらレコードを削除しても利用可能な領域が増えることがない。メモリを解放して他のテーブルから利用可能な状態にするには、以下のいずれかを実施する必要がある。

  1. DROP TABLEまたはTRUNCATE TABLE
  2. ローリングリスタート

ツール

Web経由でconfig.iniを記述するのを助けてくれるツールがある。是非使おう。

Configuration Tool for MySQL Cluster
http://www.severalnines.com/config/
個人用ツール