パクシやいかだの代わりにCRDTのようなものを使用するのはいつ良い考えですか?
CRDTとPaxosには異なる目標があり、異なるシナリオで使用されます。それらには、プログラマーが並行性/レプリケーションに対処するのに役立つという共通点があります。 CRDTは、同時更新が発生すると想定するデータ型です。 Paxosは、それらに全順序を適用することによって、それらが実行しないことを強制するプロトコルです。これをより詳細に見てみましょう。
2つの異なる場所で複製される複製セットがあるとしましょう。
Paxosを使用すると、セットへの書き込みがすべてのレプリカによって同じ順序で実行されることが保証されます。より一般的には、セットの状態がどのように変化するかについてすべてのレプリカが同意することを保証します。
たとえば、user1がreplica1でupdate1を実行し、同時にuser2がupdate2を実行し、replica2でelement2を追加する場合、Paxosはレプリカにそれらの更新の特定の順序に同意させるか、場合によっては1つを選択することに同意します。使用方法と達成したい内容に応じて、2つの更新のうち2つ目を破棄します。たとえば、Paxosの結果がupdate1がupdate2の前に来る場合、すべてのレプリカはその順序でセットを更新します。結果として、これらの更新と同時にセットを読み取るユーザーは、どこ(どのレプリカ)を読み取るかに関係なく、セットの次の状態のみを監視できます(最初にセットが空であると想定)。
{} (空集合)
{element1}
{element1、element2}
さらに、これらの状態はこの順序でのみ表示されます。つまり、セットの状態が{element1、element2}(すべてのレプリカで)になると、それ以降の読み取りでは{}または{element1}は返されません。
良い面:このセットは、複製されないセットと同等であるため、簡単に推論できます。
マイナス面:使用不可:レプリカが相互に通信できない場合(ネットワークパーティション)、合意がないため、セットを更新できません。低パフォーマンス、高遅延:契約では、クライアントに応答する前にレプリカを同期する必要があります。これにより、レプリカ間のレイテンシーに比例したレイテンシーが発生します。
CRDTの保証は弱くなります。 CRDTセットは、シーケンシャルなシングルコピーセットと同等ではありません。レプリカの更新方法について合意または全順序がないことを前提としています。
CRDTは、セットの両方のレプリカが(表示される順序に関係なく)同じ更新を確認した場合、同じ状態を示すことを保証します。レプリカは収束します。
2人のユーザーが同時に更新を実行する例では、セットの操作を順序付けるためにPaxosを実行しないシステム(これは、たとえば、最終的または因果的な一貫性の下で発生します)は、replica2がelement2を追加している間に、replica1がelement1を追加できるようにします。
したがって、replica1の状態は次のようになります。{element1}
そしてreplica2の状態は次のようになります:{element2}
この時点で、レプリカは分岐します。後で、レプリカが同期すると、更新が交換され、最終的に次の状態が表示されます。
replica1の状態は次のようになります:{element1、element2}
replica2の状態は次のようになります:{element2、element1}
この時点で、レプリカは収束しています。
これらの更新と同時にセットを読み取るユーザーは、読み取る場所(レプリカ)に応じて、セットの次の状態を確認できます(最初にセットが空であると想定)。
{} (空集合)
{element1}(replica1から読み取った場合)
{element2}(replica2から読み取った場合)
{element1、element2}
{element2、element1}
マイナス面:このセットは、シーケンシャルセットでは発生しなかった状態を示しているため、推論するのが困難です。この例では、セットへの2つの同時追加の場合のみを観察しました。これは簡単です。同時追加と削除はより複雑ですさまざまな問題を持つ多くのデータ型があります。
良い面:高可用性:レプリカが相互に通信できない場合(ネットワークパーティション)、セットを更新できます。レプリカは、接続し直すと同期されます。高性能、低遅延:レプリカは、クライアントに応答した後、すぐにクライアントに応答し、バックグラウンドで同期します。
CRDTTreedocの例には欠陥があります。 2つのシステムが同じキーで同時に挿入する場合、各ノードには明確化が必要です。
これが発生すると、システムが別の同一のキーを挿入する必要があるが、曖昧さ回避の順序を制御する必要があるため、システムが同一のキーを持ち、曖昧さ回避が異なるエントリの間に挿入することはできなくなります。明確化は密ではないため、これが常に可能であるとは限りません。曖昧さ回避がさらに別のツリーである場合、1つの問題を解決しますが、さらに深いところに別の競合解決メカニズムが必要です...など。
この言及されていない問題に加えて、メタデータを整理するために2フェーズコミットを実行する必要があるという事実により、CRDTはまだ進行中の作業であると私は思います。
複数の指標があります。
私の提案は、レプリカが互いに遠くない場合(データセンター内など)はPaxosを使用し、ネットワークのパーティション分割が正常な場合(モバイルが切断されている場合など)はCRDTを使用することです。
@btillyによる応答へのコメント:
このトピックの質問は、一貫性のさまざまなモデル、つまりデザインパターンに関連しています。
CRDTとPaxosは非常に異なるものであり、使用法はアーキテクチャ要件に基づいて決定する必要があります。それを処理する最良の方法は、それらのアルゴリズムが正常に適用されたユースケースを確認することだと思います。
使用パターン:
CRDTは、クライアント(つまり、モバイルデバイス)とサーバー間のデータ同期、リアルタイムの共同編集、dist-db実装での値の同期、および結果整合性が良好なその他すべての場合に使用できます。
PAXOSは主に、システムインフラストラクチャをサポートする独自のシステム(Chubbyなど)で使用されるか、BigTable、Datastore、Spinnaker、Spannerなどの分散データベースシステムで同期を実装するために使用されます。
RAFTは、ETCD、領事などのOSSインフラストラクチャプロジェクトでより人気があります...
(CockroachDBとTiDBが何に基づいているか覚えていない)
BFTもありますが、あまり使用されていません。
p.s. PAXOS!= ZooKeeper。 ZooKeeperは、ZABと呼ばれる別のアルゴリズムを使用し、複製された状態マシンではありませんが、単一のライターとリラックスした読み取りモデルを備えた複製されたスナップショットマシンです。 GoogleのChubbyはPaxosに基づいていますが、独自仕様です。
p.s.s. PAXOSがここ数年どのように進化しているかは興味深いです。過去20年間で、エッジケース、クォーラムサイズ、およびクラスターの再構成のさまざまな最適化を処理する多くのバリアントが発明されました。