MySQLのマスタースレーブレプリケーション原理の分析と応用実践

Vivo インターネット サーバー チーム - Shan Yongxing

MySQL レプリケーション (マスター/スレーブ レプリケーション) とは、データの変更を 1 つの MySQL サーバーから別の MySQL サーバーまたは複数の MySQL サーバーにレプリケートできることを意味し、レプリケーション機能を通じて、データベースの高可用性とスケーラビリティをシングルポイント サービスに基づいて拡張できます。 . 待ってください。

1. 背景

MySQL は実稼働環境で広く使用されており、多くのアプリケーションやサービスが MySQL サービスに重要な依存関係を持っており、データ層の MySQL インスタンスに障害が発生すると、何の問題もなく上位層の障害が直接発生すると言えます。信頼性の高いダウングレード戦略と同時に、障害発生時のデータ損失による資産損失や顧客からの苦情の影響を回避するために、MySQL に保存されているデータの損失リスクを可能な限り軽減する必要があります。

サービスの可用性とデータの信頼性に対するこのような要件に関連して、MySQL はサーバー層で信頼性の高いログベースのレプリケーション機能 (MySQL レプリケーション) を提供し、このメカニズムの作用により、1 つ以上のスレーブを簡単に構築できるライブラリーを提供し、データベースの高可用性スケーラビリティを実現し、同時に負荷分散を実現します。

  • リアルタイムのデータ変更バックアップ

  • メイン ライブラリに書き込まれたデータは継続的に実行され、冗長スレーブ ライブラリ ノードに保持されるため、データ損失のリスクが軽減されます。

  • ノードを水平方向に拡張して読み取りと書き込みの分離をサポート

  • メイン ライブラリ自体が高い負荷にさらされている場合、読み取りトラフィックを他のスレーブ ライブラリ ノードに分散して、読み取りのスケーラビリティと負荷分散を実現できます。

  • 高可用性の保証

  • メインライブラリに障害が発生した場合、すぐにスレーブライブラリのいずれかに切り替えて、スレーブライブラリをメインライブラリに昇格させることができます。データは同じであるため、システムの動作には影響しません。

上記の機能を備えた MySQL クラスターは、ほとんどのアプリケーションと障害シナリオをカバーでき、高可用性とデータ信頼性を備えています。現在のストレージ グループが提供する実稼働環境 MySQL は、デフォルトの非同期マスター/スレーブ レプリケーション クラスターに基づいています。ビジネスに対して 99.99% の可用性と 99.9999% のデータ信頼性を保証するオンライン データベース サービス。

この記事では、MySQL のレプリケーション メカニズムの実装について詳しく説明し、データベースの可用性と信頼性を向上させるためにレプリケーション機能を具体的に適用する方法について説明します。

第二に、複製の原理

2.1 ビンログの導入

広い観点からレプリケーションの原理を説明します。バイナリ ログは、リアルタイムのデータ変更の送信とレプリケーションを実現するために、MySQL サーバー間で使用されます。ここでのバイナリ ログは、MySQL サーバーに属するログであり、行われたすべての変更を記録します。 MySQLに。このレプリケーション モードも、特定のデータの特性に応じて 3 つのタイプに分類できます。

  • ステートメント: ステートメントの形式に基づく

  • ステートメント モードでは、マスター データベースで実行された元の SQL 文がレプリケーション プロセス中のデータ取得のためにスレーブ データベースに送信され、マスター データベースは実行された元の SQL 文をスレーブ データベースに送信します。

  • 行: 行形式に基づく

  • 行モードでは、マスター データベースは、各 DML 操作によって引き起こされたデータの特定の行変更を Binlog に記録し、それらをスレーブ データベースにコピーします。スレーブ データベースは、行変更レコードに従って対応してデータを変更しますが、DDL type 操作は依然として Statement 形式のレコードの形式です。

  • 混合: 混合ステートメントと行フォーマットに基づく

  • MySQL は、実行される特定の SQL ステートメントごとに、記録されるログ形式を区別します。つまり、ステートメントと行の間で 1 つを選択します。

最も初期の実装は、バージョン 3.23 で MySQL に導入されたステートメント形式に基づいていました。これは最初から MySQL Server 層の機能であり、使用される特定のストレージ エンジンとは何の関係もありませんでした。バージョン 5.1 以降は、行ベースのレプリケーションのサポートを開始しました。5.1 では、バージョン .8 以降、混合形式のレプリケーションがサポートされています。

これら 3 つのモードにはそれぞれ長所と短所があります。比較的に、Row に基づく行形式がより広く使用されています。このモードではリソースのオーバーヘッドが比較的大きくなりますが、データ変更の精度と信頼性は Statement よりも優れています。同時に、このモードの Binlog は完全なデータ変更情報を提供するため、そのアプリケーションは MySQL クラスター システムに限定されず、Binlogserver、DTS データ送信などのサービスで使用して、柔軟なクロスシステムを提供できます。データ転送能力を考慮すると、現在のインターネット ビジネス用のオンライン MySQL クラスターはすべて Binlog in Row 形式に基づいています

