2014年12月19日: 冗長化入門

【ソリューション事業部 スミダ】
イケジマさん初めSSS懇親会(慣れない・・)幹事の皆様ありがとうございました。
寒い時は鍋に限りますね!Tジさん特選の水炊き、カニ鍋とても美味でした。
さて、前回はかなりマニアックな記事で方々から反応がありましたので
引き続きこの路線で突っ走ってみようと思います。
今回は前回と違い、目に見える物はありませんが、システムを運用していく上で
大切な「冗長化」についての話になります。。。。

以前システムを構築する際にサーバー2台構成でMySQL5.5から実装されたの準同期レプリケーションと
lsyncd、rsyncdを使って2台のサーバーのファイルとDBの同期をとることを試しました。
試行錯誤しながらもうまく構築することが出来ましたので、その手順を残しておきます。


構成概要

  • 稼動系
    • 通常時のアクセスをすべて引き受けるサーバー
  • 待機系
    • 稼動系がシステムダウンした際に稼働系に昇格するための待機サーバー

冗長化構成の肝

ソース、物理ファイル同期

稼動系と待機系をrsyncd, lsyncdでリアルタイム同期します。

データベースデータ同期

準同期レプリケーションでリアルタイム同期します。

復旧は手動で

フェイルバック、フェイルオーバー共に手動です。

かつそれぞれに違うドメイン(待機系: standby_host 稼働系: active_host)を振って人力で周知します。

構築手順

MySQLは準同期レプリケーションが使える5.5以上を導入済みとする (導入手順は割愛)

1. 稼動系(Master)の設定

# vi /etc/my.cnf

以下を有効、追加する

#バイナリーログ有効
log-bin=mysql-bin
#レプリケーション方式の選択SBRとRBRを動的に切り替える(デフォルトはMIXED)
binlog_format=MIXED
#バイナリーログファイルサイズ
max_binlog_size=100M
#バイナリーログ有効期限
expire_logs_days=3
#1回バイナリログへ更新を行うことでディスクへのフラッシュを行う
sync_binlog=1
#InnoDBのログバッファをInnoDBログファイルに書き込むタイミングを決める
innodb_support_xa=1
#2相コミットを行うかどうか。ログをコミットごとにフラッシュしない
innodb_flush_log_at_trx_commit=1
#テーブルスペースをテーブル単位で作成する
innodb_file_per_table  

再起動

# /etc/init.d/mysqld restart

MySQLログイン後ステータス確認

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       126 |
| mysql-bin.000002 |       126 |
| mysql-bin.000003 |       126 |
| mysql-bin.000004 |       126 |
| mysql-bin.000005 |       126 |
| mysql-bin.000006 |       126 |
| mysql-bin.000007 |       126 |
| mysql-bin.000008 |       107 |
+------------------+-----------+
8 rows in set (0.01 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000008
Position: 107
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

スレーブ用ユーザー作成

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%' IDENTIFIED BY '任意のパスワード';

権限の確認

mysql> SHOW GRANTS FOR 'slave'@'%';
+--------------------------------------------------------------------------------------------------------------------------------------+
| Grants for slave@%                                                                                                                   |
+--------------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%' IDENTIFIED BY PASSWORD '*2222CF6639797EFE06ED82985752723FE6BB0BA0' |
+--------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
#設定の反映
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

レプリケーション設定反映確認の為に、データベース、テーブルを作成しておく

#データベースの作成
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.01 sec)
#テーブルを選択
mysql> use test;
Database changed
#テーブルの作成
mysql> CREATE TABLE IF NOT EXISTS `user` (
->   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
->   PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.09 sec)
#レコードの登録
mysql> INSERT INTO user( id ) VALUES( 1 );
Query OK, 1 row affected (0.03 sec)
#データの確認
mysql> SELECT * FROM user;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

dumpを取得

# mysqldump -u root -p --all-databases --master-data=2 --single-transaction --flush-logs > /root/dump.sql

ファイル転送

# scp /root/dump.sql root@standby_host:/tmp/

2. 待機系(slave)の設定

# vi /etc/my.cnf

※server-idが下部に無いか注意!

server-id=20
report_host=slave20
#書き込み禁止(SUPER権限のユーザーは書き込めてしまう)
read_only=1
skip_slave_start
log_bin=mysql-bin
#バイナリーログを生成する場合
log_slave_updates
#リレーログのファイル名
relay_log=mysql-relay-bin
#リレーログのインデックスファイル名
relay-log-index==mysql-relay-bin
#テーブルスペースをテーブル単位で作成する
innodb_file_per_table

mysqld再起動

# /etc/init.d/mysqld start

dumpファイルリストア

# mysql -u root < /tmp/dump.sql

レプリケーションの設定確認

# head -100 /tmp/dump_20121031_01.sql | grep CHANGE
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000009', MASTER_LOG_POS=107;

ここのMASTER_LOG_FILE, MASTER_LOG_POSを控えておく

再度MySQLログイン

mysql> CHANGE MASTER TO
MASTER_HOST='masterサーバーのIPアドレス',
MASTER_USER='slaveユーザーのアカウント名',
MASTER_PASSWORD='slaveユーザーのパスワード',
MASTER_PORT=3306,
MASTER_LOG_FILE='[MASTER_LOG_FILE]',
MASTER_LOG_POS=[MASTER_LOG_POS],
MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.02 sec)
# slave起動
mysql> START SLAVE;
Query OK, 0 rows affected (0.02 sec)

