MySQL の WriteSet 並列レプリケーションの簡単な分析

MySQL の WriteSet 並列レプリケーションの簡単な分析

【歴史的背景】

私は 3 年間 MySQL-DBA として働いてきましたが、MySQL が「基本的に利用可能」、「MySQL は限界的なシステムで使用可能」から「ああ、やばい! なぜ MySQL を使わないのか」へと進化するのを目の当たりにしてきました。

諺にある通りです! 「データベースの運命は、歴史的プロセスとそれ自身の闘争の両方にかかっています!」ここでは「歴史的プロセス」については説明しません。「自己闘争」については、並列レプリケーションのいくつかの重要な時間ノードについてのみお話ししたいと思います。

一般的に、MySQL はこれまで並列レプリケーションの 3 つの重要なタイム ノード、「データベース間の同時実行」、「グループ コミット」、および「書き込みセット」を経験してきました。各世代には独自の才能があり、以前の波は浜辺で死んでいくと言えます。一般的に、後続の世代は以前の世代よりもはるかに優れています。

[ライブラリ間の同時実行]

データベース間の同時実行の理論的根拠は、インスタンス内に複数のライブラリ (スキーマ) が存在する可能性があり、異なるライブラリ間に依存関係がないことです。そのため、スレーブ側ではライブラリ (スキーマ) ごとに個別の SQL スレッドが開始されます。このように、マルチスレッド並列レプリケーションによってマスター スレーブ レプリケーションの効率を向上させることができます。

この理論は良さそうですが、実際には 1 つのインスタンスに対してビジネス ライブラリは 1 つしかないため、ライブラリ間のこのような同時実行は役に立ちません。つまり、この方法は比較的少数のシナリオに適用可能であり、この欠点は「グループ送信」まで解決されませんでした。

【グループ応募】

グループコミットの理論的根拠は次のとおりです。複数のトランザクションを同時にコミットできる場合、これは間接的にこれらのトランザクションのロックに競合がないことを示します。つまり、それぞれが異なるロックを保持し、互いに影響しません。論理的には、複数のトランザクションをグループと見なし、スレーブ上の「グループ」単位で実行するために SQL スレッドに割り当てます。これにより、複数の SQL スレッドを並列に実行できます。並列処理の粒度はデータベースに基づいていないため、「データベース間の同時実行」よりも効果があります。

これには実際にはいくつかの問題があります。データベース上である程度の同時実行性が必要であり、そうでない場合、各グループにトランザクションが 1 つしか存在しない可能性があり、これはシリアルと変わりません。この問題を解決するために、MySQL は送信前に待機する 2 つのパラメータを提供します。これにより、グループ内のトランザクションが可能な限り多くなり、並列レプリケーションの効率が向上します。

binlog_group_commit_sync_no_delay_count 」は、より低い基準を設定します。つまり、コミットする前にグループに十分なトランザクションが存在する必要があります。これにより、グループに十分なトランザクションが存在しない状態が防止されます。

複数のトランザクションの場合、MySQL は時間に基づいて別のパラメータ「 binlog_group_commit_sync_delay 」も提供します。このパラメータは、最大で待機する時間を示します。この時間が経過すると、トランザクションが完了していなくてもトランザクションはコミットされます。

個人的な経験です! 特に、これら 2 つのパラメータの適切な値を見つけるのは困難です。今日適切であっても、数日後にビジネスが変化すると不適切になる可能性があります。MySQL が独自に適応効果を実現できれば素晴らしいでしょう。この適応効果は WriteSet を通じてのみ実現できます (WriteSet はこれら 2 つのパラメータを自動的に調整することによって実現されるのではなく、まったく異なるソリューション アプローチを使用します)。

【書き込みセット】

WriteSet はどのような問題を解決しますか?もちろん、「グループ提出」の問題も解決! これは何も言わないのと同じなので、例を挙げてみましょう (より学術的な例です)。1 日目に id == 1 の行を更新し、2 日目に id == 2 の行を更新し、3 日目にスレーブが来てデータを同期したとします。 「グループ コミット」の性質上、これら 2 つの更新は異なる「グループ」にパッケージ化されます。つまり、2 つのグループが存在することになります。各グループには 1 つのトランザクションしかないため、論理的にはシリアルです。

DBA としては、これら 2 つは互いに競合せず、同じグループにパッケージ化してもデータの不整合は発生しないため、実際に同じグループにパッケージ化できることがわかります。 つまり、2つの選択肢がある

方法 1): 姉さん、あなたは大胆にも「binlog_group_commit_sync_no_delay_count」を 2 に設定しました。つまり、グループには少なくとも 2 つのトランザクションが含まれている必要があり、「 binlog_group_commit_sync_delay 」を 24 時間以上に設定します。本当にやるなら家に帰ってください。データベースが遅すぎて (最初の更新は 1 日待たされました) 完了しません!

方法 2): MySQL に、最近変更された内容を記録する小さなノートブックを使用するように指示します。今変更するデータが以前のデータと競合しない場合は、同じグループにパッケージ化できます。前の例を引き続き使用すると、2 日目に変更された値の ID は == 2 であるため、1 日目と競合せず、2 日目の更新と 1 日目の更新を同じグループに完全にパッケージ化できます。この方法では、グループ内に 2 つのトランザクションが存在し、スレーブが 3 日目にそれらを再生すると、並列効果が発生します。