2.2 Binlog の要点

2.2.1 バイナリログイベントタイプ

Binlog の定義では、一連の単一イベントと考えることができ、これらの個々のイベントは主に次のカテゴリに分類できます。

さまざまなイベントの発生には重要なパターンがあります。

  • XID_EVENT はトランザクションの終了をマークします

  • DDL タイプの QUERY_EVENT が発生すると、それはトランザクションのエンドサブミットポイントでもあり、XID_EVENT は表示されません

  • GTID_EVENT は GTID_MODE のみを有効にします (MySQL バージョンは 5.6 以降)

  • TABLE_MAP_EVENT は特定のテーブルの変更データの前に出現する必要があり、1 対多の ROW_EVENT の状況が発生します

上記のデータに近いイベント タイプに加えて、ROTATE_EVENT (Binlog ファイルが分割されたことを示す)、FORMAT_DESCRIPTION_EVENT (メタデータ形式を定義する) などがあります。

2.2.2 ビンログのライフサイクル

Binlog と Innodb Log (redolog) の存在は異なります。ファイルを繰り返しローテーションして上書きすることはありません。サーバーは、設定された単一の Binlog ファイル サイズ構成に従って継続的に分割して新しい Binlog を生成し、.index ファイルに記録します。すべての binlog現在のハードディスク上のファイル名を削除すると同時に、binlog の有効期限に応じて期限切れの binlog ファイルを削除します。これら 2 つの自社構築データベースの構成は 1G のシングル サイズで、7 日間保存されます。

したがって、この仕組みの背景では、履歴データの状態は短期間にしか追跡できず、まだログを経験していないサーバーでない限り、データベースのデータ変更を完全に追跡することは不可能です。有効期限とリサイクル。 

2.2.3 バイナリログイベントの例

binlog はサーバー層で有効です。メイン ライブラリをコピーしているスレーブ ライブラリがない場合でも、構成で log_bin が有効になっている限り、binlog ファイルは対応するローカル ディレクトリに保存されます。mysqlbinlog を使用してサンプル binlog ファイルを開きます。行の形式:

上の図に示すように、データベース テストの作成、データ テーブル テストの作成、1 回の書き込みによる行の変更、および読み取り可能なステートメント (作成、変更、ドロップ、開始、コミット....) の 3 つの操作がはっきりとわかります。 QUERY_EVENT として考えることができ、Write_rows は ROW_EVENT の 1 つです。

レプリケーション プロセス中に、このような Binlog データは確立された接続を通じてスレーブ ライブラリに送信され、スレーブ ライブラリが処理して適用するのを待ちます。

2.2.4 ベースライン値のコピー

ビンログは生成時に厳密に順序付けされますが、第 2 レベルの物理タイムスタンプしか持たないため、位置決めや並べ替えに時間に依存することは信頼できません。同じ秒間に数百または数千のイベントが発生する可能性があります。つまり、Binlog で水位を特定するには、効果的で信頼性の高いレコード値も必要です。MySQL Binlog は、従来の Binlog File:Binlog Position モードとグローバル トランザクションという 2 つの形式のレプリケーション参照値をサポートしています。シリアル番号 GTID はバージョン 5.6 以降で利用可能です。

  • ファイルの位置

log_bin が有効である限り、MySQL にはファイル位置の位置レコードがあり、GTID の影響を受けません。

File: binlog.000001
Position: 381808617

この概念は比較的直感的で、対応するファイル数の Binlog ファイル内に存在するものとして直接理解でき、同時に合計 Position バイトのデータが生成されています。例に示すように、インスタンスは 381808617 バイトの Binlog を生成しました。この値は、対応するマシンで直接表示されるファイルのサイズとも一致するため、ファイル位置はファイルの順序とサイズの対応する値になります。

このモードに基づいてレプリケーションを有効にするには、レプリケーション関係で対応するファイルと位置を明示的に指定する必要があります。

CHANGE MASTER TO MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POSITION=381808617;

このモードでライブラリから取得されるデータは有効開始点に完全に依存するため、この値は正確である必要があります。そのため、偏差がある場合、データが失われるか、データの重複が実行されてレプリケーションが中断されます。

  • GTID

MySQL は、GTID_MODE=ON の状態にある各トランザクションに一意のグローバル トランザクション ID を割り当てます。形式は次のとおりです。server_uuid:id

Executed_Gtid_Set: e2e0a733-3478-11eb-90fe-b4055d009f6c:1-753

このうち、e2e0a733-3478-11eb-90fe-b4055d009f6c は、Binlog イベントを生成したインスタンスを一意に識別するために使用され、1 ~ 753 は、e2e0a733-3478-11eb-90fe-b4055d009f6c インスタンスによって生成された 753 個のトランザクションが生成されたことを示します。受け取った;

