1. 序章

このチュートリアルでは、トランザクションの概念を理解します。

トランザクションの種類と、それらが提供するさまざまな保証について説明します。 また、異種環境で分散トランザクションを処理するためのさまざまなプロトコルとアルゴリズムについても説明します。

2. トランザクションとは何ですか?

プログラミングでは、トランザクションを単一のアクションとして実行する必要のある関連アクションのグループと呼びます。 言い換えると、トランザクションは論理的な作業単位であり、その効果はトランザクション全体の外部に表示されるか、まったく表示されません。 アプリケーションのデータ整合性を確保するためにこれが必要です。

これをよりよく理解するために例を見てみましょう。 イベントベースのアーキテクチャの一般的な要件は、ローカルデータベースを更新し、他のサービスで使用するイベントを生成することです。

ここでは、これら2つの操作を同時に実行するか、まったく実行しないようにします。 これらの操作を単一のトランザクションにラップすることで、これを実現できます。

通常、データベースやメッセージブローカーなどのこれらのコンポーネントは、トランザクションに参加するリソースと呼ばれます。

3. トランザクションの簡単な履歴

私たちは主に、トランザクションの概念をリレーショナルデータベースに関連付けます。 したがって、トランザクションの履歴と進化は、リレーショナルデータベースの履歴と進化にも密接に関連しています。

データのリレーショナルモデルの導入は主にEdgarFによるものです。 1970年にこの主題に関する独創的な論文を発表したコッド。

3.1. 以前のトランザクションモデル

リレーショナルデータベースの使いやすさと柔軟性により、それらは当たり前になりました。 これにより、大規模なマルチユーザーで同時にアクセス可能なシステムの複雑さがもたらされました。 すぐに、一貫性の強制が必要であることがわかりました。

これにより、ACIDプロパティが生まれました。 ACIDプロパティに準拠するトランザクションは、アトミックでシリアル化可能であることが保証されています。 トランザクション処理システムは、ACIDプロパティを保証する責任があります。 これは、実行時間が短く、同時ユーザーが少なく、単一のデータベースシステムを備えたフラットトランザクションで非常にうまく機能しました。

しかしすぐに、需要が急増し始めると、複雑さも増し始めました。 アプリケーションは長寿命で複雑なトランザクションを必要とし始めました。 その結果、サブトランザクションやトランザクショングループなどの複雑なトランザクションモデルが作成されました。

これにより、特に長期にわたるトランザクションの場合に、障害シナリオをより正確に制御できます。

3.2. 高度なトランザクションモデル

トランザクションの進化の次の段階は、分散およびネストされたトランザクションのサポートによってもたらされました。 アプリケーションはより複雑になり、多くの場合複数のデータベースシステムへのトランザクションアクセスが必要になりました。 分散トランザクションはボトムアップアプローチを採用し、ネストされたトランザクションはトップダウンアプローチを採用して複雑なトランザクションをサブトランザクションに分解します。

分散トランザクションは、複数のリソースに対してグローバルな整合性制約を提供しました。 これらのリソースもすぐに異質になり始めました。 これにより、X / Open DTP(分散トランザクション処理)モデルが誕生しました。

トランザクションのその他の重要な進化には、連鎖トランザクションとsagasが含まれていました。 ネストされたトランザクションは連合データベースシステムではうまく機能しましたが、それでも長期的なトランザクションには適していませんでした。 連鎖トランザクションは、そのようなトランザクションを小さな連続して実行されるサブトランザクションに分解するというアイデアを提示しました。

Sagasは連鎖トランザクションの概念に基づいており、すでに完了したサブトランザクションをロールバックするための補償メカニズムを提案しました。 佐賀モデルは、それが提案するリラックスした一貫性のために重要なトランザクションモデルです。 これは、マイクロサービスアーキテクチャで開発された現在のアプリケーションに多くの関連性を見出しています。

ここに示されている用語と概念の多くについては、チュートリアルの後半で詳しく説明します。

4. ローカル対。 分散トランザクション

トランザクションの一部である操作はすべて、単一の参加リソースで実行することも、複数の参加リソースにまたがって実行することもできます。 したがって、トランザクションはローカルまたは分散にすることができます。

