レプリカおよび断片

eXtreme Scale を使用すると、メモリー内のデータベースまたは断片を、Java 仮想マシン (JVM) 相互間で複製することができます。断片は、コンテナー上に配置された区画を表します。異なる区画を表す複数の断片が、単一のコンテナー上に存在することができます。各区画にはインスタンスがあり、そのインスタンスは、プライマリー断片と構成可能な複数のレプリカ断片です。 レプリカ断片は、同期または非同期のいずれかです。レプリカ断片のタイプと配置は、eXtreme Scale により、同期断片および非同期断片の最小数と最大数を指定するデプロイメント・ポリシーを使用して決定されます。

断片タイプ

レプリカ生成では、次の 3 つのタイプの断片が使用されます。

  • プライマリー
  • 同期レプリカ
  • 非同期レプリカ

プライマリー断片は、挿入、更新、および除去の各操作をすべて受信します。プライマリー断片は、レプリカの追加と除去を行い、データをレプリカに対して複製し、トランザクションのコミットとロールバックを管理します。

同期レプリカは、プライマリーと同じ状態を保持します。プライマリーがデータを同期レプリカに対して複製する場合、トランザクションは、同期レプリカ上でコミットするまで、コミットされません。

非同期レプリカは、プライマリーと同じ状態である場合も、同じ状態でない場合もあります。プライマリーがデータを非同期レプリカに対して複製する場合、プライマリーは、非同期レプリカがコミットするのを待機しません。

図 1. プライマリー断片とレプリカ断片との間の通信パス
トランザクションはプライマリー断片と通信します。
プライマリー断片は、1 つ以上の Java 仮想マシンにあるレプリカ断片と通信します。

最小同期レプリカ断片数

プライマリーは、データのコミットを準備するときに、トランザクションのコミットを断定した同期レプリカ断片の数を検査します。トランザクションがレプリカに対して通常に処理を行う場合は、コミットを断定します。同期レプリカに何らかの異常がある場合は、コミットしないことを断定します。プライマリーがコミットする前に、コミットを断定している同期レプリカ断片の数が、デプロイメント・ポリシーの minSyncReplica 設定に適合している必要があります。コミットを断定している同期レプリカ断片の数が小さ過ぎる場合、プライマリーはトランザクションをコミットせず、エラーとなります。このアクションにより、正しいデータには、必要な数の同期レプリカが必ず使用可能となります。エラーを検出した同期レプリカは、再登録して、その状態を修正します。再登録 について詳しくは、レプリカ断片のリカバリーを参照してください。

コミットを断定した同期レプリカの数が少な過ぎる場合、プライマリーは、ReplicationVotedToRollbackTransactionException エラーをスローします。

レプリカ生成およびローダー

通常、プライマリー断片は、変更を、ローダーを介して同期的にデータベースに書き込みます。ローダーとデータベースは、常に同期しています。プライマリーがレプリカ断片にフェイルオーバーする場合、データベースとローダーは同期しない場合があります。例:

  • プライマリーは、トランザクションをレプリカに送信してから、データベースに対してコミットする前に、失敗する場合があります。
  • プライマリーは、データベースに対してコミットしてから、レプリカに送信する前に、失敗する場合があります。

どちらの場合も、レプリカが、1 トランザクションだけデータベースの前に、または 1 トランザクションだけデータベースの後ろに移動します。この状態は許容されません。eXtreme Scale は、ローダー実装に特殊なプロトコルと契約を使用して、2 フェーズ・コミットを使用せずにこの問題を解決します。プロトコルは、次のようになります。

プライマリー・サイド

  • トランザクションを、前のトランザクション結果と一緒に送信します。
  • データベースに書き込み、トランザクションのコミットを試行します。
  • データベースがコミットする場合、eXtreme Scale 上でコミットします。データベースがコミットしない場合には、トランザクションをロールバックします。
  • 結果を記録します。

レプリカ・サイド

  • トランザクションを受信し、それをバッファーに入れます。
  • すべての結果について、トランザクションと一緒に送信し、バッファーに入れられたすべてのトランザクションをコミットし、ロールバックされたすべてのトランザクションを廃棄します。

フェイルオーバーする場合のレプリカ・サイド

  • バッファーに入れられたすべてのトランザクションについて、トランザクションをローダーに提供し、ローダーはトランザクションのコミットを試行します。
  • 各トランザクションがべき等になるようにローダーを作成する必要があります。
  • トランザクションが既にデータベース内にある場合は、ローダーはいかなる操作も行いません。
  • トランザクションがデータベース内にない場合には、ローダーはトランザクションを適用します。
  • トランザクションがすべて処理されてから、新しいプライマリーが要求のサービス提供を開始できます。

このプロトコルにより、データベースは、確実に新規プライマリー状態と同じレベルとなります。