ホームページ  >  記事  >  バックエンド開発  >  Go言語で分散トランザクション処理を実装するにはどうすればよいですか?

Go言語で分散トランザクション処理を実装するにはどうすればよいですか?

PHPz
PHPzオリジナル
2023-06-10 18:16:372128ブラウズ

インターネット アプリケーションの規模が継続的に拡大し、垂直サービスが徐々に分割されているため、分散システムの開発はますます重要になっています。生じる問題は、このようなシステムでトランザクションの一貫性をどのように扱うかということです。この記事では、Go 言語によるいくつかの主流の分散トランザクション処理ソリューションとその実装原理を紹介します。

従来の ACID トランザクション

スタンドアロン システムでは、アプリケーションは通常、データの一貫性を確保するために従来の ACID トランザクションを使用します。 ACID は Atomicity、Consistency、Isolation、Durability の略語で、それぞれトランザクションの 4 つの主要な属性を表します。

  • Atomicity (原子性): トランザクション内の一連の操作、またはすべてが成功するか、またはすべて失敗した場合、中間状態はありません。
  • 一貫性: トランザクションの実行はデータベース内の整合性制約に違反しません。
  • 分離: 同時に実行される複数のトランザクションは分離され、相互に干渉しません。
  • 耐久性: トランザクションがコミットされると、その結果は永続的になります。

ただし、アプリケーションが分散アプリケーションになると、ネットワーク遅延、信頼性の低いメッセージング、データ分割など、より複雑な管理が必要になります。それでも従来の ACID トランザクションを使用すると、複雑さとオーバーヘッドが増加します。が発生し、パフォーマンスのボトルネックが生じ、システムのスケーラビリティが制限されます。したがって、分散システムには、分散環境でトランザクションの一貫性を管理できる新しいソリューションが必要です。

CAP 理論

分散システムでは、CAP 理論は 3 つの重要な要素の競合を説明するために使用されます。

  • 分散における一貫性 この環境では、すべてのノードが同じ見解です。
  • 可用性 (可用性): アプリケーションは、リクエストに応答するときに適切な精度を制限します。
  • パーティション耐性: マシン間でネットワークのパーティションが発生しても、システムは動作を継続できます。

CAP 理論では、どのような分散システムでも、これらの要素のうち最大 2 つを同時に満たすことができると考えられています。つまり、分散システムで一貫性と可用性を実現したい場合は、ネットワーク分断の発生を許容する必要があります。一貫性とパーティション耐性を実現したい場合、この場合は可用性を放棄する必要があります。

BASE トランザクション

ACID とは異なり、分散システムは通常、トランザクションの一貫性を処理するために BASE スタイルのトランザクションを使用します。 BASE は、Basicly Available、Soft state、最終的に整合性の略語です。

  • 基本的に可用性: システムの可用性を確保するように努めます。システムに障害が発生しても、システム全体の可用性には影響しません。
  • ソフト状態: システムは一定期間、状態データの一貫性を失わせますが、状態データがリアルタイムで一貫していることは保証されません。最終的に整合性: システムは最終的に整合性のある状態に達します。

BASE トランザクションは強整合性を保証しませんが、結果整合性を通じてトランザクションの整合性を実現します。 BASE トランザクションは、制約を満たす必要があるアプリケーションには適していませんが、大規模なアプリケーション、データ ウェアハウス、および大量のデータを処理する必要があるその他のプロジェクトには適しています。

分散トランザクション実装スキーム

Go には、現在 3 つの主流の分散トランザクション実装スキームがあります:

  1. 2 フェーズ コミット プロトコル プロトコル)

2 フェーズ コミット プロトコルは、分散トランザクションの管理に使用される同期プロトコルです。複数のノード間で実行される分散トランザクションの原子性、一貫性、分離性が保証されます。このうち、コーディネーターはグローバルコミットプロトコルの管理を担当し、各ノードはコミット/ロールバックプロトコルの実行を担当します。

2 フェーズ コミット プロトコルには、2 つのフェーズがあります:

