DockerでMySQLのリードレプリカを作成する | SEEDS Creators' Blog | 株式会社シーズ

DockerでMySQLのリードレプリカを作成する

Webサイト構築事業部の西村です

今回は、Docker環境でMySQLコンテナを2つ用意し、片方をマスターに、片方をリードレプリカにしてみようと思います

注意事項

この記事ではMySQLのレプリケーションの機能を利用します
レプリケーションについて解説はしませんので、詳しく知りたい方はこちらをご参考ください
https://dev.mysql.com/doc/refman/5.7/en/replication.html

ファイル構成

最終的にできるファイル構成は下記のようになります
あらかじめファイルを作っておきますと作業が楽になるかと思われます

/
┣ Docker/
┃┣ mysql_source/
┃┃┣ conf.d/
┃┃┃┗ mysql_source.cnf
┃┃┗ init_data/
┃┃ ┗ 001-GRANT_REPLICATION.sh
┃┗ mysql_read/
┃ ┣ conf.d/
┃ ┃┗ mysql_read.cnf
┃ ┗ init_data/
┃  ┗ 001-START_REPLICA.sh
┣ .env
┗ docker-compose.yml

各ファイル編集

/.env

.envには利用するユーザとパスワードを指定します
今回、ユーザは User パスワードは password としておきます

SOURCE_MYSQL_USER=user
SOURCE_MYSQL_PASSWORD=password

/docker-compose.yml

コンテナはMySQLを2台なので2台分の設定をします
やることは、imageでmysql:5.7の指定 volumes の指定と環境変数の指定のみです
初期で作成するデータベースはマスターにのみ指定しておけばOKです
必要に応じてポート等の設定はしてください

version: '3.8'
services: 
    mysql_source:
        image: mysql:5.7
        volumes:
            - ./docker/mysql_source/conf.d:/etc/mysql/conf.d
            - ./docker/mysql_source/init_data:/docker-entrypoint-initdb.d
        environment:
            MYSQL_DATABASE: test
            MYSQL_USER: ${SOURCE_MYSQL_USER}
            MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
            MYSQL_RANDOM_ROOT_PASSWORD: 1
    mysql_read:
        image: mysql:5.7
        volumes:
            - ./docker/mysql_read/conf.d:/etc/mysql/conf.d
            - ./docker/mysql_read/init_data:/docker-entrypoint-initdb.d
        environment:
            SOURCE_MYSQL_HOST: mysql_source
            SOURCE_MYSQL_USER: ${SOURCE_MYSQL_USER}
            SOURCE_MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
            MYSQL_RANDOM_ROOT_PASSWORD: 1

/docker/mysql_source/conf.d/mysql_source.cnf

レプリケーションに必要な設定を記述します
設定の必要な項目は下記に記載があります
https://dev.mysql.com/doc/refman/5.7/en/replication-howto-masterbaseconfig.html
https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-howto.html

各設定項目の内容です
log-bin … バイナリログの有効化
server-id … サーバの識別子 / 0以外でかつ一意しておく必要がある
gtid-mode … グローバルトランザクションIDモードをONにする
enforce-gtid-consistency … GTIDベースのレプリケーションで安全なステートメントのみがログに記録されるようにする

[mysqld]
log-bin
server-id=1
gtid-mode=ON
enforce-gtid-consistency=ON

/docker/mysql_read/conf.d/mysql_read.cnf

リードレプリカ側の必要な設定です

マスターにはない設定内容は以下の通りです
read_only … 書き込みを不可にする

[mysqld]
server-id=2
read_only
gtid-mode=ON
enforce-gtid-consistency=ON

/docker/mysql_source/init_data/001-GRANT_REPLICATION.sh

ここではリードレプリカからマスターに接続を許可するユーザを指定します
本来であれば別途アカウントを作るほうがいいのですが、開発用途なのですでにいるユーザを利用します

#!/bin/sh
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e"GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_USER'@'%';"

/docker/mysql_read/init_data/001-START_SLAVE.sh

ここではマスターの起動を確認したのちに、マスターの設定を行い、リードレプリカとして利用できるよう START SLAVE; を実行します

#!/bin/sh
until mysqladmin ping -h$SOURCE_MYSQL_HOST -u$SOURCE_MYSQL_USER -p$SOURCE_MYSQL_PASSWORD --silent; do
    sleep 1
done

mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
    CHANGE MASTER TO \
        MASTER_HOST = '$SOURCE_MYSQL_HOST', \
        MASTER_PORT = 3306, \
        MASTER_USER = '$SOURCE_MYSQL_USER', \
        MASTER_PASSWORD = '$SOURCE_MYSQL_PASSWORD', \
        MASTER_AUTO_POSITION = 1; \
    START SLAVE; \
"

ここまでで環境の準備は完了です
docker-compose up で起動させましょう
エラーが発生しなければ問題なく設定できているかと思います

動作確認

まず、マスターのMySQLサーバに入ります

docker-compose exec mysql_source mysql -uuser -ppassword -Dtest

そしてテーブルを作成し、データを入れてみます

mysql > CREATE TABLE test(
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
);
Query OK, 0 rows affected (0.02 sec)
mysql > INSERT INTO `test`(`name`) VALUE ('SampleData');
Query OK, 0 rows affected (0.01 sec)

データの入力ができたら SELECT で確認しておきます

mysql> SELECT * FROM `test`;
+----+------------+
| id | name       |
+----+------------+
|  1 | SampleData |
+----+------------+
1 row in set (0.00 sec)

続いて、データが反映されているかを確認します
リードレプリカのMySQLサーバに入ります

docker-compose exec mysql_read mysql -uuser -ppassword -Dtest

その後先ほどと同じ SELECT を実行します

mysql> SELECT * FROM `test`;
+----+------------+
| id | name       |
+----+------------+
|  1 | SampleData |
+----+------------+
1 row in set (0.00 sec)

すると正常にデータが反映されていることがわかります

最後に

これで開発環境でもリードレプリカを用いて色々テストが行えるかと思います
この記事が少しでも参考になればうれしいです
最後までお読みいただきありがとうございました