スレーブ ライブラリがメイン ライブラリから Binlog イベントを取得すると、自身の実行レコードは、取得したマスター ライブラリの Binlog GTID レコード、またはスレーブ ライブラリが存在する場合は e2e0a733-3478-11eb-90fe-b4055d009f6c:1-753 と一致します。 e2e0a733- 3478-11eb-90fe-b4055d009f6c がレプリケーションを有効にしている場合、ライブラリ自体から show master status を実行すると、同じ値が表示されます。

スレーブ ライブラリ上でコピーされたマスター ライブラリと一致しない値が表示される場合は、誤った GTID があると考えられます (通常、スレーブ ライブラリでのマスター/スレーブの切り替えまたは強制的な書き込み操作が原因です)。 、スレーブ ライブラリの Binlog GTID はメイン ライブラリの GTID と一致している必要があります。

このモードに基づいてコピーを開始するには、ファイル位置などの特定の値を指定する必要はなく、以下を設定するだけで済みます。

CHANGE MASTER TO MASTER_AUTO_POSITION=1;

スレーブ ライブラリは Binlog を読み取った後、自身の Executed_GTID_Set レコードに従って、実行済みまたは未実行の Binlog トランザクションがあるかどうかを自動的にチェックし、対応する無視および実行操作を実行します。

2.3 コピーの具体的なプロセス

2.3.1 基本的なレプリケーションプロセス

メイン ライブラリが binlog を有効にし ( log_bin = ON )、binlog を正常に記録した場合、レプリケーションを有効にするにはどうすればよいですか?

ここでは、MySQL のデフォルトの非同期レプリケーション モードについて説明します。

  1. まず、ライブラリからI/Oスレッドを開始し、メイン ライブラリとのクライアント接続を確立します。

  2. メイン ライブラリはbinlog ダンプスレッドを開始し、メイン ライブラリの binlog イベントを読み取り、スレーブ ライブラリの I/O スレッドに送信します。I/O スレッドは binlog イベントを取得した後、それを独自のリレー ログに書き込みます。

  3. ライブラリからSQLスレッドを開始し、リレー内のデータが再生されるのを待ち、ライブラリからのデータ更新を完了します。

要約すると、マスター ライブラリにはスレッドが 1 つだけ、スレーブ ライブラリにはスレッドが 2 つだけ存在します。

  • タイミング関係

クラスターが実行状態になると、スレーブ ライブラリは引き続きメイン ライブラリから Binlog イベントを受信し、対応する処理を実行し、このプロセスは次のデータ フロー メソッドに従います。

  1. マスターはデータ変更を Binlog に記録し、BinlogDump スレッドは書き込みリクエストを受信した後、対応する Binlog を読み取ります。

  2. ビンログ情報はスレーブの I/O スレッドにプッシュされます。

  3. スレーブ I/O スレッドは、読み取った Binlog 情報をローカルのリレー ログに書き込みます。

  4. スレーブの SQL スレッドは、リレー ログの内容を読み取り、スレーブ ライブラリ上で実行します。

上記のプロセスはすべて非同期操作であるため、DDL によるフィールドの変更、多数の行に影響を与える書き込み、更新、または削除操作など、一部の大規模な変更では、マスターとスレーブ間の遅延が急増します。 , MySQL の上位バージョンでは、ライブラリからのトランザクションの再生速度の向上に役立ついくつかの新機能が徐々に導入されています。

  • リレーログの意味

リレー ログは、本質的に binlog と同じログ ファイルとみなすことができます。この 2 つをローカルで直接開いたとしても、違いはほとんど見つかりません。

ビンログ バージョン 3 (MySQL 4.0.2 ~ < 5.0.0)

リレーログを追加し、ログ位置の意味を変更しました

MySQL 4.0 より前には、リレー ログはなく、プロセス全体でスレッドが 2 つしかありませんでした。しかし、これにはレプリケーション処理を同期的に実行する必要があり、影響を受けやすく、効率が高くないという問題もあります。たとえば、メイン ライブラリは、次の binlog イベントを送信する前に、スレーブ ライブラリが読み取りを完了するまで待つ必要があります。これは、ブロッキング チャネルとノンブロッキング チャネルに似ています。

リレー ログがプロセスに追加されると、元の同期取得イベントと再生イベントが分離され、2 つのステップを非同期で実行できるようになり、リレー ログがバッファとして機能します。リレー ログには、現在のレプリケーションの進行状況と次のイベントが書き込まれる位置を記録するために使用される、relay-log.info ファイルが含まれています。このファイルは、SQL スレッドによって更新されます。

後から徐々に導入される特殊コピーモードでは多少の違いはありますが、全体的にはこのような流れで行われます。

2.3.2 準同期レプリケーション

非同期レプリケーションのシナリオでは、スレーブ ライブラリがマスター ライブラリと一貫した状態にリアルタイムで更新されることを保証することは不可能であるため、遅延を背景にマスター ライブラリに障害が発生した場合、2 つのライブラリの差分データを取得することはできません。この場合、読み取りと書き込みの分離が行われ、非同期から完全同期に変更すると、パフォーマンスのオーバーヘッドが大幅に増加し、要求を満たすことが困難になります。実際の使用ニーズ。

