HyperDB でお手軽に WP の MySQL サーバを複数分散

WordPress で DB サーバを分散処理したいとか思ったことありませんか?
以前、MariaDB Galera Cluster を使って DB サーバをクラスター構成にする方法を解説しました。
しかし、ここではもっと簡単に MySQL のマスター/スレーブ構成によるレプリケーション機能を使って読み込み先と書き込み先の DB を分ける手法について解説します。
Amazon RDS のリードレプリカ機能を使えば、WordPress のプラグイン(正確にはドロップイン)を設置して、ちょっと設定するだけですが、ここでは一応 MySQL でマスター/スレーブ構成のレプリケーションする方法についても解説します。

構成は、上のアイキャッチのような感じです。

MySQL でマスター/スレーブ構成のレプリケーション

この構成によるメリットは

  • スレーブサーバによるリアルタイムでのデータのバックアップ
  • マスターもしくはスレーブのどちらか片方が落ちた場合でも、どちらか片方で処理させダウンタイムを短くすることができる
  • read と write を分散させることによる処理の負荷分散

この解説の中でマスター/スレーブサーバは、それぞれ以下の IP アドレスで稼働しているとします。

  • マスター : 192.168.0.1
  • スレーブ : 192.168.0.2

また MySQL サーバは、すでにインストール済みであるとします。

マスター側の設定

マスター側で実行されたクエリはすべてバイナリログに書き出され、そのバイナリログをスレーブ側に転送して適用することで複数台の MySQL サーバ間でのデータの同期を取ります。
そのため、マスター側ではバイナリログを保存するように設定する必要があります。

マスター側の my.cnf で以下のように設定しましょう。

[mysqld]
log-bin
server-id=1

log-bin はバイナリログを取るように指定しています。
server-id は識別用の ID で任意の数値で良いのですが、スレーブサーバと重複しない値を指定します。
ここでは 1 を指定しています。
設定したら変更を適用するために MySQL サーバを再起動してください。

次にスレーブ側から、マスター側に接続するための MySQL ユーザーを作成します。
このユーザーは REPLICATION SLAVE 権限を持っている必要があります。
192.168.0.2 からユーザ名 repl、パスワード password で REPLICATION SLAVE 権限で接続するためのユーザを作成するには、マスター側の MySQL サーバで以下の SQL 文を実行してください。

mysql> GRANT REPLICATION SLAVE ON *.* TO
   repl@192.168.0.2 IDENTIFIED BY 'password';

次にマスターのデータベースをスレーブにコピーするために mysqldump でダンプします。
まずは、ダンプ中に更新されないようにすべてのテーブルへの書き込みをロックします。

mysql> FLUSH TABLES WITH READ LOCK;

テーブルをロックしたら、現在のバイナリログの状態を調べます。

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |        7 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

現在のバイナリログのファイル名 ( File ) と、バイナリログ内の現在位置が表示されるのでメモっておいてください。

次に mysqldump を使ってすべてのデータをダンプします。

$ mysqldump -u root -p --all-databases --lock-all-tables > dbdump.sql

これで dbdump.sql というファイルに全データベースのダンプファイルが作成されます。

データベースのダンプを取ったら、ロックを解除することを忘れずに。

mysql> UNLOCK TABLES;

スレーブ側の設定

次にスレーブ側の設定を行います。

まずは my.cnf を設定して、マスターと違う server-id を設定します。ここでは 2 に設定しています。

[mysqld]
server-id=2

変更を有効にするために MySQL サーバを再起動してください。

続いて、先ほどマスターで取ったデータベースのダンプをインポートします。
dbdump.sql は scp 等で、マスター側のサーバからコピーしておいてください。

$ mysql -u root -p < dbdump.sql[/text]

次にスレーブ側の mysql サーバに接続して以下の SQL 文を実行します。
[text]mysql> CHANGE MASTER TO
        MASTER_HOST='192.168.0.1',
        MASTER_USER='repl',
        MASTER_PASSWORD='password',
        MASTER_LOG_FILE='mysql-bin.000001',
        MASTER_LOG_POS=7;