1. 準備フェーズ: コーディネーターは、参加しているすべてのノードに、トランザクションをコミットする準備ができているかどうかを尋ねます。すべてのノードの準備ができたら、送信フェーズに入ります。それ以外の場合、トランザクションはロールバックされます。

2. コミットフェーズ: すべての参加ノードは、コーディネーターに「送信」または「ロールバック」命令を発行します。すべてのノードが正常に送信されると、分散トランザクションは完了します。少なくとも 1 つのノードがコミットに失敗した場合、トランザクションはロールバックされます。

ただし、2 フェーズ コミット プロトコルには、準備フェーズでスタックする問題 (いわゆる 2 フェーズ ブロッキング問題) があり、このとき、一部のノードがサブミットしているのに、他のノードがサブミットされてしまう可能性があります。準備段階の後に行き詰まった。その結果、一部のノードがロールバック命令を取得できない可能性があり、データの不整合が発生します。したがって、2 フェーズ コミット プロトコルは、完全な分散トランザクション処理ソリューションではありません。

2. 3 フェーズ コミット プロトコル

3 フェーズ コミット プロトコルは 2 フェーズ コミット プロトコルを最適化したもので、2 フェーズ ブロッキングの問題の発生を減らすことを目的としています。 2 フェーズ コミット プロトコルの準備フェーズを 2 つのサブフェーズに分割します:

1. 質問フェーズ: コーディネーターは、参加ノードにトランザクションをコミットする準備ができているかどうかを尋ねます。

2. 準備フェーズ: 参加ノードは、トランザクションをコミットする準備ができているかどうかを確認します。

名前が示すように、3 フェーズ提出プロトコルには 3 つの段階が含まれます。

  1. CanCommit フェーズ: コーディネーターは、参加している各ノードに、トランザクションをコミットする準備ができているかどうかを尋ねます。
  2. プレコミットフェーズ: すべてのノードの準備ができたら、プレコミットフェーズに入ります。それ以外の場合、コーディネーターはロールバック メッセージを送信します。
  3. DoCommit フェーズ: 各参加ノードは、プリコミットおよびコミット プロセス中にエラーが発生しないと確信している場合、コミット メッセージを送信します。参加しているノードのいずれかがコミット前またはコミット プロセス中にエラーに遭遇した場合、ロールバック メッセージが送信されます。

3 フェーズ コミット プロトコルの利点は、2 フェーズ コミット プロトコルと比較して、2 フェーズ ブロックの可能性が減り、障害 (フェイルオーバーなど) に迅速に対応できることです。ただし、ネットワーク分割に対応できない可能性があるという問題がまだあります。

3.SAGAパターン(Sagaパターン)

SAGAパターンは、トランザクションを相互に依存する一連のステップに分割し、各ステップをアトムに変換することで、以下のことを実現するように動作するロングトランザクション実装スキームです。目標:

  • トランザクションの範囲を可能な限り縮小します。
  • すべてのステップで一貫性を強制する必要はありません。
  • すべてのステップではなく、部分的にロールバックできます。

SAGA モードは複数のステージで構成されており、各ステージはトランザクション操作の一部を実行します。これらの操作は、冪等性の保証が得られる操作であればどれでも実行できます (つまり、操作自体は、時間を気にすることなく繰り返し実行できます)結果への影響)。ステージが失敗した場合、SAGA モードは実行状況に応じてステージを前後にロールバックし、最終的にはすべてのステージの操作が正しく実行されたか、ロールバックできない状態に達します。

SAGA モードを通じて、少なくとも部分的なロールバックをサポートするという犠牲を払って、各ビジネス モジュールの独立した開発、展開、拡張を実現できます。SAGA モードは最終結果を保証するため、ロールバックを行う必要はありません。すべてのステップが厳密に一貫していることを確認するため、複雑な非同期/同期分散環境で機能することが可能になります。

概要

Go 言語には、分散プロトコル、ロング トランザクション スキーム、Saga など、分散トランザクション処理を処理する複数の方法があります。各ソリューションには独自の長所と短所があり、適切なシナリオに最適に適用されます。実際のアプリケーションでは、分散トランザクション管理をより適切に実現するために、特定の状況に基づいて選択を行う必要があります。

以上がGo言語で分散トランザクション処理を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。