MySQL NDB Clusterの構築:稼働率99.999%を実現する「ゼロダウンタイム」データベースソリューション

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

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エンジンを指定してテーブルを作成すると、データは自動的にシャーディング(分割)され、手動設定なしでndb1ndb2に分散保存されます。

なぜ従来の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.10config.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ノードをクラスターに接続する設定

サーバー .13my.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は最初は習得が難しいかもしれませんが、絶対的な安定性を求めるアプリケーションにとって、非常に強力な盾となるはずです。

Share: