5分でできる:DockerでMySQL NDB Clusterを試す
退屈な理論を読み進める代わりに、まずは手元のマシンでクラスターを構築してみましょう。Docker Composeを使えば、1つのManagement Node(管理)、2つのData Nodes(データ保存)、1つのSQL Node(クエリ処理)からなる分散システムをシミュレートできます。
# docker-compose.yml のサンプルファイル
version: '3.8'
services:
management:
image: mysql/mysql-cluster:8.0
command: ndb_mgmd
networks:
- cluster
ndb1:
image: mysql/mysql-cluster:8.0
command: ndbd
networks:
- cluster
depends_on:
- management
ndb2:
image: mysql/mysql-cluster:8.0
command: ndbd
networks:
- cluster
depends_on:
- management
mysql-node:
image: mysql/mysql-cluster:8.0
command: mysqld
networks:
- cluster
environment:
- MYSQL_ROOT_PASSWORD=password
depends_on:
- management
networks:
cluster:
docker-compose up -dを実行するだけで、分散データベースクラスターが立ち上がります。NDBCLUSTERエンジンを指定してテーブルを作成すると、データは自動的にシャーディング(分割)され、手動設定なしでndb1とndb2に分散保存されます。
なぜ従来のMaster-Slave構成では不十分なのか?
構築を始めたばかりのエンジニアの多くは、Master-Slaveレプリケーションだけで十分安全だと誤解しがちです。実際には、Masterに障害が発生した場合、手動でのフェイルオーバー(切り替え)に30秒から数分かかることが一般的です。稼働率99.999%(ファイブナイン)の基準では、年間のダウンタイムは最大5.26分しか許されません。Master-Slave構成でこの数字を達成するのは困難です。
MySQL NDB Clusterは、**単一障害点(No Single Point of Failure)**の問題を根本から解決します。システムはノードの停止を自動的に検知し、数秒以内にクエリを再ルーティングします。深夜に物理サーバーの1台がダウンしても、安心して眠りにつくことができます。
NDB Clusterの「3つの柱」となるアーキテクチャ
スムーズに運用するためには、以下の3種類のノードの役割を理解する必要があります。
- Management Node (ndb_mgmd): 司令塔の役割を果たします。クラスター全体の構成情報の保持と各ノードの状態管理を行います。このノードがオフラインになっても、クラスター自体は動作し続けますが、構成の変更はできなくなります。
- Data Nodes (ndbd): データの保存と処理を直接行います。NDBは超低レイテンシを実現するためにデータをRAM上に優先的に保存し、その後、安全性のためにディスクに書き込みます。
- SQL Nodes (mysqld): アプリケーションとのインターフェースです。SQLコマンドを受け取り、クラスター言語に変換してデータノードからデータを取得します。負荷に応じてSQLノードを好きなだけスケールアウトさせることが可能です。
1億レコードを扱う実際のプロジェクトでは、シングル構成のMySQLからNDB Clusterに移行したことで、複数ノードでの並列読み書きが可能になり、システムの処理能力が4倍向上しました。
実践的な設定ガイド
Ubuntuを実行する4台のサーバー(`.10`:管理、`.11` & `.12`:データ、`.13`:SQL)があると仮定します。
1. 管理ノードのセットアップ
サーバー 192.168.1.10 に config.ini ファイルを作成します:
[ndbd default]
NoOfReplicas=2
DataMemory=2G
IndexMemory=512M
[ndb_mgmd]
HostName=192.168.1.10
DataDir=/var/lib/mysql-cluster
[ndbd]
HostName=192.168.1.11
DataDir=/usr/local/mysql/data
[ndbd]
HostName=192.168.1.12
DataDir=/usr/local/mysql/data
[mysqld]
HostName=192.168.1.13
2. SQLノードをクラスターに接続する設定
サーバー .13 で my.cnf を編集し、NDBエンジンを有効にします:
[mysqld]
ndbcluster
ndb-connectstring=192.168.1.10
[mysql_cluster]
ndb-connectstring=192.168.1.10
実際のプロジェクトから得た「血肉となる」教訓
NDB Clusterの構築自体は難しくありませんが、安定運用させるのは別問題です。以下に3つの重要な注意点を挙げます:
1. NDBエンジンの指定忘れ
デフォルトでMySQLはInnoDBを使用します。テーブル作成時に ENGINE=NDBCLUSTER を指定し忘れると、データは1つのSQLノード内にローカル保存されてしまいます。これでは高可用性(High Availability)機能が全く意味をなさなくなります。
2. データノードのRAM不足問題
NDB Clusterはメモリ優先(In-memory)データベースです。すべてのインデックスと主要な稼働データはRAM上に配置されます。RAMがいっぱいになると、システムは即座にINSERT/UPDATEコマンドを拒否します。急激なデータ増加に備え、常に25〜30%程度のRAMの空き容量を維持するようにしてください。
3. ネットワークレイテンシは最大の敵
各ノードはネットワーク経由で常にデータを同期しています。スイッチのレイテンシが高い、あるいはネットワークケーブルが1Gbps止まりだと、パフォーマンスのボトルネックになります。レイテンシを1ms以下に抑えるため、10Gbpsネットワークの使用と、各ノードを同一スイッチ内(ローカルネットワーク)に配置することを推奨します。
NDB Clusterが最適解ではないケース
以下のようなケースでは、無理にNDB Clusterを採用すべきではありません:
- 複雑すぎるJOINクエリ: NDBは複数ノードにまたがるJOIN処理が、従来のInnoDBに比べて非常に低速です。
- ハードウェア予算の制限: 安定稼働には最低3〜4台のサーバーが必要であり、コストは決して安くありません。
- 膨大だがアクセス頻度の低いデータ: テラバイト級の「コールドデータ」をすべてRAMに詰め込むのは、非常に大きなコストの無駄です。
このガイドが、高可用性データベースシステムの設計に役立つことを願っています。NDB Clusterは最初は習得が難しいかもしれませんが、絶対的な安定性を求めるアプリケーションにとって、非常に強力な盾となるはずです。