ローカルトランザクションでは、操作は同じリソースで実行されます。 分散トランザクションでは、操作は複数のリソースに分散されます

これまでのところ、トランザクションに参加しているリソースの場所については話していません。 トランザクションには、データベース、メッセージキュー、Webサービスなどの複数の独立したリソースが含まれる場合があります。 これらのリソースは、同じ仮想マシン、同じ物理マシン内の異なる仮想マシン、またはまったく異なる物理マシンで実行できます。

参加リソースの数と場所は、特定の保証付きのトランザクションを実装する上で重要な側面です。これについては、次のセクションで詳しく説明します。

5. トランザクション保証

データの処理にトランザクションを使用する基本的な理由の1つは、データの整合性を確保することです。 データの整合性は、すべてのトランザクションが提供することになっている一連の保証によって明確に定義されています。

さらに、分散データシステムは、データパーティショニングからのより良いレバレッジを支持して、これらの保証の一部を失うことを余儀なくされる可能性のある新しい課題を提示します。 このセクションでは、これらの概念について説明します。

5.1. ACIDプロパティ

トランザクションは、頭字語ACIDで有名な一連の保証と関連付けられることがよくあります。 このコンセプトは、元々はジム・グレイによって提案され、後にアンドレアス・ロイターとテオ・ハーダーによって拡張されました。 ACIDは、Atomicity、Consistency、Isolation、およびDurabilityの略です。

  • Atomicity :Atomicityは、トランザクションの一部としてデータに加えるすべての変更を保証し、それらを単一のエンティティおよび操作として行います。 これは事実上、すべての変更を実行するか、まったく変更しないことを意味します。
  • 一貫性:一貫性により、トランザクションの開始時と終了時に一貫性のある状態を維持しながら、すべてのデータ変更を確実に実行できます。 データの一貫した状態は、データに対して定義するすべての制約に準拠する必要があります。
  • 分離:分離により、トランザクションの中間状態を他のトランザクションから見えないようにすることができます。 これにより、同時に実行されるトランザクションにシリアル化の効果が与えられます。 トランザクションを他のトランザクションから分離する必要がある度合いは、分離レベルによって定義されます。
  • Durability :Durabilityは、トランザクションが完了したときにデータへの変更を永続化し、他のトランザクションがそれらの変更を元に戻さないことを保証します。 必須ではありませんが、データの変更をディスクに保存する必要がある場合もあります。

これらは、トランザクションから期待すべき保証です。 ただし、トランザクションはそれらすべてを提供する必要はありません。 ACID保証を提供しないトランザクションは、トランザクションではないことを示唆する多くの議論を文献で見つけることができます。

ただし、可用性に重点が置かれている分散システムの採用が増えるにつれ、トランザクションという用語がより自由に使用されることがよくあります。

5.2. CAP定理

分散データシステムは、一般にCAP定理によって提供できるものに制約されます。 Eric Brewerは2000年に元の予想を提供し、SethGilbertとNancyLynchは2002年にこれの正式な証明を提供しました。 CAPは、Consistency、Availability、Partitiontoleranceの略です。

  • 整合性:整合性は、分散データシステムで、すべてのノードが最新の正常に書き込まれた値を返すことを保証します。 事実上、すべてのノードは常にデータの同じビューを持っています。 これをACIDの一貫性と混同しないでください。これらは異なる概念です。
  • 可用性:可用性では、障害が発生していないすべてのノードが、妥当な時間内に読み取りおよび書き込み要求に対してエラー以外の応答を返す必要があります。
  • パーティショントレランス:パーティショントレランスとは、ノード間で任意の数のメッセージがドロップまたは展開された場合でも、データシステムが機能し続けることを指します。

CAP定理は、分散データシステムは、整合性、可用性、およびパーティション許容度の3つすべてを同時に提供することはできないと述べています。 より実用的な意味では、分散データシステムは、可用性または一貫性のいずれかを強力に保証することしかできません。

これは、分散データシステムがデフォルトでパーティションの許容範囲を損なうべきではないためです。

5.3. BASEシステム

