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、テーブルの作成、データの挿入までを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 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) |
レプリケーション用のユーザーを作成します。
1 2 |
# 同一VNet内で有効なレプリケーション用のユーザーを作成今更 grant replication slave on *.* to 'replication'@'192.168.0.0/24' identified by 'repl' |
MasterDBの設定を行います。サーバーIDは任意のものを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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インストールと設定を行います。
1 2 3 4 5 6 7 8 |
# slaveのVMへssh ログイン ssh {user}@{vm ip} # パッケージアップデート sudo apt-get update sudo apt-get upgrade -u # mysqlインストール sudo apt-get install mysql-server |
1 2 3 4 5 6 7 8 |
sudo nano /etc/mysql/my.cnf [mysqld] log-bin=mysql-bin log_slave_updates server-id=2 sudo systemctl restart mysql |
続いてMasterDBでバイナリログの名前とイベント開始位置をめもります。
1 2 3 4 5 6 7 8 9 10 |
#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のバックアップをとります。
1 |
mysqldump -u root -p testdb --lock-all-tables>testdb.sql |
scpでslaveへと転送します。
1 |
scp testdb.sql {user}@192.168.0.5:~ |
SlaveのDBでリストアします。
1 2 3 4 5 |
mysql -u root -p create database testdb; quit; mysql -u root -p testdb<testdb.sql |
SlaveでMasterの登録を行います。
1 2 3 |
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; |
レプリケーションをスタートします。
1 2 |
start slave; |
レプリケーションの確認を行う
では本当にレプリケーションできたか確認をしてみましょう。
slaveのDBでitemsテーブルを表示してみます。
1 2 3 4 5 6 7 8 9 10 11 |
mysql -u root -p use testdb; select * from items; +----+-------+ | id | name | +----+-------+ | 1 | item1 | +----+-------+ 1 row in set (0.00 sec) |
とりあえずレプリケーション登録時点ではMasterと同じ内容が入っています。
ではMasterにデータを追加してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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で変更を確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 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側のステータスを見たいときは
1 |
show master status; |
slave側のステータスを見たいときは
1 |
show slave status; |
でOK
感想
思ったよりめんどくさかったという感じはありますがAWSのようなマネージドなMySQLならボタンポチーでできるのだろうか?Azureも早くMySQLのマネージドサービスほしいですね(ClearDBではない)