Kronos:分散システムでも時間旅行はありません

分散システムでは、いくつかの基本的な問題があります。効率的な分散トランザクション、1回だけのデータ処理、物理クロックの正確な同期です。 後者の問題を解決するために異なるタイプの論理クロック が発明されました


それにもかかわらず、 ベクトルクロックには不快な特性があります。つまり、存在しないイベントと、実際に存在するイベントとの間に条件付きの関係が生じます。


ただし、より信頼性の高いもの-Kronosを考え出すことができます。 この記事では、因果関係アカウンティングアルゴリズムと、分散トランザクションでKey-Valueストレージを構築するためのそのアプリケーションについて説明します。


画像


問題


すでに述べたように、論理クロックには多くの問題があります。



解決策


Kronosによる2014年の記事:イベントオーダーサービスの設計と実装では 、ソリューションが提案されています。これは、イベントの因果関係を処理するスタンドアロンサービスです。


Kronos内の主な抽象化は、部分的な順序付けが導入されるイベントです。 原因と結果の関係は推移的です。つまり、たとえば、ファイルの作成がその変更に先行し、変更が削除に先行することがわかっている場合、作成は削除の前に発生したという論理的な結論を出すことができます。


最小限のAPIは、次の一連のメソッドで定義できます。


方法結果解説
create_event()eKronosで新しいイベントを作成します
query_order([(e_1, e_2), ...])[<-, concurrent, ->, ...]クエリの各ペアに対して、因果関係の方向、またはイベントの同時性を返します
assign_order([(e_1, e_2, must), (e_3, e_4, prefer), ...])OK/FAIL要求のペアごとに、因果関係の方向を設定します
acquire_ref(e)OKこのイベントの参照カウンターを増やします。
release_ref(e)OKこのイベントの参照カウントを減らします。

実装


システムは、イベントの関係をチェックする効果的な幅優先探索、障害発生時の安定性メカニズム、およびガベージコレクションを備えた、イベントの指向グラフに基づいていることは論理的です。


APIからわかるように、 assign_orderリクエストは、因果関係タイプ( mustまたはprefer assign_order受け入れます。 厳密な不変条件に対応しているmust -たとえば、 _->_must関係と競合する場合はpreferが適用されない場合がmustます。 preferを使用する例としては、先に来たリクエストが先にラップされたほうが良いが、これは正確さに影響しない


効果的なBFS


私たちの場合、グラフは大きいかもしれませんが、検証リクエストが実行されるイベントは通常近いでしょう。 したがって、このような場合にはBFSをより速く実行する必要があります。


標準実装では、最長の場所は訪問した頂点の配列の初期化であり、これは常にグラフ内の頂点の数に等しい時間がかかります。 代わりに、ハッシュテーブルを使用するか、他のトリックを適用できます。


ガベージコレクション


表からわかるように、 acquire_refrelease_ref 2つのメソッドがあります。


Kronos内では、イベントごとに参照カウンターが保存されます。 一部のサービスはイベントを処理するか、現在のイベントの後に発生する新しいイベントを追加する機能を予約している間、リンクを保存します。 この必要性がなくなると、サービスはrelease_ref呼び出します。


Kronosは、すべての条件が満たされるとイベントを削除します。


  1. リンクの数がゼロに達しました
  2. これに先行するすべてのイベントはすでにグラフから削除されています。

このアプローチは可能なクエリを制限しませんが、Kronos内のメモリを節約します。


用途


分散トランザクションでのキー値ストレージの例として、システムの使用を検討してください。


複数のサーバーがあり、各サーバーが一連のキーを担当しているとします。


各トランザクションは、Kronosのイベントに対応しています。 サーバーは、キーごとに、このキーが参加した最後のトランザクションの番号を保存する必要があります。 クライアントはイベントを作成し、このトランザクションによってキーが影響を受けるすべてのサーバーにその番号を送信します。 サーバーは、現在のトランザクション番号とこのキー用に保存された前のイベントとの間にKronosで依存関係を作成しようとしています。 依存関係を作成できない場合、トランザクションは失敗として認識されます(これまではデータとの対話がまだないことに注意してください)。


すべての依存関係の追加操作が正常に完了した場合-これは、トランザクションが実行され、実行できることを意味します。 サーバーはこれについてクライアントから学習し、トランザクションの一部を実行し始めます。


このようなトランザクションはACIDになることに注意してください。



性能


このようなKVストレージを実装すると、本当に効果的です。 元の記事は、KVストレージの説明された実装がロックに基づくトランザクションより4倍速いというデータを引用しています。


さらに、MongoDBは分散トランザクションを使用しないにもかかわらず、MongoDBと比較して、Kronos上のシステムはわずか6%遅れています。


分析


ただし、クロノスの運用にはいくつかの欠点があります。



それにもかかわらず、記述されたシステムは、イベント間の因果関係の柔軟な制御を可能にし、必要な不変条件への予測可能なコンプライアンスを保証します。


おわりに


これについて、GoTo Schoolでは、分散システムの方向で生徒と生徒を指導しています。


また、 アルゴリズムとアプリケーション 、応用プログラミング、バイオインフォマティクス、 データ分析があります


10月27日〜11月4日に秋の学校 、または1月上旬にウィンタースクールに来てください。


そして、あなたがもはや学生でも生徒でもない場合は、 教え来てください



Source: https://habr.com/ru/post/J426399/


All Articles