CAP定理の制約の下で、多くの分散データシステムは、可用性よりも一貫性を優先することを選択しました。 これにより、頭字語をBASEとする分散システムの新しい保証セットが生まれます。 BASEは、基本的に利用可能、ソフト状態、および結果整合性の略です。

  • 基本的に利用可能:この保証は、CAP定理に従って一貫性よりも可用性を優先します。 応答が古くなっている場合でも、データシステムは要求に対する応答を生成します。
  • Soft-state :これは、入力が受信されなくても、システムの状態が時間の経過とともに変化する可能性があるという事実を指します。 したがって、システムは常に結果整合性に向かって移動するソフト状態のままになります。
  • 結果整合性:これは、入力の受信を停止すると、システムが結果整合性になることを保証します。 データの変更は最終的にすべてのノードに伝播し、すべてのノードが同じデータビューを持つようになります。

BASEは、提案する整合性モデルの点でACIDとは正反対です。 ACIDはすべてのトランザクションの終了時に整合性を強制しますが、BASEは、トランザクションの終了時に整合性が流動的な状態にある可能性があることを受け入れます。

強一貫性要件のこの緩和により、分散データシステムで高可用性を実現できます。

6. 分散コミットプロトコル

ほとんどすべての一般的なリレーショナルデータベースは、デフォルトでトランザクションのサポートを提供します。 ローカルトランザクションには1つのデータベースしか含まれないため、データベースはそのようなトランザクションを直接管理できます。 さらに、アプリケーションは、関連するAPIを介してトランザクション境界を制御できます。

ただし、分散トランザクションについて話すと、複雑になり始めます。 ここには複数のデータベースまたはリソースが関係しているため、データベースでそのようなトランザクションを排他的に管理することはできません。 ここで必要なのは、トランザクションコーディネーターと、トランザクションに協力するためのデータベースなどの個々のリソースです。

6.1. 2フェーズコミット

ACIDプロパティを保証する分散トランザクションの場合、必要なのは調整プロトコルです。 2フェーズコミットは、分散トランザクションのコミットまたはロールバックの決定を容易にするために広く使用されている分散アルゴリズムです。

プロトコルは2つのフェーズで構成されています。

  • 準備フェーズ:このフェーズは、トランザクションコーディネーターがすべての参加者にコミットの準備を依頼することで構成され、個々のリソースマネージャーは肯定的または否定的に応答できます。
  • コミットフェーズ:このフェーズでは、トランザクションコーディネーターが、前のフェーズの個々の応答に基づいて、すべての参加者にコミットまたはロールバックのいずれかを要求します。

トランザクションコーディネーターは、すべての参加者との2フェーズコミットを容易にします。 参加者が2フェーズコミットに参加するには、プロトコルを理解してサポートする必要があります。

6.2. 3フェーズコミット

2フェーズコミットプロトコルは非常に便利ですが、想像するほど堅牢ではありません。 重要な問題の1つは、コミットフェーズ中にコーディネーターと参加者の1人の両方の障害から確実に回復できないことです。

3フェーズコミットプロトコルは、この問題に対処する2フェーズコミットプロトコルを改良したものです。 コミットフェーズを事前コミットフェーズとコミットフェーズに分割することにより、第3フェーズを紹介します。

ここでの事前コミットフェーズは、参加者が失敗するか、コミットフェーズ中にコーディネーターと参加者の両方が失敗するという失敗シナリオからの回復に役立ちます。 リカバリコーディネータは、コミット前フェーズを使用して、コミットを続行するか中止するかを安全に決定できます。

これらのコミットプロトコルは、分散トランザクションでACIDが保証することを保証しますが、問題の1つのシェアから解放されているわけではありません。 これらのプロトコルの最大の課題は、これらがブロッキングプロトコルであるということです。これは、後で説明するように、常に適切であるとは限りません。

7. 業界仕様

ベンダーは、2フェーズコミットのような分散トランザクションプロトコルを独立して実装できます。 ただし、これにより、特に複数のベンダーと連携する場合、相互運用性が非常に困難になります。 トランザクションにメッセージキューなどの異種リソースを含め始めると、複雑さがさらに増します。

この問題に正確に対処するために、分散トランザクションの標準仕様を定義するためにいくつかの業界のコラボレーションがありました。

7.1. X /OpenDTPモデル