ここで、それぞれの値は以下の通りです。適宜、環境に合わせて修正してください。

  • MASTER_HOST : マスター側のホスト名、もしくは IP アドレス
  • MASTER_USER : マスター接続に使用するユーザー名
  • MASTER_PASSWORD : マスター接続に使用するユーザーのパスワード
  • MASTER_LOG_FILE : SHOW MASTER STATUS で確認した File
  • MASTER_LOG_POS : SHOW MASTER STATUS で確認した Position

ここまで設定したら、スレーブ側でレプリケーションを開始します。

mysql> START SLAVE;

マスター/スレーブで文字コード等が違う場合はエラーが発生してレプリケーションが開始されないかもしれません。
エラーが発生したら my.cnf の内容を見比べてみてください。
また、スレーブからマスターへは MySQL のポートが空いてないと接続できません。
エラーで接続できない場合はファイアウォールの設定等を見直してみましょう。

HyperDB による読み書きの分散処理

ここまでで MySQL サーバをレプリケーションできるようになったので、次は WordPress のプラグイン(正確にはドロップイン) HyperDB を使って書き込み先をマスターに、読み込み先をスレーブに向けるように修正します。
WordPress の wp-config.php を修正したことがある人ならわかると思いますが WordPress では通常接続先の MySQL サーバは一つしか指定できません。
これを複数の MySQL サーバに分散できるようにするドロップインが HyperDB です。

まずは公式プラグインディレクトリから HyperDB をダウンロードしてきます。
HyperDB
これは通常のプラグインでは無く、ドロップインという形式の追加機能です、ダッシュボードからはインストールできないので注意してください。

まず、以下のようなファイルを作成して db-config.php と言う名前で wp-config.php と同じディレクトリに配置してください。

<?php
// Master ( read and write )
$wpdb->add_database(array(
        'host'     => '192.168.0.1',
        'user'     => DB_USER,
        'password' => DB_PASSWORD,
        'name'     => DB_NAME,
        'write'    => 1,
        'read'     => 2,
));

// Slave ( read only )
$wpdb->add_database(array(
        'host'     => '192.168.0.2',
        'user'     => DB_USER,
        'password' => DB_PASSWORD,
        'name'     => DB_NAME,
        'write'    => 0,
        'read'     => 1,
));

最初の $wpdb->add_database() では、マスター側を読み書き用の MySQL サーバとして設定しています。
パラメータの仮想配列中の write は DB 書き込みの優先度、read は DB 読み込みの優先度です。
これを 0 に設定すると書き込み、または読み込みはそのサーバに対して行われません。

二番目の $wpdb->add_database() では、スレーブ側を読み込み専用の MySQL サーバとして設定しています。
write パラメータが 0 に設定されているため、このサーバに対して書き込みは行われません。

他にも timeout を設定したり、マルチサイトの各サイトで使用するテーブルを別サーバにわけたりなどの設定ができます。
詳しくはダウンロードしてきた hyperdb.zip 内に同梱されている readme.txt や db-config.php を読んでみてください。

次にダウンロードしてきた hyperdb.zip を展開した中に含まれている db.php を wp-content/ 直下に置きます。

これだけで HyperDB の設定は完了です。
マスターサーバを停止したりして、ちゃんと HyperDB が動いてるか確認してみましょう。

それでは、良い分散処理ライフを!

HyperDB でお手軽に WP の MySQL サーバを複数分散」への1件のフィードバック

  1. ほげ

    分散いいですね〜。
    ただwrite側専用の管理画面にvhostを立ててあげたり、readでもDB書き込みが必要なプラグインでは注意が必要だったりしますね。
    とはいえ、mysqlのデータがメモリやキャッシュに乗り切った時の速度は快感ですね!

    返信

コメントを残す

メールアドレスが公開されることはありません。