この小さなノートブックは本当に素晴らしいですね。もっと大きくすることはできますか?確かに!パラメーターbinlog_transaction_dependency_history_sizeは、小さなノートブックの容量です。私の MySQL にはこの小さなノートブックがありますか? MySQL が mysql-5.7.22 より新しい場合は、小さなノートブックが組み込まれています。

つまり、「WriteSet」は巨大な「グループ送信」の基盤の上に構築されており、マスター上で自己適応型のパッケージングとグループ化が行われるため、マスターに2つのパラメータを追加するだけで済みます。

binlog_transaction_dependency_tracking = WRITESET # COMMIT_ORDER   
トランザクション書き込みセット抽出 = XXHASH64

理論については説明したので、次は実践を見てみましょう。

【WriteSetの練習】

WriteSet に基づく並列レプリケーション環境の構築方法、つまり、通常の「グループ コミット」よりもマスターに 2 つのパラメータを追加する方法については詳しく説明しません。2 つの並列レプリケーション モードでの動作の変更点のみを説明します。

1): 実行したいターゲットSQLは次のとおりです

データベース tempdb を作成します。
tempdb を使用します。
テーブル person(id int not null auto_increment primary key,name int) を作成します。

person(name) 値(1) に挿入します。
person(name) 値に挿入(2);
person(name) の値に挿入します(3);
person(name) 値に挿入(5);

2): 上記のSQLをグループ送信別にグループ化したものを見てみましょう。

3): write_setがグループ送信を最適化する方法を確認する

各挿入は並列実行できるため、同じグループ(同じlast_committed)にグループ化されていることがわかります。last_committed、sequence_number、これらの2つの値はbinlogに記録されます。binlogを解析するときは、通常、次のオプションを使用します。

mysqlbinlog -vvv --base64-output='デコード行' mysql-bin.000002

【まとめ】

WriteSet は、「グループ コミット」方式に基づいて構築された新しい並列レプリケーション実装です。これは、「グループ コミット」よりも柔軟性があります。もちろん、同時実行性の向上により、WriteSet は「グループ コミット」よりも優れたパフォーマンスを発揮します。一部の WriteSet が競合を解決できない場合は、「グループ コミット」モードにスムーズに移行できます。

上記は、MySQL WriteSet 並列レプリケーションの詳細の簡単な分析です。MySQL WriteSet 並列レプリケーションの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL 並列レプリケーションの簡単な分析
  • MySQL並列レプリケーションの簡単な説明
  • MySQL5.7 並列レプリケーションの原理と実装

<<:  HTMLにリンクを挿入する方法

>>:  nginx での書き換えジャンプの実装

推薦する

mysql-canal-rabbitmq のインストールと展開の非常に詳細なチュートリアル

目次1.1. MySQL binlog を有効にする1.2. RabbitMQ の交換とキューを構成...

MySQLクエリ最適化に必須の知識ポイントのまとめ

序文クエリの最適化は一夜にして達成できるものではありません。対応するツールの使い方を学び、他の人の経...

Bootstrap Webページレイアウトグリッドの実装

目次1. Bootstrapグリッドシステムの仕組み1.1 12グリッドシステム1.2 Bootst...

LinuxでIPを表示する方法の例

ネットワークの問題のトラブルシューティング、新しい接続のセットアップ、ファイアウォールの構成を行うと...

CSS継承方法

次の背景画像を持つ div があるとします。 次の反射効果を作成します。 方法はたくさんありますが、...

DockerでPrometheusをインストールする詳細なチュートリアル

目次1. Node Exporterをインストールする2. cAdvisorをインストールする3. ...

JavaScriptはマウスの動きに追従するボックスを実装します

この記事では、マウスの動きを追跡するためのJavaScriptの具体的なコードを参考までに紹介します...

HTML スクロールバーのテキストエリア属性の設定

1.オーバーフローコンテンツのオーバーフロー設定(設定されたオブジェクトにスクロールバーを表示するか...

CocosCreator ユニバーサルフレームワークデザインネットワーク

目次序文Websocketの使用Websocketオブジェクトの構築Websocket ステータスW...

Centos7のシステム言語を簡体字中国語に変更する方法

例示するシステムを自分でインストールする場合は、通常、システム言語をカスタマイズできます。ただし、ク...

Win10 での MySQL 8.0.20 のインストールと設定のチュートリアル

Win10 システムでの MySQL 8.0.20 のインストールと設定の超詳細なチュートリアルMy...

Apache ポートに基づいて仮想ホストを作成する例

apache: ポートに基づいて仮想ホストを作成する仮想ホスト(a、b、c)の作成を例に挙げます1)...

CentOS7 上で KVM 仮想化プラットフォームを構築する (3 つの方法)

KVM はカーネルベースの仮想マシンの略で、Linux をハイパーバイザーに変換する Linux ...

VMware12 に CentOS8 をインストールする方法 (VM 仮想マシンに CentOS8 をインストールするチュートリアル)

数日前に CentOS8 がリリースされました。8 の最初のバージョンですが、今日は VM12 に ...

NexusはAPIを使用して操作します

Nexus は RestApi を提供していますが、一部の API はまだ Groovy と組み合わ...