プロセス確認

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: ************
Master_User: slave
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-bin.000009
Read_Master_Log_Pos: 107
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000009
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 409
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 10
1 row in set (0.00 sec)

Masterからテーブルにデータをinsertして反映されるか確認

3. 準同期設定

Master設定

#master用のプラグインをインストール
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.13 sec)
#slave用のプラグインも一応入れておく。(slave,master切り替え用に)
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.49 sec)
#プラグインの確認
mysql> SHOW PLUGINS;
+--------------------------+----------+--------------------+--------------------+---------+
| Name                     | Status   | Type               | Library            | License |
+--------------------------+----------+--------------------+--------------------+---------+
| binlog                   | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| mysql_native_password    | ACTIVE   | AUTHENTICATION     | NULL               | GPL     |
| mysql_old_password       | ACTIVE   | AUTHENTICATION     | NULL               | GPL     |
| MRG_MYISAM               | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| CSV                      | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| MyISAM                   | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| MEMORY                   | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| ARCHIVE                  | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| BLACKHOLE                | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| FEDERATED                | DISABLED | STORAGE ENGINE     | NULL               | GPL     |
| PERFORMANCE_SCHEMA       | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| InnoDB                   | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| INNODB_TRX               | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_LOCKS             | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_LOCK_WAITS        | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_CMP               | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_CMP_RESET         | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_CMPMEM            | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_CMPMEM_RESET      | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_BUFFER_PAGE       | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_BUFFER_PAGE_LRU   | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| INNODB_BUFFER_POOL_STATS | ACTIVE   | INFORMATION SCHEMA | NULL               | GPL     |
| partition                | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| rpl_semi_sync_master     | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
| rpl_semi_sync_slave      | ACTIVE   | REPLICATION        | semisync_slave.so  | GPL     |
+--------------------------+----------+--------------------+--------------------+---------+
25 rows in set (0.00 sec)

設定ファイル編集

vi /etc/my.cnf

[mysqld]の項目に以下を追加

# ホスト名
report_host=active_host
# プラグイン有効化
plugin-load=rpl_semi_sync_master=semisync_master.so
innodb_flush_log_at_trx_commit = 1
#準同期が有効化
rpl_semi_sync_master_enabled = 1
#slaveから応答待ち最大時間(レスポンスが返ってこなかったときの待ち時間を指定)。単位はミリ秒。デフォルト10秒
rpl_semi_sync_master_timeout=10

mysqld再起動

# /etc/init.d/mysqld restart

Slave設定

#master用のプラグインをインストール
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.13 sec)
#slave用のプラグインも一応入れておく。(slave,master切り替え用に)
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.49 sec)

設定ファイル編集

vi /etc/my.cnf

[mysqld]の項目に以下を追加

report_host=standby_host
plugin-load=rpl_semi_sync_slave=semisync_slave.so
innodb_flush_log_at_trx_commit = 1
#slaveの有効化
rpl_semi_sync_slave_enabled = 1

mysqld再起動

# /etc/init.d/mysqld restart

動作確認

#
mysql> show variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | OFF   |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
| rpl_semi_sync_slave_enabled        | ON    |
| rpl_semi_sync_slave_trace_level    | 32    |
+------------------------------------+-------+
#
mysql> SELECT @@innodb_flush_log_at_trx_commit;
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
#同期開始
start slave;

4.ソース、物理ファイル同期化対応

同期はlsyncd+rsyncでリアルタイムに更新する

共通設定

rsyncは873番ポートを利用するため、予め開けておこう

待機系(コピー先)設定

rsyncはxinetd経由で起動するので、念のためインストールしておく

# yum install rsync xinetd

rsyncの有効化

# vi /etc/xinetd.d/rsync
disable yes -> no に変更

設定ファイル作成(デフォルトで存在しないので作成する)

# vi /etc/rsyncd.conf
uid = standby
gid = standby
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
[standby_source_sync]
path = /path/to/active_host
hosts allow = active_host
read only = no

xinetd起動

# /etc/init.d/xinetd start

稼動系(コピー元)設定

lsyncdインストール

# yum install lsyncd

設定ファイル作成

# vi /etc/lsyncd.conf
settings = {
logfile    = "/var/log/lsyncd.log",
statusFile = "/tmp/lsyncd.stat",
statusInterval = 1,
delay = "1",
}
sync{
default.rsync,
source="/path/to/standby_host",
target="standby_host::standby_source_sync"
}

起動

# /etc/init.d/lsyncd start

約1秒遅れで同期されているのがわかる

続いて自動起動設定

# chkconfig --add lsyncd
# chkconfig lsyncd on

これで設定は終わりですが、障害時の復旧は手作業となります。
heartbeat等のクラスタリングソフトを使ってフェイルオーバー出来る様にしなければ
サーバー管理者は枕を高くして寝ることが出来ません・・・その話は次回にでも

この記事に関連する情報

テーブルといえば、家具の名産地、福岡県大川市で木が持つ本来の魅力を堪能できる上質な無垢家具を製造する、「こもれび家具」の通販サイトをオープンしました。 家具好きの方も納得する出来栄えです。是非一度ご覧下さい!
こもれび家具
カテゴリー:
| 投稿者:
DAブログ | DAホールディングス(エクスショップ&ガーデンプラス)

コメント