[質問] 分散トランザクションシナリオで読み取り/書き込み分離のデータ整合性を確保するにはどうすればよいですか

このトピックを理解すると、分散処理、読み取りと書き込みの分離、データの一貫性というキーワードが得られます。

それでは、「読み書きの分離」ですが、私の理解では、データの整合性を確保することを前提として、2つ(以上)のデータベースが異なるデータ処理タスクを担当します。昔の話は省きますが、近年ではMySQLがよく使われています。次に、MySQL に基づいて、私が主に使用した読み取り/書き込み分離テクノロジには次のものがあります。

  1. MySQL マスター/スレーブ ホット バックアップ メカニズム
  2. アリババ運河コンポーネント
  3. Apache Shardingsphere ミドルウェア

一般的に、これらの利点と欠点を要約すると、次のようになります(完全に個人的な感覚です)。

テクノロジー 機構 要約する
MySQL MySQL 独自のログ レプリケーション メカニズムを使用して、マスター ライブラリの書き込み操作が Binlog ログを通じてスレーブ ライブラリに同期され、データのバックアップと読み書きの分離が実現されます。 利点:
1. 使いやすく、追加のミドルウェアやコンポーネントは必要ありません;
2. 成熟したネイティブ テクノロジ;
3. ビジネス コードから切り離されています;
欠点:
1. データ同期は非同期であり、最終的な一貫性のみを保証でき、強力な一貫性を実現することはできません。これにより、同時実行性が高い状態ではデータの一貫した読み取りと書き込みが保証できなくなります。
2. データの同期はネットワークとディスクの安定性に依存しており、データの不完全または損失のリスクがあります (素晴らしい教訓は次のユーザーと共有されます)。 you); 3. クロス
スパン プラットフォームには互換性の問題が発生します。
アリババチャンネル MySQL Binlog の増分サブスクリプションおよび消費コンポーネントに基づいて、MySQL の増分ログをリアルタイムでキャプチャして消費できます。 利点:
1. データベースに対応する複数の製品のデータ同期を実現できます (kafka、redis、elasticsearch など);
欠点:
1. 追加の Canal サービスにより、保守および監視機能を同時に増やす必要があります;
2 . 高い同時実行性ではパフォーマンスの問題が発生します;
3. MySQL と同じバイナリログ レプリケーション メカニズムを使用すると、最終的な整合性しか保証できません。
Apache シャーディングスフィア 読み書き分離、サブデータベース、サブテーブルなどの機能をサポートするオープンソースの分散データベースミドルウェアソリューションです。 利点:
1. アプリケーションでルーティングを構成することで直接実装可能
2. 以下のような複雑な分散シナリオに適した複数のプロトコル データ同期モード:
- XA プロトコル: 2 フェーズ コミットと 3 フェーズ コミットに基づいて分散トランザクション管理を実現します。フェーズコミットプロトコル。
・BASEプロトコル:結果整合性の概念に基づいた分散トランザクション管理を実現します。
- TCCプロトコル:補償トランザクション概念に基づいた分散トランザクション管理を実現します。
- Saga プロトコル: ロングトランザクションの概念に基づいた分散トランザクション管理を実現します。
短所:
1. 構成が複雑になると、学習コストが増加します。

実際、私は以前に MyCAT を使用したことがあり、Google の Vitess についても調査しました。

MyCAT は、それが良くないと言っているのではなく、それを使用する人なら誰でもそれが分かるでしょう。アクセスコストは低く、パフォーマンスは許容範囲内ですが、機能が比較的単一であり、分散トランザクションのサポートはあまり良くありません。

Vitess は大きすぎます。非常に大規模な MySQL クラスターを持っている場合は Vitess が良い選択ですが、中小企業の場合は、より柔軟で汎用的な Shardingsphere を選択する方が間違いなく良い選択です。

