Webサイト構築事業部の西村です
今回は、Docker環境でMySQLコンテナを2つ用意し、片方をマスターに、片方をリードレプリカにしてみようと思います
注意事項
この記事ではMySQLのレプリケーションの機能を利用します
レプリケーションについて解説はしませんので、詳しく知りたい方はこちらをご参考ください
https://dev.mysql.com/doc/refman/5.7/en/replication.html
ファイル構成
最終的にできるファイル構成は下記のようになります
あらかじめファイルを作っておきますと作業が楽になるかと思われます
1/
2┣ docker/
3┃┣ mysql_source/
4┃┃┣ conf.d/
5┃┃┃┗ mysql_source.cnf
6┃┃┗ init_data/
7┃┃ ┗ 001-GRANT_REPLICATION.sh
8┃┗ mysql_read/
9┃ ┣ conf.d/
10┃ ┃┗ mysql_read.cnf
11┃ ┗ init_data/
12┃ ┗ 001-START_REPLICA.sh
13┣ .env
14┗ docker-compose.yml
各ファイル編集
/.env
.envには利用するユーザとパスワードを指定します
今回、ユーザは user パスワードは password としておきます
1SOURCE_MYSQL_USER=user
2SOURCE_MYSQL_PASSWORD=password
/docker-compose.yml
コンテナはMySQLを2台なので2台分の設定をします
やることは、imageでmysql:5.7の指定 volumes の指定と環境変数の指定のみです
初期で作成するデータベースはマスターにのみ指定しておけばOKです
必要に応じてポート等の設定はしてください
1version: '3.8'
2services:
3 mysql_source:
4 image: mysql:5.7
5 volumes:
6 - ./docker/mysql_source/conf.d:/etc/mysql/conf.d
7 - ./docker/mysql_source/init_data:/docker-entrypoint-initdb.d
8 environment:
9 MYSQL_DATABASE: test
10 MYSQL_USER: ${SOURCE_MYSQL_USER}
11 MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
12 MYSQL_RANDOM_ROOT_PASSWORD: 1
13 mysql_read:
14 image: mysql:5.7
15 volumes:
16 - ./docker/mysql_read/conf.d:/etc/mysql/conf.d
17 - ./docker/mysql_read/init_data:/docker-entrypoint-initdb.d
18 environment:
19 SOURCE_MYSQL_HOST: mysql_source
20 SOURCE_MYSQL_USER: ${SOURCE_MYSQL_USER}
21 SOURCE_MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
22 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ベースのレプリケーションで安全なステートメントのみがログに記録されるようにする
1[mysqld]
2log-bin
3server-id=1
4gtid-mode=ON
5enforce-gtid-consistency=ON
/docker/mysql_read/conf.d/mysql_read.cnf
リードレプリカ側の必要な設定です
マスターにはない設定内容は以下の通りです
read_only … 書き込みを不可にする
1[mysqld]
2server-id=2
3read_only
4gtid-mode=ON
5enforce-gtid-consistency=ON
/docker/mysql_source/init_data/001-GRANT_REPLICATION.sh
ここではリードレプリカからマスターに接続を許可するユーザを指定します
本来であれば別途アカウントを作るほうがいいのですが、開発用途なのですでにいるユーザを利用します
1#!/bin/sh
2mysql -uroot -p$MYSQL_ROOT_PASSWORD -e"GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_USER'@'%';"
/docker/mysql_read/init_data/001-START_REPLICA.sh
ここではマスターの起動を確認したのちに、マスターの設定を行い、リードレプリカとして利用できるよう START SLAVE; を実行します
1#!/bin/sh
2until mysqladmin ping -h$SOURCE_MYSQL_HOST -u$SOURCE_MYSQL_USER -p$SOURCE_MYSQL_PASSWORD --silent; do
3 sleep 1
4done
5
6mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
7 CHANGE MASTER TO \
8 MASTER_HOST = '$SOURCE_MYSQL_HOST', \
9 MASTER_PORT = 3306, \
10 MASTER_USER = '$SOURCE_MYSQL_USER', \
11 MASTER_PASSWORD = '$SOURCE_MYSQL_PASSWORD', \
12 MASTER_AUTO_POSITION = 1; \
13 START SLAVE; \
14"
ここまでで環境の準備は完了です
docker-compose up で起動させましょう
エラーが発生しなければ問題なく設定できているかと思います
動作確認
まず、マスターのMySQLサーバに入ります
1docker-compose exec mysql_source mysql -uuser -ppassword -Dtest
そしてテーブルを作成し、データを入れてみます
1mysql > CREATE TABLE test(
2 id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
3 name VARCHAR(255)
4);
5Query OK, 0 rows affected (0.02 sec)
6mysql > INSERT INTO `test`(`name`) VALUE ('SampleData');
7Query OK, 0 rows affected (0.01 sec)
データの入力ができたら SELECT で確認しておきます
1mysql> SELECT * FROM `test`;
2+----+------------+
3| id | name |
4+----+------------+
5| 1 | SampleData |
6+----+------------+
71 row in set (0.00 sec)
続いて、データが反映されているかを確認します
リードレプリカのMySQLサーバに入ります
1docker-compose exec mysql_read mysql -uuser -ppassword -Dtest
その後先ほどと同じ SELECT を実行します
1mysql> SELECT * FROM `test`;
2+----+------------+
3| id | name |
4+----+------------+
5| 1 | SampleData |
6+----+------------+
71 row in set (0.00 sec)
すると正常にデータが反映されていることがわかります
最後に
これで開発環境でもリードレプリカを用いて色々テストが行えるかと思います
この記事が少しでも参考になればうれしいです
最後までお読みいただきありがとうございました