読む前に、 この記事を読むことをお勧めします。
職場では、別の地域(アジア)のサイトミラーを作成するという疑問が生じました。 なぜなら パケットの通過時間は非常に長く、地理的な遠隔性が影響し、グレートチャイニーズファイアウォールもキャンセルされていないため、アジア地域にミラーを作成することにしました。 エンジンの転送に問題はありませんでした。ユーザーファイルはrsyncを介して安全に同期できますが、データベースに問題がありました。 ユーザーがアジアにオブジェクトを追加した場合はどうなりますか? このオブジェクトは、ローカルミラーのユーザーだけでなく、他のすべてのユーザーにも表示される必要があります。
MySQLクラスタリングの問題の調査を開始しました。 多くの興味深い詳細が判明しました。 たとえば、Ubuntuディストリビューターに含まれるサーバーのバージョン(テストベンチで使用)は、NDB(ネットワークデータベース)ストレージエンジンをサポートしていません。 NDBをサポートすると噂されているmysql-maxバージョン、またはmysql-clusterをインストールする必要があります。 最も興味深いのは、debパッケージがないため、バイナリまたはソースからインストールすることです。 バイナリシステムからのインストールに成功しませんでした。 古いサーバーを削除することはできませんでした(パッケージは削除され、ファイルはすべて適切な場所にあります)。 正直に2日間これを試したので、私はこのベンチャーを辞めました。 私はソースからコンパイルしようとしませんでしたが、これが最良のオプションだと思います。
マスターマスターレプリケーション
一般に、研究の次の段階は複製でした。 それから私はこれが私が必要なものであることに気づきました。 中央サーバーがあり、リージョンにはそこから更新を運ぶレプリカがあります。 ただし、レプリカからの更新がメインデータベースに含まれることを確認する必要があります。 結局のところ、マスターマスターレプリケーションを行う必要があります。 つまり 最初のサーバーは2番目のサーバーのマスターになり(2番目はスレーブとして接続します)、2番目のサーバーは最初のサーバーのマスターになります(最初のサーバーはスレーブとして接続します)。 Ubuntu Server 9.10に基づいた仮想マシンで実施されたテスト
したがって、ubuntu1サーバー(192.168.0.21)、mysql config:
[mysqld]
# ,
server-id = 1
# ,
log-bin = /var/lib/mysql/mysql-bin
# ,
relay-log = /var/lib/mysql/mysql-relay-bin
relay-log-index = /var/lib/mysql/mysql-relay-bin.index
replicate-do-db = test_db
master-host=192.168.0.22 #ubuntu2
master-user=replication
master-password=password_of_user_replication
master-port=3306
2番目の場合、同様に、別のIPマスターとサーバー番号のみ。
サーバーを再起動します。 次に、ユーザー複製を作成し、複製する権利を与えます。
mysql@ubuntu1> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'192.168.0.22' IDENTIFIED BY 'password';
mysql@ubuntu2> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'192.168.0.21' IDENTIFIED BY 'password';
次に、スレーブをマスターにバインドする必要があります。 これは次のように行われます。
ubuntu1をマスターとしてubuntu2にバインドします。
まず、データベース内のエントリをブロックします。
mysql@ubuntu1> SET GLOBAL read_only = OFF;
詳細については、 こちらをご覧ください。
mysql@ubuntu1> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000006 | 7984 | | |
+------------------+----------+--------------+------------------+
1 row in set (0,00 sec)
Fileの値とそこから位置を取り、ウィザードを接続します。
mysql@ubuntu2> slave stop; #
mysql@ubuntu2> CHANGE MASTER TO MASTER_HOST = "192.168.0.22", MASTER_USER = "replication", MASTER_PASSWORD = "password_of_user_replication", MASTER_LOG_FILE = "mysql-bin.000006", MASTER_LOG_POS = 7984;
mysql@ubuntu2> slave start;
その後、次のいずれかの方法で接続を確認できます
mysql@ubuntu2>load data from master;
どちらかを通して
mysql@ubuntu2> show slave status;
エラーがなければ、ウィザードは接続されています。
このサーバーを最初のマスターとして接続します(まったく同じように行われます)。
その結果、2つのサーバーのシステムがあり、任意のサーバーに変更を加えると、2番目のサーバーに複製されます。
マルチマスターレプリケーション
しかし、これは十分ではないように思えました。 3台目のサーバーを追加する場合はどうですか? 最初は線形トポロジについて考えました。
ubuntu1 <-> ubuntu2 <-> ubunt3およびスタートポロジーです。 しかし、悲しいかな、それは現実とはほど遠いものでした。 MySQLは、単一のスレーブが複数のマスターを持つことを許可しません。 そして、線形トポロジでは、これはubuntu2になります。 誰かが1つのスレーブを複数のマスターに結び付ける方法を知っていれば、その情報に感謝します。
星も線形にフィットせず、リングは残ります。 そして、私はしようと思いました。
このスキームでは、各サーバーにはマスターが1つしかなく、リングが閉じているという事実により、更新はリング内のどこからでもすべてのサーバーに到達します。 ここで重要なのは、ウィザードが独自の更新をスレーブに送信するだけでなく 、ウィザードの更新も送信するために、my.cnf行を[mysqld]セクションに追加することです。
log-slave-updates
それぞれ各サーバーの設定で。
チェックし、スキームが機能したことを嬉しく思いました。 データベースが変更されるたびに、変更は実際にサーバーの残りの部分に複製されます。
自動インクリメントフィールド
自動インクリメントフィールドを含む新しい行が異なるマスターサーバーに追加されると、競合が発生する可能性があります。 これを防ぐには、データベースサーバーでの自動インクリメントのシーケンスのステップを変更する必要があります。
- auto_increment_incrementは、AUTO_INCREMENTを変更するステップを決定します。
- auto_increment_offsetは初期増分値を決定します
異なるマスターでこれらのパラメーターの正しい(競合しない)値を選択すると、マルチマスター構成で使用されるサーバーは、レコードを挿入するときに競合しないAUTO_INCREMENT値を使用します。 たとえば、N個のマスターサーバーの場合、次の値を設定します。
- 各マスターでauto_increment_incrementをNに設定します。
- N個のマスターのそれぞれで、1、2、...、Nを使用してauto_increment_offsetの異なる値を設定します。
たとえば、auto_increment_increment = 10およびauto_increment_offset = 3を使用すると、次のフィールド値3、13、23が生成され、10、7を使用すると、7、17、27などになります。
耐障害性
結局のところ、サーバーの1つをドロップしようとするしかありませんでした。 ubuntu2から食べ物を引き出します。 次にロードします。 なに?
ubnutu2に対するその後の変更は、問題なくubuntu3およびubuntu1に複製されます。 ただし、ubuntu2で他のサーバーに加えられた変更は複製されません。 ubuntu3のshow slave statusを見て、マスターが失われていることを確認します。
レシピとして、次のものを提供できます。
データベースサーバーを起動した後、現在のサーバーのスレーブからマスターを解き、再度バインドします。 なぜなら トポロジでは、どのサーバーにもリングスレーブが1つしかないため、タスクが簡素化されます。 アルゴリズムは次のようになります。
1. ubuntu2が電源でシャットダウンし、再び起動します
2.自宅のubuntu2:
-レプリケートされたデータベースを書き込み用にロックします
mysql@ubuntu2> SET GLOBAL read_only = OFF;
-ログの名前と位置を確認します
mysql@ubuntu2> show master status;
2. mysqlを介してクライアントがスレーブ(ubuntu3)にログオンするubuntu2
-スレーブ
mysql@ubuntu3> slave stop;
から自身を
mysql@ubuntu3> slave stop;
-自分自身をマスターとして宣言します:
mysql@ubuntu3> CHANGE MASTER TO MASTER_HOST = "192.168.0.22", MASTER_USER = "replication", MASTER_PASSWORD = "password_of_user_replication", MASTER_LOG_FILE = "mysql-bin.000006", MASTER_LOG_POS = 5161;
前の手順で取得したログ名と位置を使用します。
-スレーブを再度バインドします:
mysql@ubuntu3> slave start;
このスクリプトの実装の準備はできていませんが、perl / php / python / bashで何を書くかを考えます...
このトピックに関するhabrasocietyの考えを聞いてうれしいです。 記事が有用であることが判明した場合は、まだクラスタリングに対処し、クラスター複製を行う計画を書いてください。