MySQLレプリケーションは高レイテンシの相互接続の影響を受けますか?


11

異なるデータセンターに常駐する標準的なマスターとスレーブのMySQLセットアップと、マスターと同じデータセンターにある別のスレーブがあります。

データセンター間の帯域幅はかなり高くなっていますが(ネットワークベンチマークでは、15MB /秒に達する可能性があります)、レイテンシが存在し、約28msです。決して高くはありませんが、同じデータセンターの1秒未満のレイテンシよりもはるかに高くなります。

ローカルスレーブが最新の状態であるときに、削除スレーブで重大な遅延(2000秒以上)が発生する場合があります。遅れているリモートスレーブを見ると、SQLスレッドは通常、IOスレッドがリレーログを更新するのを待つ時間を費やしています。マスターは同時に「ネットを待っている」またはある種の何かを示します。

つまり、それはネットワークであることを意味しますが、これが発生した時点ではまだ帯域幅に空きがあります。

私の質問は、データセンター間のレイテンシがレプリケーションのパフォーマンスに影響を与える可能性がありますか?スレーブioスレッドは、マスターが送信を停止するまでイベントをストリーミングするのですか、それともイベント間でマスターをプールするのですか?


2000秒?それで、33分の遅れ?
Richard

うん...それは一日中上下します。
shlomoid

2
このサイトでこれらの種類の質問が好きなため、+ 1 この性質の質問で他の人がこのサイトに来るために言葉を出してください!!!
RolandoMySQLDBA 2011

回答:


7

あなたの質問に対する直接の答えは「はい」ですが、実行しているMySQLのバージョンによって異なります。MySQL 5.5より前は、レプリケーションは次のように動作しました。

  • マスターがSQLを実行する
  • マスターログのSQLイベントをバイナリログに記録する
  • スレーブがマスターバイナリログからSQLイベントを読み取る
  • スレーブはI / Oスレッド経由でリレーイベントにSQLイベントを保存します
  • スレーブがSQLスレッドを介してリレーログから次のSQLイベントを読み取る
  • スレーブがSQLを実行する
  • スレーブは、SQLイベントの完全な実行のマスターを確認します

MySQL 5.5以降では、準同期レプリケーションを使用して、レプリケーションは次のように動作します。

  • マスターがSQLを実行する
  • マスターログのSQLイベントをバイナリログに記録する
  • スレーブがマスターバイナリログからSQLイベントを読み取る
  • スレーブがSQLイベントの受信のマスターを確認する
  • スレーブはI / Oスレッド経由でリレーイベントにSQLイベントを保存します
  • スレーブがSQLスレッドを介してリレーログから次のSQLイベントを読み取る
  • スレーブがSQLを実行する
  • スレーブは、SQLイベントの完全な実行のマスターを確認します

この新しいパラダイムにより、スレーブをマスターにさらに同期させることができます。

それにもかかわらず、ネットワーク内のレイテンシは、MySQLセミシンクレプリケーションを妨げ、古いスタイルの非同期レプリケーションに戻る可能性があります。どうして ?スレーブがトランザクションを確認せずにタイムアウトが発生した場合、マスターは非同期複製に戻ります。少なくとも1つの準同期スレーブが追いつくと、マスターは準同期レプリケーションに戻ります。

UPDATE 2011-08-08 14:22 EDT

MySQL 5.5半同期レプリケーションの設定は簡単です

ステップ1)これらの4行を/etc/my.cnfに追加します

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
#rpl_semi_sync_master_enabled
#rpl_semi_sync_master_timeout=5000
#rpl_semi_sync_slave_enabled

ステップ2)MySQLを再起動します

service mysql restart

ステップ3)MySQLクライアントでこれらのコマンドを実行します

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave  SONAME 'semisync_slave.so';

ステップ4)plugin-dirオプションの後に3つのrpm_semi_syncオプションのコメントを外します

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout=5000
rpl_semi_sync_slave_enabled