質問に戻ります。上の表の比較によると、強い一貫性が必要なく、プロジェクトが小規模な場合は、MySQL のマスター/スレーブ ホット バックアップを使用して最終的な一貫性を確保できます。ただし例外もあります。たとえば、ビジネス シナリオの一部でクロスサービス データ マッピングにフェデレーション エンジンを使用する必要があるプロジェクトに遭遇したことがあります。この場合、元のマスター/スレーブのホット バックアップが影響を受けます。スレーブ ライブラリの同期は時々停止します(これは別の記事とも言えますので、機会があれば共有します)。この方法は状況に応じて使用してください。一般的に、「奇妙な」データベース エンジンが使用されていない場合には、この方法が低コストで優れたソリューションとなります。

Alibaba Canal については、業界ではすでに比較的成熟したデータ同期ソリューションであり、MySQL データを Redis または MQ に同期するために使用されてきましたが、MySQL から別の MySQL に同期することは試みられていません。ご存知のとおり、Alibaba Canal は binlog データ レプリケーションによるデータ同期も実装しているため、MySQL で MySQL を同期させたい場合は、元のマスター/スレーブ ホット バックアップを直接使用できます。Alibaba Canal はどうなったのでしょうか? つまり、Alibaba Canal は製品間での使用には適していますが、データの同期はそうではありません...

ということで、今のところ最終的には分散トランザクションの読み書き分離にApache Shardingsphere(以下「A-SS」)を使うことにしました。

A-SS は私が会社の開発フレームワークに追加したもので、同社のプロジェクトが一般的に「読み取りが多く、書き込みが少ない」ということを考慮すると、A-SS は読み取りと書き込みを分離した「書き込み」操作に主に使用され、「読み取り」操作には主に使用されます。操作は、HikariCP データベース接続プールを読み取りに直接使用します。

A-SS はもともとさまざまな分散トランザクション シナリオをサポートしているため、A-SS の構成ドキュメントを理解していれば、分散トランザクションに関するほとんどの事項は基本的に解決でき、残りは A-SS SS で完全にホストできます。といっても、いくつかの基本的な概念を明確にする必要があるため、ここでは XA プロトコルの 2 フェーズ コミットを使用するため、XA プロトコルを例にして説明します。

まず、A-SS の XA プロトコルの 2 フェーズ コミットは、X/Open 分散トランザクション処理 (DTP) モデルに基づくデータ同期テクノロジであり、複数のデータベース インスタンスまたはサービスにわたるトランザクションの強力な一貫性を保証できます。 。原理は簡単に理解できます。

  1. 分散トランザクションを送信する必要がある場合、A-SS トランザクション マネージャーはまず、トランザクションに参加しているすべてのデータベース インスタンスに送信の準備をするコマンドを送信します。
  2. 各データベース インスタンスがトランザクションで SQL を正常に実行すると、インスタンスがコミット操作を実行できることを示すコミット成功メッセージで応答します。いずれかのインスタンスが失敗した場合は、中止メッセージで応答します。
  3. A-SS は、すべてのデータベース インスタンスからコミット準備完了の成功応答を受信した後、トランザクションをすべてのインスタンスに正式にコミットするコマンドを送信します。
  4. 各インスタンスは commit コマンドを受信すると、トランザクションを正式にコミットし、トランザクションが完了するまでコミットが成功したと応答します。
  5. コミット準備フェーズ中にいずれかのインスタンスが失敗した場合、トランザクション マネージャーはトランザクションをすべてのインスタンスにロールバックするコマンドを送信し、その後トランザクション全体をロールバックします。

このような 2 フェーズ コミット プロセスを通じて、分散トランザクションがすべてのサブデータベースに正常にコミットされるか、すべてのサブデータベースが失敗した場合にはロールバックされることが保証されます。これにより、複数のデータベース インスタンスにわたる分散トランザクションの強力な一貫性が保証されます。

もちろん、A-SS は万能薬ではなく、使用上の制限も多くあり (詳細については公式ドキュメントを確認してください)、使用する場合はより注意が必要です。しかし、今のところ、ストレステスト中の書き込みパフォーマンスが少し低い(ストレステストのスクリプトに問題がある可能性があります)ことを除けば、今のところ大きな問題は見つかっていません。

おすすめ

転載: blog.csdn.net/kida_yuan/article/details/132351858