このような背景を踏まえ、MySQL はバージョン 5.5 以降、データ損失の可能性を減らすために半同期レプリケーション メカニズムを導入しており、このレプリケーション モードでは、マスターがスレーブ ノードからの ACK (確認応答文字) メッセージを一定時間待機するようになります。 ACK メッセージを受信した後にトランザクションがコミットされるため、パフォーマンスへの影響が軽減されるだけでなく、非同期レプリケーションよりも強力なデータ信頼性が得られます。

準同期レプリケーションを導入する前に、マスター/スレーブ レプリケーションが発生したときの MySQL トランザクション書き込みの完全なプロセスを簡単に見てみましょう。マスター データベース トランザクション書き込みは 4 つのステップに分かれています。

  1. InnoDB REDO ファイル書き込み (準備書き込み)

  2. ビンログ ファイルのフラッシュとビンログ ファイルへの同期

  3. InnoDB Redo ファイルコミット(コミット書き込み)

  4. ビンログをスレーブに送信する

  • マスターがスレーブが Binlog イベントを受信するかどうかを意識する必要がない場合、非同期マスター/スレーブ レプリケーションになります。

  • 3 番目のステップ Commit Write がクライアントに応答する前にマスターがスレーブの ACK を待つ必要がある場合、それは半同期レプリケーション (コミット後) です。

  • Flush&Sync の 2 番目のステップ、つまりコミットの前にマスターがスレーブの ACK を待つ必要がある場合、半同期レプリケーション (同期後) が強化されます。

  • タイミング関係

準同期レプリケーションのタイミング図から判断すると、実際にはマスターライブラリのコミットリンクでスレーブライブラリからのACKを待っている段階に過ぎず、スレーブノードからのACKは1つだけで済みます。このモードでは、メインライブラリがダウンした場合でも、少なくとも 1 つのスレーブライブラリノードが利用可能であることが保証され、同期時の待ち時間も短縮されます。

2.3.3 概要

現在の本番環境のオンライン データベース バージョンのコンテキストでは、MySQL によって公式に提供されているレプリケーション方法は主に上記のとおりですが、もちろん、MySQL ベースまたは MySQL と互換性のある多くの派生データベース製品がまだあります。使いやすさと信頼性の向上の観点から、この記事ではこの部分の詳細な説明は行いません。

2.4 レプリケーションの特徴

これまで述べてきたレプリケーション方法には、非同期レプリケーションではスレーブ ライブラリのデータが遅延し、半同期レプリケーションではマスター ライブラリの書き込みがブロックされ、パフォーマンスに影響を与えるデータ遅延のシナリオが避けられないという注目すべき特徴があります。

MySQL の初期レプリケーション モードでは、スレーブ ライブラリの IO スレッドと SQL スレッドは基本的にイベントをシリアルに取得し、それらを読み取って再生します。リレーログの実行を担当するスレッドは 1 つだけですが、メイン ライブラリ自体はリクエストを同時に受信でき、パフォーマンスの上限 マシン リソースのボトルネックと MySQL の処理能力の上限によってのみ、マスター ライブラリの実行とスレーブ ライブラリの実行 (SQL スレッド アプリケーション イベント) を調整することは困難です。テストデータのセット:

  • マシン: 64 コア 256G、MySQL 5.7.29

  • テスト シナリオ:通常の INSERT、UPDATE 圧力テスト シナリオ

  • 結果: MySQL Server の IO スレッド速度はネットワーク上のデータ量で評価され、1 秒あたり 100MB を超えており、通常ビジネス用途をカバーできますが、SQL スレッドの推定速度は 21 ~ 23MB/s にすぎません。 UPDATE シナリオが含まれるため、パフォーマンスも低下します。

  • なお、上記の結果はMySQLの上位バージョンに並列レプリケーション機能があることを前提としており、この機能が無いバージョンの場合はパフォーマンスが低下します。

ビジネス レイヤーでの使用が制限されることを期待するのは非現実的です。MySQL はバージョン 5.6 で利用可能な並列レプリケーション ソリューションの導入を試み始めました。一般的に言えば、それはスレーブ ライブラリ レベルでアプリケーションの速度を向上させることによって行われます。

2.4.1 スキーマレベルに基づく並列レプリケーション

データベース レベルに基づく並列レプリケーションは非常に単純な原理に基づいており、インスタンス内の異なるデータベース/スキーマのデータとデータの変更は無関係であり、並列処理できます。

このモードでは、MySQL スレーブ ノードが複数の WorkThread を開始し、再生を担当する元の SQLThread がコーディネーター ロールに変換され、トランザクションを並行して実行して WorkThread に分散できるかどうかを判断する責任を負います。

トランザクションが異なるスキーマに属しており、DDL ステートメントではなく、スキーマ間操作がない場合、トランザクションは並行して再生できます。それ以外の場合は、トランザクション内のコンテンツを実行する前に、すべてのワーカー スレッドが実行を完了するまで待機する必要があります。現在のログ。