ステップ5)MySQLを再起動します

service mysql restart

全部できた !!!次に、通常どおりMySQLレプリケーションをセットアップします。


非同期複製の最終段階についてはわかりません。マスターがすべてのスレーブがどこまで到達したのかはわかりません。私が知る限り、彼らはバイナリログの任意の部分を要求できます。これについての参照はありますか?
shlomoid 2011

また、非同期タイプではなく、MySQLのデフォルトの非同期レプリケーションを使用しています。これは、プラグインなどをインストールして意図的に有効にする必要があります。私が理解しようとしているのは、イベントがログの開始位置からスレーブにパイプされたnet-catスタイルであるか、またはそのようなレイテンシの影響を受ける可能性のある各イベントのマスターとスレーブ間のやり取りが存在するかどうかです。
shlomoid 2011

ぜひとも、MySQL 5.5を使用して、この新しい形式のMySQLレプリケーションとInnoDBの拡張機能を利用することを強くお勧めします。
RolandoMySQLDBA 2011

1
はい、もちろんMySQL 5.5を使用していますが、これはデフォルトのレプリケーションタイプではありません。半同期的に機能させるには、設定手順全体を実行し、プラグインなどをインストールする必要があります。
shlomoid 2011

2

Rolandoがレプリケーションで実行される一連の操作をどのように説明しているかが本当に気に入っています。ただし、別のコンポーネント(クライアント)を追加すると、より明確になると思います。

クライアントでは、非同期レプリケーションの一連の操作は次のようになります。

  1. クライアントは、トランザクションを使用してSQLクエリ(たとえば、挿入)をマスターに送信します

  2. マスターがトランザクションを実行します。成功した場合、レコードはディスクに保存されますが、トランザクションはまだコミットされていません。

  3. マスターは挿入イベントをマスターバイナリログに記録しますマスターがそれをバイナリログに保存できなかった場合、トランザクションはロールバックされます。

  4. クライアントはマスターからの応答を受け取ります(成功またはロールバック)。

  5. トランザクションが成功した場合、マスターのダンプスレッドがバイナリログからイベントを読み取り、スレーブのI / Oスレッドに送信します。

  6. スレーブI / Oスレッドはイベントを受信し、それをリレーログファイルの最後に書き込みます。

  7. イベントがリレーログに入ると、スレーブSQLスレッドが
    イベントを実行して、変更をスレーブのデータベースに適用します。

このシナリオでは、マスターはスレーブを気にせず、クライアントは「SHOW SLAVE STATUS」コマンドを手動で実行することによってスレーブで何かが間違っていることを知っているだけです。

準同期レプリケーションの場合、操作のシーケンスは次のようになります。

  1. クライアントは、トランザクションを使用してSQLクエリ(たとえば、挿入)をマスターに送信します。

  2. マスターがトランザクションを実行します。成功した場合、レコードはディスクに保存されますが、トランザクションはコミットされません。

  3. マスターが挿入イベントをマスターバイナリログに記録するマスターがそれをバイナリログに保存できなかった場合、トランザクションはロールバックされ、クライアントはロールバックの場合にのみ応答を受け取ります。

  4. マスターでのトランザクションが成功したため、マスターのダンプスレッドはバイナリログからイベントを読み取り、スレーブI / Oスレッドに送信します。

  5. スレーブI / Oスレッドはイベントを受信し、それをリレーログファイルの最後に書き込みます。

  6. スレーブは、マスターがリレーログファイルにイベントを記録することを確認します。

  7. マスターは挿入トランザクションをコミットします。

  8. クライアントはマスターからの応答を受け取ります(成功)。

  9. イベントがリレーログに入ると、スレーブSQLスレッドが
    イベントを実行します。マスターとクライアントは、実行が成功したかどうかを知りません。