XAは、分散トランザクション処理の仕様である eXtendedArchitectureを指します。 1991年にX/Openコンソーシアムによって最初にリリースされ、後にTheOpenGroupと合併しました。 この仕様の目標は、異種コンポーネントを含むグローバルトランザクションで原子性を提供することです。

XA仕様は、2フェーズコミットプロトコルを使用してデータの整合性を提供し、関連するコンポーネントとインターフェイスを標準化します。

XAは、2フェーズコミットベースの分散トランザクションを容易にするためのいくつかのコンポーネントについて説明しています。

  • アプリケーションプログラム:アプリケーションプログラムは、トランザクションを定義し、トランザクション境界内のリソースにアクセスする役割を果たします。 アプリケーションプログラムは、トランザクションマネージャを使用して、グローバルトランザクションの開始と終了を定義します。
  • トランザクションマネージャー:トランザクションマネージャーは、分散トランザクションの作業単位であるグローバルトランザクションを管理し、それらをコミットするかロールバックするかの決定を調整し、障害回復を調整する責任があります。
  • リソースマネージャー:リソースマネージャーは、データベースなどの共有リソースの特定の部分を管理する責任があります。 リソースマネージャーは、グローバルトランザクションの一部であるトランザクションブランチのトランザクションマネージャーと調整します。

XAは、これらのコンポーネントが相互にどのように機能するかを容易にするための、これらのコンポーネント間のインターフェースについても説明しています。 この説明は、XA仕様の重要な部分について言及したばかりであり、完全な説明ではありません。

7.2. OMGOTSモデル

OTSは、 Object Transaction Service の略で、オブジェクト指向の方法で分散アプリケーションの通信インフラストラクチャを記述します。 これは、Object Management Group(OMG)のObject Management Architecture(OMA)の一部です。

OTSは、いくつかのコンポーネントとそれらのインターワーキングを定義することにより、CORBAアプリケーションで分散2フェーズコミットトランザクションを使用できるようにします。

これらのコンポーネントをもう少し詳しく理解しましょう。

  • Transactional Server :これはトランザクションに関係する1つ以上のオブジェクトを保持します
  • トランザクションクライアント:これはトランザクションオブジェクトのメソッドを呼び出すプログラムです。
  • 回復可能なサーバー:これは、トランザクションのコミットまたはロールバックの影響を受けるトランザクションオブジェクトである1つ以上の回復可能なオブジェクトを保持します
  • Transactional Object :これはCORBAオブジェクトであり、そのメソッドはトランザクションコンテキストで呼び出すことができます

OTSは、OMAの下でOMGによって提供されるいくつかのオブジェクトサービスの1つです。 OMAアーキテクチャのカーネルは、CORBA仕様で定義されているObject Request Broker(ORB)です。

さらに、OTSモデルはX / Open DTPモデルに基づいており、XAおよびTXインターフェイスをCORBAIDLインターフェイスに置き換えます。 OTSの徹底的な分析は、このチュートリアルの範囲を超えています。

8. 長時間実行されるトランザクション

ほとんどの分散トランザクションプロトコルはACID保証の提供に重点を置いていますが、それらはすべてブロックしているという事実に悩まされています。 実行時間が短いトランザクションには完全に機能しますが、実行時間の長いビジネストランザクションには適していません。

アプリケーションのスケーリングが非常に困難になる可能性があります。 リソースロックを使用する従来の手法は、緩く結合された非同期環境でのビジネストランザクションを必要とする最新のアプリケーションとはあまり一致しません。 たとえば、マイクロサービスアーキテクチャで構築されたアプリケーションでのビジネストランザクション。

長時間実行されるトランザクションに対処するためにパターンと仕様を定義する試みがいくつかありましたが、このセクションではそれらのいくつかについて説明します。

8.1. 佐賀相互作用パターン

sagaインタラクションパターンは、長期にわたるビジネスプロセスを、複数の小規模で関連するビジネスアクションとインタラクションに分割しようとします。 さらに、メッセージとタイムアウトに基づいて管理することにより、プロセス全体を調整します。 これは、1987年に最初に定義されたで、HectorGarcia-MolinaとKennethSalemによって定義されました。

佐賀がビジネスプロセスをどのように分解するかを見てみましょう。

