伝統的なMaster-Slave構成という「悪夢」
以前、ECサイトのMaster-Slave構成のMySQLクラスタでトラブルが発生し、一晩中対応したことがあります。ハードウェアの故障でMasterサーバーが突然ダウンしました。予備のSlaveはありましたが、データの差異を確認し、手動でSlaveをMasterに昇格させ、アプリケーション側のIPを更新するのに30分以上かかりました。1分間に数百件の注文を処理するシステムにとって、30分のダウンタイムは収益面で致命的な打撃となります。
旧来のレプリケーションにおける最大の課題は、その手動性にあります。トラブル発生時には直接的な介入が避けられず、また非同期通信であるためにデータ紛失(データロス)のリスクも常に付きまといます。MySQL Group Replication (GR) はこれらの不安を解消し、真の自己修復(Self-healing)機能を提供するために登場しました。
MySQL Group Replicationの仕組み
本質的に、Group ReplicationはMySQLサーバーを一つの統合されたグループとして連携させるプラグインです。データの一方向送信ではなく、グループ内の各ノードがPaxosコンセンサスプロトコルを通じて「合意」を形成します。
トランザクションは、グループ内の過半数のノードが同意したときにのみ成功と見なされます。この仕組みにより、以下の2つの核となる価値が提供されます:
- 自動フェイルオーバー: ノードに障害が発生した場合、システムは10秒以内に新しいリーダーを自動的に選出します。深夜に飛び起きてコマンドを叩く必要はもうありません。
- データの一貫性: クラッシュ時のゴーストデータやトランザクションの消失を排除します。1台でもノードが稼働していれば、データは安全に保たれます。
実際に200GBのデータベースを運用した際、ネットワークインフラが安定した同一リージョン内であれば、レイテンシの増加はごくわずaか(通常5ms未満)であることを確認できました。
実践に向けた環境準備
多数決による合意形成メカニズムを安定させるため、最低3つのノードが必要です。このガイドでは、以下のIPアドレスを持つMySQL 8.0が動作する3台のVPSを使用します:
- ノード 1: 192.168.1.10 (mysql-1)
- ノード 2: 192.168.1.11 (mysql-2)
- ノード 3: 192.168.1.12 (mysql-3)
重要な注意点:Group Replicationでは、すべてのテーブルで InnoDB エンジンを使用し、かつ Primary Key(主キー) が必須です。主キーがない場合、一貫性を保護するためにGRによって書き込み操作が即座に拒否されます。
ステップ1:my.cnf設定ファイルの最適化
3つのノードすべてで、MySQLの設定ファイル(通常は /etc/mysql/mysql.conf.d/mysqld.cnf)を開きます。これがGroup Replicationを有効にするための骨組みとなります。
[mysqld]
# サーバー識別子 (ノード1は1、ノード2は2...)
server_id = 1
binlog_format = ROW
log_slave_updates = ON
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
# Group Replicationの設定
transaction_write_set_extraction = XXH64
loose-group_replication_group_name = "550e8400-e29b-41d4-a716-446655440000"
loose-group_replication_start_on_boot = OFF
loose-group_replication_local_address = "192.168.1.10:33061"
loose-group_replication_group_seeds = "192.168.1.10:33061,192.168.1.11:33061,192.168.1.12:33061"
loose-group_replication_bootstrap_group = OFF
# シングルプライマリモード (データ書き込みの安全性を確保)
loose-group_replication_single_primary_mode = ON
loose-group_replication_enforce_update_everywhere_checks = OFF
ポート 33061 のファイアウォールを必ず開放してください。これはノード同士が互いの稼働状況を確認するための専用通信チャネルです。
ステップ2:レプリケーション用ユーザーの設定
MySQLを再起動した後、同期を専門に担当する「郵便配達員」のようなユーザーを作成する必要があります。3つのノードすべてでMySQLにログインし、以下を実行します:
SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'super_strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE REPLICATION SOURCE TO SOURCE_USER='repl', SOURCE_PASSWORD='super_strong_password' FOR CHANNEL 'group_replication_recovery';
ヒント:SET SQL_LOG_BIN=0 コマンドを使用することで、ユーザー作成がバイナリログに記録されないようにします。これにより、ノードが連携を開始する際のデータ競合を防ぐことができます。
ステップ3:グループの初期化(ブートストラップ)
以下のコマンドは、ノード1でのみ実行してください。これが新しいグループを「誕生」させる操作です。
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;
performance_schema.replication_group_members テーブルをクエリしてステータスを確認します。MEMBER_STATE カラムが ONLINE と表示されていれば、グループは正式に稼働しています。
ステップ4:残りのノードを接続する
ノード2とノード3の参加は非常に簡単です。以下のコマンドを実行するだけです:
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
START GROUP_REPLICATION;
システムは自動的にノード1の既存データと照合します。差異がある場合、新しいノードは完全に同期されるまで自動的にデータをプルします。
運用における実践的なアドバイス
構築することと、安定して運用することは別物です。私が経験から学んだ3つの「血肉となる」注意点を挙げます:
- ネットワーク遅延: GRはネットワークのレイテンシに非常に敏感です。ノード間のPingが100msを超えると、システムがノードのダウンと誤認し、グループから頻繁に除外される可能性があります。
- ProxySQLの併用: アプリケーションをMySQLのIPに直接接続させないでください。ProxySQLを使用して、読み取り/書き込みトラフィックを自動的に振り分けます。Masterがダウンしても、ProxySQLはミリ秒単位で新しいMasterを認識します。
- バイナリログの制限: 継続的な同期により、バイナリログファイルは急速に肥大化します。ディスク容量の突然の枯渇を防ぐため、
binlog_expire_logs_secondsを3〜7日程度に設定することをお勧めします。
Lời kết
MySQL Group Replicationは単なる技術ではなく、運用チームに「安心」をもたらすものです。初期設定はMaster-Slaveよりも手間がかかりますが、自己修復能力とデータ保護のメリットは、その労力に見合う十分な価値があります。99.99%の可用性が求められるシステムを管理しているなら、今すぐGRの検証を始めてみてください。