半同期レプリケーションは、スレーブまたはネットワークが停止し、マスターが続行し続けた場合の1つの重要なケースを解決しました。次に、マスターが停止し、そのノードを修正したという理由だけで古いスレーブを新しいマスターとして再起動したいとします。

つまり、そのノードを新しいマスターとして起動し、古いマスターを修正して、それをスレーブとして使用したいとします。そのノードにはまだデータがありますが、新しいスレーブが新しい​​マスターが開始した位置から開始する場合、レコードが重複します。

待機期間が無限の場合、スレーブのすべてのクエリが成功したと仮定すると、マスターバイナリログの位置は常にスレーブリレーログの位置と同期します。この仮定はどの程度現実的ですか?

とてもリアルだと思います。スレーブクエリが失敗する最も一般的なケースの1つは、「レコードの重複」です。マスターがスレーブに持っていなかった場合、重複したレコードはどこでスレーブに送られましたか?複製を開始するためにスレーブに与えられた間違った位置から来ました。複製開始位置には、すでに複製されたレコードが含まれていました。準同期レプリケーションの場合、この状況は発生しません。

ジェイコブ・ニコム


1

修飾子:私はMySQLユーザーではないので、ほとんどの場合、これはインターネット上での私の研究です。

ご存知のとおり、MySQLレプリケーションの最大の制限はシングルスレッドであることです。したがって、スレッドが社内スレーブへのデータの送信でビジーである間、スレッドはリモートスレーブにデータを送信できません。これはこちらです。


パーこちら

確認する必要があることの1つは、トランザクション時間を削減することです。これにより、レプリケーションスレッドはデータベースで何が行われているのかを把握することができます。トランザクションをできるだけ短くしたい。

これを行う1つの方法は、クエリを細断することです。WHERE句を使用して、UPDATEまたはDELETEによって変更された行を制限します。これをループ内に固定すると、リストを反復処理して、毎回トランザクションを開始およびコミットできます。(最初の3分の1、2分の3、最後の3分の1はそれぞれ独自のトランザクションで更新/削除します。)トランザクション間でテーブルのデータが変更される可能性があるので、個人的にこれ行うことはお勧めしません。しかし、他の誰もテーブルをいじってないことが確実である場合(そして、決してそうない場合)は、このパフォーマンスを改善する可能性があります

もう1つの可能性は、長時間実行されているトランザクションを複製せず、両方のマスター(ローカルスレーブに複製される)で実行してから、リモートスレーブで個別に実行することです。これにより、レプリケーションスレッドが解放され、30分以上に達しなくなります。


パーこちら

最後の可能性の1つは、TCPバッファーのサイズを調整することです。目標は、マスターとスレーブの間で行っている通信の数を減らすことです。これにより、待ち時間を短縮できます。

個人的には、他のすべてが失敗した場合、私はこれを試します。問題の原因は、ネットワークの遅延ではなく、シングルスレッドのレプリケーションシステムにあると私は思います。通常、ネットワークは30分経過する前にタイムアウトします。(30分?!)


JHammerbのDeliciousブックマークには、mysqlレプリケーションのリンクがいくつかあります。これらのリンクもチェックアウトする必要があります。

お役に立てば幸いです。


1
MySQLレプリケーションがシングルスレッドである方法について言及すると+1が得られますが、ステートメントを次のように修飾する必要があります。スレーブ上のローカルのSQLイベント。ただし、SQLイベントの送信はシングルスレッドで行われるため、この質問には状況に応じて適切です。
RolandoMySQLDBA

2
ところで、UPDATEまたはDELETEステートメントでLIMITを使用しないでください。更新または削除される行の順序が、スレーブとマスターで同じになるとは限らないためです。実際、これに関する警告メッセージは、エラーログに「Statement Not BinLog-Safe」のようなものとして表示されます。
RolandoMySQLDBA 2011

ああ、UPDATEとDELETEでLIMITを使用しないことについての良い点。答えを変更して削除します。
Richard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.