MySQL Server
 
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aksay_record       |
| mysql              |
| performance_schema |
| proxy_encrypt      |
| sys                |
| test               |
+--------------------+
7 rows in set (0.06 sec)

スレーブ ライブラリの場合、メイン ライブラリから aksay_record と proxy_encrypt のデータ変更を受け取ると、スキーマのこれら 2 つの部分のデータを同時に処理できます。

ただし、この方法には明らかな欠陥や欠陥もあります。まず、複数のスキーマのトラフィックがバランスされている場合にのみ、パフォーマンスが大幅に向上します。ただし、ホットスポット テーブルがある場合、またはインスタンス上の 1 つのスキーマのみにデータ変更がある場合は、この並列モードは、初期のシリアル レプリケーションと違いはありません。同様に、異なるスキーマのデータに関連性はありませんが、このような並列実行は、トランザクションの実行順序にも影響を与えます。サーバー全体の因果的一貫性は、ある程度まで影響を受けます。破壊されます。

2.4.2 グループコミットベースのレプリケーション(グループコミット)

スキーマに基づく並列レプリケーションは、複数のテーブルを持つ 1 つのデータベースの場合など、ほとんどのシナリオでは効果的ではありませんが、スレーブ データベースの単一の実行スレッドを変更するというアイデアは継続されています。バージョン 5.7 では、トランザクション グループ ベースのコミットが追加されます。 並列レプリケーション方法では、レプリケーションに適用されるグループ コミット戦略を具体的に導入する前に、トランザクションをコミットするサーバー独自の Innodb エンジンのロジックを導入する必要があります。

binlog ストレージは sync_binlog の設定に基づいており、通常は sync_binlog=1 が使用されます。つまり、トランザクションが送信されるたびに fsync が開始されます。

メイン ライブラリが大規模なトランザクションを同時に実行する場合、トランザクションごとにディスク上にロックが設定されるため、すべての Binlog がディスク上に連続して配置され、パフォーマンスのボトルネックになります。この問題を解決するために、MySQL 自体がバージョン 5.6 でトランザクションのグループ コミット機能を導入しました (これはスレーブ ライブラリに適用されるロジックを指しません)。設計原理は理解しやすく、リソースが取得できる限り、同時に、すべての準備トランザクションをすべて同時に送信できます。

メイン ライブラリにこの機能があるという背景の下で、スレーブ ライブラリも同様のメカニズムを適用してトランザクションを並列実行できることが簡単にわかります。以下では、MySQL の特定の実装の 2 つの段階について説明します。

  • 親ベースのコミット

MySQL での書き込みはロックベースの同時実行制御に基づいているため、マスター側で同時に準備フェーズにあるコミットされていないトランザクションはすべてロックの競合がなく、スレーブ側で実行するときに並行して実行できます。

したがって、すべてのトランザクションが準備フェーズに入ると、論理タイムスタンプをマークすることができ (実装では最後にコミットされたトランザクションの sequence_number が使用されます)、スレーブ側で同じタイムスタンプを持つトランザクションを同時に実行できます。

ただし、このモードは前のトランザクション グループの送信に依存するため、リソース制約のない同時トランザクションの場合は、コミットの親が送信されていないため実行できません。

  • ロジックベース

Commit-Parent-Based に存在していた制限が解除されました。純粋に理解すると、現在のトランザクションの sequence_number のみが同時に実行できます。同時に実行できるのは、ロックが取得でき、競合がないかどうかに基づいてのみです。コミットされたトランザクションの sequence_number。

3. アプリケーション

現在、vivo のオンライン MySQL データベース サービスの標準アーキテクチャは、マスター、スレーブ、オフラインの非同期レプリケーション クラスターに基づいており、そのうちの 1 つはビジネス読み取りリクエストを分離するために使用され、オフライン ノードは読み取りサービスを提供せず、オフラインおよびリアルタイムのデータ抽出を提供します。ビッグ データ用 DB プラットフォームのクエリとバックアップ システムの使用。このようなアプリケーションの背景に合わせて、ストレージ研究開発チームは MySQL シナリオ用に 2 つの追加の拡張サービスを提供しています。

3.1 高可用性システム+ミドルウェアの適用

MySQL のマスター/スレーブ レプリケーションはシステムの高可用性を向上させることができますが、MySQL にはバージョン 5.6 および 5.7 の Redis のような自動フェイルオーバー機能がありません。メイン データベースに障害が発生して介入しない場合、実際にはビジネスは正常に書き込まれません。はい、障害時間が長い場合、スレーブ ライブラリでの個別の読み取りも信頼できなくなります。

3.1.1 VSQL (オリジナルの高可用性 2.0 アーキテクチャ)

次に、現在の標準の 1 マスター 2 スレーブ アーキテクチャに基づいて、HA 高可用性コンポーネントとミドルウェア コンポーネントをシステムに追加して、MySQL サービスの高可用性、読み取りスケーラビリティ、およびデータ信頼性を強化します。

  • HA コンポーネントは、MySQL のレプリケーション トポロジを管理し、クラスターの健全性ステータスを監視し、障害シナリオでの自動フェイルオーバーを管理します。

  • ミドルウェア プロキシは、トラフィックを管理し、元のドメイン名シナリオでの遅い変更解決や非効率なキャッシュの問題に対処し、読み取りと書き込みの分離を制御し、IP と SQL のブラック リストとホワイト リストを実現するために使用されます。等。;

