Azure設計プラクティス4: MySQLレプリケーション

MySQLにはレプリケーションという同じ内容のデータベースを複数冗長に持つ設定をすることができる機能があります。

Microsoft Azureには現在(2017/5/9)MySQLのレプリケーション機能をサポートするサービスは存在しませんがLinux VirtualMachine内にMySQLを稼働させることで同じ機能を実現することができます。

今回はMySQLのレプリケーションをAzureで行っていきたいと思います。

今回の構成はこのようにします。

同一VirtualNet、同一ネットワーク・セキュリティグループ内にUbuntuOSのVMを2台、MasterとSlaveとして配置します。

レプリケーションについて

MySQLレプリケーションに関してはこちらの記事がとても詳しくまとまっているので参考にしていきます。

MySQL入門 レプリケーション編
http://qiita.com/Tocyuki/items/c224cef57493f536a941

通常、データベースを1台で運用すると1台のDBに負荷が集中してサービスのボトルネックや可用性の低下へとつながります。

そこで同じ内容のデータベースを複数作成(レプリケーション)しアクセスを分散することで1台あたりのデータベースの負荷を減らします。また、1台のDBが使えなくなったとしてももう一台のDBが継続的に稼働し続けることで高可用性を実現します。

しかしDBを複数持つと1台に書き込んだ瞬間にすべてのDBを更新しなければいけません。

そこでDB1台のみに書き込み、読み込みを許可しその他のDBには読み込みのみを許可することでDBの読み込みのトラフィックを分散することができます。上記の書き込み、読み込みを許可するDBをMaster、読み込みのみを許可するDBをSlaveと呼びます。

さらに、Masterが落ちた時はSlaveをMasterへと昇格することでサービスの継続稼働をサポートします。

インスタンスを作成する

今回の本題はMySQLの設定になるので上図の構成のインスタンスをさくっと作ってしまいます。

まずVirtualNetを作成します。アドレス空間はIPv4のクラスCとしましたが別になんでも大丈夫です。

続いて2つのVMを包むネットワーク・セキュリティグループを作成します。こちらも特に問題はありません。

MasterDB用のVirtualMachineを作成します。

OSはUbuntu 16.04LTS

VirtualNetworkとネットワーク・セキュリティグループは先程作成下ものを指定してください。

Slave用のVMを作成します。

OSはMasterと同じUbuntu 16.04LTS、VNet、セキュリティグループもMasterと同じ、先ほど作成したものとします。

VMに紐付いているネットワークインターフェースカードの設定を開き、IPアドレスの割当を静的にし、上図の構成通り、Masterに192.168.0.4、Slaveに192.168.0.5を設定します。

ネットワーク・セキュリティグループの設定を開き、SSHの22番の受信許可をします。

 

これで上図の設定をすることができました。

MySQLにレプリケーションの設定をする

今回はGTIDの使用はなしの方向でいきます。

まずMasterのVMにsshでログインします。

DB、テーブルの作成、データの挿入までを行います。

# ssh ログイン
ssh {user}@{vm ip}
# パッケージアップデート
sudo apt-get update
sudo apt-get upgrade -u
# mysqlインストール
sudo apt-get install mysql-server
# mysqlログイン
mysql -u root -p
# データベース作成
create database testdb;
use testdb;
# テーブル作成
create table items(id int primary key auto_increment,name text);
# データ挿入
insert into items (name) values('item1');
# データ表示
select * from items;

+----+-------+
| id | name  |
+----+-------+
|  1 | item1 |
+----+-------+
1 row in set (0.00 sec)

レプリケーション用のユーザーを作成します。

# 同一VNet内で有効なレプリケーション用のユーザーを作成今更
grant replication slave on *.* to 'replication'@'192.168.0.0/24' identified by 'repl'

 

MasterDBの設定を行います。サーバーIDは任意のものを設定します。

sudo nano /etc/mysql/my.cnf

[mysqld]
# バイナリロギングの有効化
log-bin=mysql-bin
# サーバーID
server-id=1

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
#外部アクセスを許可するように設定
bind-address=0.0.0.0

# 再起動
sudo systemctl restart mysql

SlaveのMysqlインストールと設定を行います。

 

# slaveのVMへssh ログイン
ssh {user}@{vm ip}
# パッケージアップデート
sudo apt-get update
sudo apt-get upgrade -u
# mysqlインストール
sudo apt-get install mysql-server
sudo nano /etc/mysql/my.cnf

[mysqld]
log-bin=mysql-bin
log_slave_updates
server-id=2

sudo systemctl restart mysql

続いてMasterDBでバイナリログの名前とイベント開始位置をめもります。

#masterのVMで
mysql -u root -p
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

MasterDBのバックアップをとります。

mysqldump -u root -p testdb --lock-all-tables>testdb.sql

scpでslaveへと転送します。

scp testdb.sql {user}@192.168.0.5:~

SlaveのDBでリストアします。

mysql -u root -p
create database testdb;
quit;

mysql -u root -p testdb<testdb.sql

SlaveでMasterの登録を行います。

mysql -u root -p
# masterのIPやユーザー名、バイナリログのファイル名やポジションは上記までの設定で取得できたものを使う
change master to master_host='192.168.0.4',master_user='replication',master_password='repl',master_log_file='mysql-bin.000001',master_log_pos=154;

レプリケーションをスタートします。

start slave;

 

レプリケーションの確認を行う

では本当にレプリケーションできたか確認をしてみましょう。

slaveのDBでitemsテーブルを表示してみます。

mysql -u root -p
use testdb;
select * from items;

+----+-------+
| id | name  |
+----+-------+
|  1 | item1 |
+----+-------+
1 row in set (0.00 sec)

 

とりあえずレプリケーション登録時点ではMasterと同じ内容が入っています。

ではMasterにデータを追加してみます。

# master VMで
mysql -u root -p
use testdb;
insert into items (name) values('item2');

select * from items;
+----+-------+
| id | name  |
+----+-------+
|  1 | item1 |
|  2 | item2 |
+----+-------+
2 rows in set (0.00 sec)

 

ではslaveで変更を確認してみます。

# slave VMで
mysql -u root -p
use testdb;

select * from items;
+----+-------+
| id | name  |
+----+-------+
|  1 | item1 |
|  2 | item2 |
+----+-------+
2 rows in set (0.00 sec)

正しくレプリケーションできていました。

master側のステータスを見たいときは

show master status;

slave側のステータスを見たいときは

show slave status;

でOK

 

感想

思ったよりめんどくさかったという感じはありますがAWSのようなマネージドなMySQLならボタンポチーでできるのだろうか?Azureも早くMySQLのマネージドサービスほしいですね(ClearDBではない)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください