hero_picture

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

2020/12/17

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)

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

最後に

これで開発環境でもリードレプリカを用いて色々テストが行えるかと思います

この記事が少しでも参考になればうれしいです

最後までお読みいただきありがとうございました