ACIDトランザクションとは異なり、佐賀の場合、障害が発生したときにロールバックすることはできません。  ここでは、代わりに私たちが行うことを反作用、または補償行動と呼びます。 ただし、カウンターアクションは、元のアクションの効果を元に戻すための最善の努力です。 すべてのトランザクションの効果を常に完全に元に戻すことは不可能な場合があります。

さらに、佐賀パターンでは、障害からの回復を成功させるために、個々のアクションとそれに対応する対抗アクションがべき等である必要があります。

8.2. OASIS WS-BA

sagaインタラクションパターンは、SOAPサービスベースのインタラクションを備えたSOAベースのアーキテクチャに最適です。 特定の通信要件に対応するために、SOAP用にいくつかのプロトコル拡張が定義されています。 これらはまとめてWS*に該当し、分散トランザクションをサポートするためのプロトコルが含まれています。

Webサービス–ビジネスアクティビティ(WS-BA)は、佐賀ベースのビジネスプロセスに参加するサービスとコーディネーターの両方の整然としたプロトコルと状態を定義します。 WS-BAは、次の2つのプロトコルを定義しています。

  • コーディネーターの完了とのビジネス契約:これは、コーディネーターが決定し、いつ完了するかを参加者に通知する、より順序付けられたプロトコルです。
  • 参加者の完了とのビジネス契約:これは、参加者がいつ完了する必要があるかを決定する、より緩く結合されたプロトコルです。

さらに、WS-BAは2つの調整タイプを定義します。 1つ目は、すべての参加者がクローズまたは補償する必要があるアトミックアウトカムです。 2つ目は、コーディネーターが各参加者を異なる方法で扱う混合結果です。

8.3. OASIS BTP

ビジネストランザクションプロセス(BTP) は、組織間で保証と保証の制限を伝達するための共通の理解と方法を提供します。 これにより、組織の境界外にビジネスプロセスの一部を配布するための正式なルールが提供されます。

BTPは調整を提供し、ビジネスプロセスの一貫した終了を強制しますが、参加組織からのローカルな補償アクションに依存しています。 BTPは、2つの異なるプロトコルを提供します。

  • BTPアトミックトランザクションアトムとも呼ばれ、密結合システムでのトランザクションに似ています。 ここでは、1つのアトムコーディネーターと0個以上のサブコーディネーターがトランザクションを調整し、それぞれが1人以上の参加者を管理します。 アトムの結果はアトミックです。
  • BTP Cohesive Transactions :アトムとは異なり、 cohesions とも呼ばれ、参加者に異なる終了結果をもたらす可能性があります。 ここでの一貫性は、クライアントとコーディネーターの間の合意と相互作用によって決定されます。

したがって、BTPは、異種環境で動作する分散ビジネスプロセスに報酬ベースのトランザクションセマンティックを提供します。

9. 高度なコンセンサスプロトコル

トランザクションをデータベースにコミットするかどうかの決定は、コンセンサス問題として知られる分散コンピューティングの幅広い問題の一部です。 問題は、ランダムな障害が発生した場合にシステムの信頼性を実現することです。 コンセンサスとは、分散プロセスが何らかの状態または決定について合意するためのプロセスを指します。 他のそのような決定には、リーダーの選出、状態機械複製、およびクロック同期が含まれます。

コンセンサス問題を解決するために必要なのは、コンセンサスプロトコルです。 コンセンサスプロトコルは、最終的な終了、データの整合性、および分散プロセスまたはノード間の合意を提供する必要があります。 異なるコンセンサスプロトコルは、ここで異なるレベルの整合性を規定できます。 コンセンサスプロトコルの重要な評価基準には、実行時間とメッセージの複雑さが含まれます。

2フェーズコミットや3フェーズコミットのように、これまで説明してきた分散コミットプロトコルは、すべてコンセンサスプロトコルの一種です。 2フェーズコミットプロトコルは、メッセージの複雑さが低く、全体的な遅延が少ないですが、コーディネーターの障害をブロックします。 3フェーズコミットプロトコルは、全体的なレイテンシが高くなるという犠牲を払って、この問題を改善します。 3フェーズコミットプロトコルでさえ、ネットワークパーティションに直面してバラバラになります。