3.1.2 データの信頼性向上

データ自体は依然として MySQL のネイティブ マスター/スレーブ レプリケーション モードに依存してクラスター内で同期しているため、非同期レプリケーション自体のリスクが依然として存在します。このシナリオでは、3 つの実現可能なソリューションを提供します。

  • ログリモートレプリケーション

HA のセントラル ノードとネットワーク全体の MySQL マシンのログイン マシンを構成した後、従来の MHA ログ ファイル レプリケーション補償スキームに従って、障害が発生したときにデータが失われないようにします。障害が発生したノードのローカル ファイル ディレクトリを使用してマスター候補を読み取ります。ノードの欠落している Binlog データがマスター候補で再生されます。

アドバンテージ

  • 1.0 の MHA スキームと一致しており、古いメカニズムを直接使用できます。

  • メカニズムが変換された後は、マシン間の秘密のない相互信頼を必要とせずに、高可用性機能に組み込むことができるため、権限要件とセキュリティ リスクが軽減されます。

不利益

  • 障害のあるノードが存在するマシンにアクセス可能であり、ハードディスクが正常である必要がありますが、ハードウェアまたはネットワークの異常には対応できません。

  • ネットワーク上のリンクが長く、中間再生ログの消費時間を制御できない可能性があり、その結果、サービスが長時間利用できなくなる可能性があります。

  • 一元化されたログストレージ

データ転送サービスの BinlogServer モジュールに依存して、Binlog ログの集中ストレージ機能を提供します。HA コンポーネントは、MySQL クラスターと BinlogServer を同時に管理し、MySQL アーキテクチャの堅牢性を強化します。スレーブ データベースはすべて BinlogServer 上に確立され、マスター データベースには直接接続されません。

アドバンテージ

  • ログの保存形式 (ファイル システムまたはその他の共有ストレージ モード) をカスタマイズできます。

  • マシンの可用性と権限に関係しない問題

  • binlog (バックアップ) のストレージのセキュリティを間接的に向上させます。

不利益

  • 追加のリソース使用量。ログを長期間保持する必要がある場合、リソース使用量が多くなります。

  • 準同期が有効になっていない場合、収集 (IO スレッドに相当) 速度がリレー速度を大幅に超えた場合でも、すべての binlog ログが収集できる保証はなく、制限は約 110MB/s です。

  • システムの複雑さが増すと、追加のリンクを導入するリスクが必要になります

  • 半同期レプリケーションへの変更

MySQL クラスターは準同期レプリケーションを有効にし、構成による機能低下を防ぎます (リスクが高くなります)。エージェント自体が準同期クラスターの関連監視をサポートしているため、フェイルオーバー中のログ損失の量を削減できます (非同期レプリケーションと比較して)。

アドバンテージ

  • MySQL のネイティブ メカニズムは追加のリスクを導入する必要がありません

  • 本質的には、高可用性 (MySQL クラスター自体) の機能を強化しています。

  • HA コンポーネントは、変更を加えることなく、半同期クラスターにシームレスに接続できます。

不利益

  • 互換性のないバージョンが存在するため、開けない可能性があります

  • 企業はパフォーマンスの低下による影響を受け入れられない可能性があります

  • 準同期では、データがまったく失われないことは保証できません。エージェント独自のメカニズムでは、実際には、「ログが最も多い」スレーブ ノードではなく、「実行が最も多い」スレーブ ノードが優先されます。

オーケストレーターは、リレー ログ内のデータが多いレプリカではなく、より多くのイベントを実行したレプリカを昇格させます。

現在、ログ リモート レプリケーション ソリューションを使用しており、今年はデータ セキュリティを強化するために集中ストレージ用の BinlogServer ソリューションを計画していますが、準同期も読み取り複数の有効かつ実行可能な方法であることは言及する価値があります。 -write 少数の企業の場合、クラスターをアップグレードする機能を実際に検討できます。これにより、読み取りトラフィックの分離の精度が本質的に保証されます。

3.2 データ送信サービス

3.2.1 Binlog に基づくシステム間データ転送

Binlog を使用することで、MySQL データ ストリームを MySQL、ElasticSearch、Kafka、その他の MQ などの他のシステムにリアルタイムで転送することは、すでに非常に古典的なアプリケーション シナリオとなっています。MySQL によってネイティブに提供される変更されたデータを同期する機能により、これが実際に効果的になります。さまざまなシステム間の時間連携を実現するために、MySQL の収集の DTS (Data Transfer Service) も、上で紹介したレプリケーション原理と同じ方法に基づいており、MySQL のスレーブノードと同じ仕組みを使用してデータを取得する方法を紹介します。コピーを可能にするための拡張された導入を完了します:

