レプリケーションとは何ですか。なぜ必要なのですか。
レプリケーション自体は、オブジェクトの複数のコピーを同期するプロセスを指します。私たちの場合、そのようなオブジェクトはデータベースサーバーであり、データ自体が最大の価値を持っています。2つ以上のサーバーがあり、それらのサーバーで同期されたデータセットを維持する場合は、システムレプリケーションを実装しています。手動オプションcでさえ
mysqldump -> mysql load
複製です。
データ複製自体には価値がなく、次のタスクを解決するためのツールにすぎないことを理解する必要があります。
- データ読み取りパフォーマンスの向上。レプリケーションの助けを借りて、サーバーの複数のコピーを維持し、それらの間で負荷を分散することができます。
- . , . , .
- . , , , .
- . , ( , ), , .
- . , , .
- . .
MySQL
レプリケーションプロセスには、マスターサーバー(通常はマスター、マスターと呼ばれます)から1つ以上のスレーブサーバー(スレーブ、 スレーブ)へ のデータ変更の伝播が含ま れ ます。特に複数のマスターサーバーを使用する場合は、より複雑な構成もありますが、特定のマスターサーバーでの変更ごとに、残りのマスターが条件付きでスレーブになり、これらの変更を消費します。
一般に、MySQLレプリケーションは次の3つのステップで構成されます。
- マスターサーバーは、データの変更をログに書き込みます。このログはバイナリログと呼ばれ、変更はバイナリログイベントと呼ばれます。
- スレーブは、バイナリログへの変更をリレーログと呼ばれる独自のログにコピーします。
- スレーブはリレーログからの変更を再生し、それらを自身のデータに適用します。
レプリケーションタイプ
レプリケーションには、基本的に異なる2つのアプローチがあります 。command-by- commandと row-by-rowです。コマンドごとのレプリケーションの場合、データ変更要求(INSERT、UPDATE、DELETE)はマスターログに記録され、スレーブは同じコマンドを正確に再現します。行ごとのレプリケーションでは、ログによってテーブルの行が直接変更され、同じ実際の変更がスレーブに適用されます。
特効薬がないため、これらの方法にはそれぞれ長所と短所があります。コマンドによるレプリケーションは、実装と理解が容易であり、マスターとネットワークの負荷を軽減します。ただし、コマンドごとの複製は、NOW()、RAND()などの非決定論的関数を使用する場合、予測できない影響をもたらす可能性があります。マスターとスレーブ間でデータが同期していないために問題が発生することもあります。実際のデータ変更がキャプチャされて再現されるため、行ごとのレプリケーションにより、より予測可能な結果が得られます。ただし、この方法では、ログ内のすべての変更をログに記録する必要があるマスターサーバー、およびこれらの変更が伝播するネットワークの負荷が大幅に増加する可能性があります。
MySQLは両方のレプリケーション方法をサポートしており、バージョンに応じてデフォルト(推奨される方法と言えます)が変更されました。 MySQL 8のような最新バージョンは、デフォルトで行ベースのレプリケーションを使用します。
レプリケーションアプローチを分割する2番目の原則は 、マスターサーバーの数です。..。 1つのマスターサーバーが存在するということは、彼だけがデータの変更を受け入れることを意味し、変更がすでに多くのスレーブに伝播されている一種のベンチマークです。マスター-マスターレプリケーションの場合、利益と問題の両方が発生します。たとえば、利点の1つは、同じシドニーとヘルシンキからのリモートクライアントに、データベースに変更を書き込む同じように高速な機会を提供できることです。これは、両方のクライアントが同じデータを同時に変更した場合、その変更が最終的なものと見なされ、トランザクションがコミットされ、トランザクションがロールバックされる場合に、主な欠点につながります。
また、一般にマスターレプリケーションマスターが存在しても、システムへのデータ書き込みのパフォーマンスを向上させることはできないことに注意してください。私たちの唯一のマスターが一度に最大1000のリクエストを処理できると想像してみましょう。複製された2番目のマスターを追加すると、「それらの」要求の処理に加えて、2番目のマスターで行われた変更を適用する必要があるため、それぞれで1000個の要求を処理できなくなります。つまり、コマンドごとのレプリケーションの場合、両方に可能な負荷の合計が最も弱いものになり、行ごとのレプリケーションでは、効果を完全に予測することはできません。特定の条件に応じて、正または負のいずれかになります。
MySQLで単純なレプリケーションを構築する例
今こそ、MySQLで簡単なレプリケーション構成を作成するときです。このために、dockerhubのDockerイメージとMySQLイメージ、および ワールドデータベースを使用します 。
まず、2つのコンテナを起動します。1つは後でマスターとして構成し、もう1つはスレーブとして構成します。彼らがお互いに話すことができるように彼らをネットワーク化しましょう。
docker run -d --name samplereplication-master -e MYSQL_ALLOW_EMPTY_PASSWORD=true -v ~/path/to/world/dump:/docker-entrypoint-initdb.d mysql:8.0
docker run -d --name samplereplication-slave -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:8.0
docker network create samplereplication
docker network connect samplereplication samplereplication-master
docker network connect samplereplication samplereplication-slave
マスターコンテナには、初期ベースの存在をシミュレートするために、world.sqlダンプとのボリューム接続が指定されています。コンテナを作成するとき、mysqlはdocker-entrypoint-initdb.dディレクトリにあるsqlスクリプトをダウンロードして実行します。
構成ファイルを操作するには、テキストエディターが必要です。便利なものなら何でも使えますが、vimが好きです。
docker exec samplereplication-master apt-get update && docker exec samplereplication-master apt-get install -y vim
docker exec samplereplication-slave apt-get update && docker exec samplereplication-slave apt-get install -y vim
まず、レプリケーションに使用されるマスターにアカウントを作成しましょう。
docker exec -it samplereplication-master mysql
mysql> CREATE USER 'replication'@'%';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
次に、マスターサーバーの構成ファイルを変更しましょう。
docker exec -it samplereplication-master bash
~ vi /etc/mysql/my.cnf
次のパラメータを[mysqld]セクションのmy.cnfファイルに追加する必要があります。
server_id = 1 # log_bin = mysql-bin #
バイナリログを有効/無効にするには、サーバーを再起動する必要があります。Dockerの場合、コンテナーが再ロードされます。
docker restart samplereplication-master
バイナリログが有効になっていることを確認してください。ファイル名や位置などの特定の値は異なる場合があります。
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 156 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
データ複製を開始するには、スレーブをマスターの状態に「プルアップ」する必要があります。これを行うには、実際のデータのスナップショットを作成するために、ウィザード自体を一時的にブロックする必要があります。
mysql> FLUSH TABLES WITH READ LOCK;
次に、mysqldumpを使用して、データベースからデータをエクスポートしましょう。もちろん、この例では、同じworld.sqlを使用できますが、より現実的なシナリオに近づきましょう。
docker exec samplereplication-master mysqldump world > /path/to/dump/on/host/world.sql
その後、SHOW MASTER STATUSコマンドを再度実行し、ファイルと位置の値を記憶または書き留める必要があります。これらは、バイナリログのいわゆる座標です。スレーブを開始するようにさらに指示するのは、それらからです。これで、マスターのロックを再び解除できます。
mysql> UNLOCK TABLES;
マスターが構成され、他のサーバーに複製する準備ができています。さあ、奴隷に移りましょう。まず、マスターからダンプをロードします。
docker cp /path/to/dump/on/host/world.sql samplereplication-slave:/tmp/world.sql
docker exec -it samplereplication-slave mysql
mysql> CREATE DATABASE `world`;
docker exec -it samplereplication-slave bash
~ mysql world < /tmp/world.sql
次に、パラメータを追加してスレーブ構成を変更します。
log_bin = mysql-bin # server_id = 2 # relay-log = /var/lib/mysql/mysql-relay-bin # relay-log-index = /var/lib/mysql/mysql-relay-bin.index # read_only = 1 # “ ”
その後、スレーブをリロードします。
docker restart samplereplication-slave
次に、どのサーバーがマスターになるか、どこからデータの複製を開始するかをスレーブに指示する必要があります。MASTER_LOG_FILEとMASTER_LOG_POSの代わりに、マスターのSHOW MASTERSTATUSから取得した値に置き換える必要があります。これらのパラメータは、まとめてバイナリログ座標と呼ばれます。
mysql> CHANGE MASTER TO MASTER_HOST='samplereplication-master', MASTER_USER='replication', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=156;
リレーログの再生を開始して、レプリケーションステータスを確認しましょう。
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
スレーブステータス
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: samplereplication-master Master_User: replication Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 156 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 324 Relay_Master_Log_File: mysql-bin.000001 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: 156 Relay_Log_Space: 533 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: 1 Master_UUID: c341beb7-3a33-11eb-9440-0242ac110002 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: Master_public_key_path: Get_master_public_key: 0 Network_Namespace: 1 row in set, 1 warning (0.00 sec)
すべてがうまくいけば、あなたのステータスは同じように見えるはずです。ここでの重要なパラメータ:
- Slave_IO_State-実際には、レプリケーションの状態。
- Read_Master_Log_Posは、マスターログから読み取られた最後の位置です。
- Relay_Master_Log_File-現在のマスターログファイル。
- Seconds_Behind_Master-スレーブはマスターより数秒遅れます。
- Last_IO_Error、Last_SQL_Error-レプリケーションエラー(ある場合)。
マスターのデータを変更してみましょう。
docker exec -it samplereplication-master mysql
mysql> USE world;
mysql> INSERT INTO city (Name, CountryCode, District, Population) VALUES ('Test-Replication', 'ALB', 'Test', 42);
そして、それらがスレーブに表示されたかどうかを確認します。
docker exec -it samplereplication-slave mysql
mysql> USE world;
mysql> SELECT * FROM city ORDER BY ID DESC LIMIT 1;
+------+------------------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------------+-------------+----------+------------+
| 4081 | Test-Replication | ALB | Test | 42 |
+------+------------------+-------------+----------+------------+
1 row in set (0.00 sec)
優秀な!入力されたレコードはスレーブにも表示されます。おめでとうございます。これで、最初のMySQLレプリケーションが作成されました。
結論
この記事のフレームワーク内で、レプリケーションプロセスの基本を理解し、このツールの使用法に慣れ、MySQLでレプリケーションの簡単な例を独自に実装できるようになったと思います。複製のトピックとその実用化は非常に広範囲にわたっており、このトピックに興味がある場合は、次の情報源を参考にしてください。
- Andrey Aksenov(Sphinx)によるレポート「MySQLレプリケーションのしくみ」
- 「MySQLを最大限に活用する」という本。最適化、複製、バックアップ」-Baron Schwartz、Petr Zaitsev、Vadim Tkachenko
- 「高負荷」 -ここでは、データ複製の特定のレシピを見つけることができます
この記事がお役に立てば幸いです。フィードバックやコメントを歓迎します。