このセクションで説明するのは、障害シナリオに関連する問題に対処するいくつかの高度なコンセンサスプロトコルです。

9.1. パクソス

Paxosは、1989年にLeslieLamportによって最初に提案されたプロトコルのファミリーです。 これらのプロトコルは、信頼性の低いプロセスの非同期ネットワークのコンセンサス問題を解決します。 Paxosは、ネットワーク内の限られた数のレプリカに障害が発生した場合でも耐久性を提供します。 Paxosは、厳密に正しいことが証明された最初のコンセンサスプロトコルと広く見なされています。

その提案以来、提案されたPaxosプロトコルのいくつかのバージョンがありました。 ここでは、最も基本的なPaxosプロトコルについて説明します。 基本的なPaxosプロトコルは、それぞれが2つのフェーズを持ち、両方ともさらに2つのサブフェーズに分割された複数のラウンドを提案します。

  • 準備(フェーズ1A):提案者は、これまでで最も多く使用されているはずの一意の番号(n)で識別されるメッセージを作成します
  • Promise (フェーズ1B):アクセプターはプロポーザーからメッセージを受信し、その番号(n)を確認しました。番号がこれまでに受信された最大数である場合、アクセプターはプロポーザーにプロミスを返します。
  • Accept (フェーズ2A):提案者は、AcceptorのクォーラムからPromiseの過半数を受け取る可能性があり、選択した値のAcceptメッセージをAcceptorsのクォーラムに送信する必要があります。
  • 承認済み(フェーズ2B):承認者は提案者から承認メッセージを受信し、より高い識別子を持つ提案をまだ約束していない場合は承認する必要があります

Paxosでは、複数の提案者が競合するメッセージを送信し、承認者が複数の提案を受け入れることができることに注意してください。 その過程で、ラウンドは失敗する可能性がありますが、Paxosは、アクセプターが最終的に単一の値に同意することを保証します。

9.2. ラフト

Raftは、DiegoOngaroとJohnOusterhoutが独創的な論文で開発し、後に博士論文で拡張したコンセンサスアルゴリズムです。 これは、信頼性、複製、冗長性、およびフォールトトレラントの略です。

Raft は、コンピューティングノードのクラスター全体にステートマシンを分散する一般的な方法を提供します。 さらに、クラスター内の各ノードが同じ一連の状態遷移に同意することを保証します。 Raftは、複製されたログと単一のノードのみを保持することで機能し、リーダーはそれを管理できます。

Raftは、コンセンサス問題を3つのサブ問題に分割します。

  • リーダー選出:すべてのノードは、リーダー、候補者、フォロワーの3つの状態のいずれかにとどまることができます。 どの時点でも、リーダーは複数存在できません。 ノードは常にフォロワーとして開始し、リーダーからのハートビートを期待します。 ハートビートを受信しない場合は、候補状態に移行し、リーダー状態に移行するための投票を要求します。
  • ログレプリケーション:リーダーはリクエストを受信すると、最初にそれをログに追加し、次にすべてのフォロワーにリクエストを送信して、同じことを実行できるようにします。 大多数のノードから確認を取得したリーダーは、メッセージをコミットしてからクライアントに応答できます。 フォロワーは、リーダーから次のハートビートを受信するとメッセージをコミットします。
  • 安全性:すべてのログが正しく複製され、コマンドが同じ順序で実行されるようにすることが重要です。 このために、Raftはいくつかの安全メカニズムを使用しています。 これらには、ログマッチングプロパティと選挙制限が含まれます。

Raftは、フォールトトレランスとパフォーマンスにおいてPaxosと同等であることに注意してください。 Paxosと同様に、Raftも正式に安全であることが証明されています。 しかし重要なのは、 Raftは、はるかに複雑な前身のPaxosよりも理解と開発が容易なことです。

10. 結論

このチュートリアルでは、トランザクションの意味と、ローカルトランザクションと分散トランザクションの違いについて説明しました。

また、分散トランザクションを処理するための一般的なプロトコルのいくつかを確認しました。 さらに、利用可能な業界仕様とJavaでのサポートについても触れました。

また、長時間実行されるトランザクションについても説明し、最後にいくつかの複雑なコンセンサスアルゴリズムについても説明しました。