(1) Binlogの入手方法

一般的な方法は 2 つあります。

  • ログ収集システムの操作と同様に、Binlog ファイルを監視します。

  • MySQL Slaveの仕組み、コレクタがSlaveのふりをして実現する

この記事では、2 番目の方法である Fake Slave の実装のみを紹介します。

(2) スレーブ ID の登録

ここではGO SDKを例に挙げますが、GOのバイト範囲は0~255であり、他の言語もそれに応じて変換できます。

data := make([]byte, 4+1+4+1+len(hostname)+1+len(b.cfg.User)+1+len(b.cfg.Password)+2+4+4)
  1. ビット 0 ~ 3 は 0 であり、意味はありません

  2. 4 番目のビットは MySQL プロトコルの Command_Register_Slave で、バイト値は 21 です。

  3. ビット 5 ~ 8 は、リトル エンディアン エンコードを使用して現在のインスタンスによって事前設定された server_id (uuid、値ではありません) の 4 バイトです。

  4. 次の数ビットは、現在のインスタンスのホスト名、ユーザー、パスワードです。

  5. 次の 2 ビットは、リトルエンディアンでエンコードされたポート値です。

  6. 通常、最後の 8 ビットは 0 に設定され、最後の 4 ビットは master_id を参照し、偽のスレーブは 0 に設定できます。

(3) コピーコマンドを開始します。

data := make([]byte, 4+1+4+2+4+len(p.Name))

  1. ビット 0 ~ 3 も 0 に設定されますが、特別な意味はありません。

  2. 4 番目のビットは MySQL プロトコルの Command_Binlog_Dump で、バイト値は 18 です。

  3. ビット 5 ~ 8 は、Binlog Position 値のリトルエンディアン エンコードによって生成される 4 ビット バイトです。

  4. 9 番目から 10 番目の数字は MySQL Dump のカテゴリで、デフォルトは 0 で、Binlog_Dump_Never_Stop を参照し、2 つの 0 値にエンコードされます。

  5. ビット 11 ~ 14 は、リトル エンディアン エンコードに基づくインスタンスの server_id (非 uuid) の 4 バイト値です。

  6. 最後の数桁は Binlog ファイル名に直接追加されます

上記の 2 つのコマンドがクライアント接続を通じて実行されると、マスター ライブラリ上で有効なレプリケーション接続が確認できます。

3.2.2 並列コピー モードを使用してパフォーマンスを向上させる

上記の 2 つのコマンドがクライアント接続を通じて実行されると、マスター ライブラリ上で有効なレプリケーション接続が確認できます。

初期のパフォーマンス テストの結果によると、最適化を行わない場合、ネットワーク上の平均伝送速度は約 7.3MB/s であり、ネットワーク上の平均伝送速度は約 7.3MB/s であり、MySQL の SQL よりもはるかに遅れています。リレー速度: 高電圧シナリオでの需要を満たすのは困難です。

DTS 消費ユニットは、Kafka から消費されるイベントのトランザクション再編成と同時トランザクション分析を実現しますが、実際の最終実行は引き続き MySQL にシリアルかつシングルスレッドで再生されます。このプロセスにより、パフォーマンスのボトルネックは完全にシリアル実行に集中します。 。

  1. MySQL 5.7 より前は、トランザクションの Schema 属性を使用して、異なるデータベースでの DML 操作をスタンバイ データベースで同時に再生できるようにしていました。最適化後は、異なるテーブルでの同時実行を実現できます。ただし、ビジネスがマスター側で同時にライブラリ (または最適化されたテーブル) に書き込まれる場合、スレーブ側で大きな遅延が発生します。スキーマベースの並列レプリケーションでは、スレーブが読み取り専用インスタンスとして読み取り機能を提供すると、同じスキーマの下でのトランザクションの因果的順序を保証できます (因果的一貫性。この記事で一貫性について説明する場合、スレーブ側が読み取り専用) ですが、異なるスキーマ間のトランザクションは保証できません。例えば、トランザクションの実行順序を気にする業務の場合、マスター側のdb1にT1を書き込み、T1の戻りを受けてdb2でT2を実行します。ただし、スレーブ側では、T2のデータを先に読み出し、その後T1のデータを読み出す場合もあります。

  2. MySQL 5.7 の LOGICAL CLOCK 並列レプリケーションでは、スキーマの制限がなくなり、マスター データベースのデータベースまたはテーブルで同時に実行されるトランザクションをスレーブ側でも並列実行できるようになります。論理クロック並列レプリケーションの実装は元々コミット親ベースであり、同じコミット親のトランザクションを同時に実行できます。ただし、この方法では、競合がないことを保証できるトランザクションを同時に実行することはできず、トランザクションは、前のコミット親グループのすべてのトランザクションが再生されるまで待機してから実行する必要があります。その後、トランザクションと現在実行中のトランザクションのロック間隔が重複している限り、つまりマスター側でロックの競合が発生しないように、ロックベースの方法に最適化されます。スレーブ側で同時に実行できます。LOGICAL CLOCK は、トランザクションの非同時実行を保証できます。つまり、1 つのトランザクション T1 が実行されると、別のトランザクション T2 がシナリオ内の因果的一貫性の実行を開始します。

(1) コネクションプールの変換

古いバージョンの DTS では、各消費タスクは MySQL の長い接続を 1 つだけ維持しており、消費リンクのすべてのトランザクションはこの長い接続上で逐次実行され、パフォーマンスに大きなボトルネックが発生するため、トランザクションの同時実行要件を考慮すると、接続を同時に再利用することは不可能であるため、元の単一の接続オブジェクトを変換し、接続プールと同様のメカニズムにアップグレードする必要があります。

go-mysql/client パッケージ自体には接続プールモードは含まれておらず、トランザクション同時実行解析の同時実行数に基づいて、起動時に存続接続数が拡張されます。

// 初始化客户端连接数
se.conn = make([]*Connection, meta.MaxConcurrenceTransaction)

(2) 同時選択接続

  • ロジッククロックを使用する

GTID レプリケーションを有効にするモードでは、ビンログ内の GTID_EVENT のテキストには 2 つの値が含まれます。

LastCommitted  int64
SequenceNumber int64

lastCommitted は同時実行性の基礎となります。原則として LastCommitted と同等のトランザクションが同時実行可能です。元のトランザクション同時実行数分析と組み合わせることで、同時実行数 (設定値) のトランザクション セットが生成されます。このリストを分析して判断します。 、トランザクションを接続プールに送信して、おおよその負荷分散メカニズムを実現します。

  • 非同時項目の相互排他

同時実行シナリオの場合、負荷分散に似たメカニズムを使用して接続プールから mysql 接続を横断し、対応するトランザクションを実行することができますが、ソース トランザクション自体には論理クロック内のシーケンスがあることに注意してください。このシナリオでは、concurrent prepare を使用した一部のトランザクションは同時に実行できますが、同時に実行できないトランザクションもかなりの数あります。それらは明らかにトランザクション キュー全体に分散しており、同時トランザクション (少なくとも 2 つ) は実行できないと考えられます。同時実行トランザクションに囲まれる:

6 つの要素を持つトランザクション キューがあり、そのうち t1、t2、t5、t6 のみが同時に実行できると仮定します。t3 が実行されるときには、t1 と t2 が実行されている必要があり、t5 が実行されるときには、t3 と t3 の両方が実行されている必要があります。 t4が実行されました。

(3) チェックポイントの更新

同時トランザクション実行シナリオでは、水位の低いトランザクションが後から実行され、水位の高いトランザクションが先に実行されますが、本来の仕組みでは、水位の低いトランザクションが高い水位をカバーすることになり、一定のリスクが生じます。 :

  1. Write_Event の構造 SQL は、書き込みイベントの競合や繰り返しを回避できるように置き換えられるように調整されており、更新と削除は論理クロックの同時実行性の保証に基づいており、表示されません。

  2. 水位は上がるだけで下がりません。

しかし、最適化の方法に関係なく、トランザクションの同時実行は、同時トランザクションの制御不能なロールバック、ターゲット インスタンスとソース インスタンス間の因果関係の破壊など、より多くのリスクを必然的にもたらします。企業はそれに応じてトレードオフを行うことができます。同時実行を有効にするかどうかは、独自のニーズに合わせて変更できます。

論理クロックに基づいた同時トランザクション実行変換後、コンシューマの実行パフォーマンスは、同じテスト シナリオで 7.3MB/s から約 13.4MB/s に向上できます。

(4) まとめ

消費タスク自体のライブラリとテーブルのフィルタリングに基づいて、別の形式の同時実行を実現でき、複数の消費タスクを開始して、それぞれ異なるライブラリとテーブルをサポートできます。これは、Kafka のマルチコンシューマ グループ サポートの使用でもあります。水平方向に拡張できます。同時実行パフォーマンスを向上させ、データ移行シナリオに適用するために、この部分は特別なサポートを提供できます。

論理クロックに基づく方法は、現在のネットワーク上で GTID が有効になっていない大規模クラスターには効果的ではないため、上位バージョンの機能である Write Sets を組み合わせるなど、この部分のより良い解決策を模索してきました。パフォーマンスの最適化を行うため。

4. まとめ

最後に、MySQL のレプリケーション機能は、MySQL データベース サービス自体の可用性と信頼性を大幅に向上させるだけでなく、データの適用範囲を拡張するための非常に柔軟でオープンなデータ インターフェイスである Binlog も提供します。この「インターフェイス」を使用することで、複数の異なるストレージ構造と環境でデータのリアルタイム同期を簡単に実現できます。将来的には、ストレージ グループは、データ セキュリティの保証とダウンストリームを含む (ただしこれに限定されない) MySQL アーキテクチャを強化するために、BinlogServer の拡張サービスにも注力する予定です。データリンク開設など

参考文献:

おすすめ

転載: blog.csdn.net/vivo_tech/article/details/130056126