raft - RaftコンセンサスプロトコルのGolang実装

(Golang implementation of the Raft consensus protocol)

Created at: 2013-11-05 08:41:20
Language: Go
License: MPL-2.0

ラフトCircleCI

raftは、レプリケートされたログを管理するGoライブラリであり、FSMで使用してレプリケートされたステートマシンを管理できます。コンセンサスを提供するためのライブラリです。

このようなライブラリのユースケースは、多くの分散システムの主要コンポーネントである複製された状態マシンなど、広範囲に及びます。これらは、フォールトトレランスも制限された、一貫性のあるパーティショントレラント(CP)システムの構築を可能にします。

建物

ラフトを構築したい場合は、Goバージョン1.16以降がインストールされている必要があります。

次の方法でインストールを確認してください。

go version

ドキュメンテーション

完全なドキュメントについては、関連するGodocを参照してください。

cgoの複雑化を防ぐために、プライマリバックエンドはraft-mdb

MDBStore
と呼ばれる別のリポジトリにあります。これは、およびの推奨される実装です。
LogStore
StableStore

Bboltを使用する純粋なGoバックエンドは、 raft-boltdbと呼ばれることもできます 。

LogStore
ととしても使用できます
StableStore

コミュニティが貢献した例

RaftgRPCの例-gRPCでRaftリポジトリを利用する

タグ付きリリース

2017年9月より、HashiCorpは、メジャーバージョンの更新を明確に示すために、このライブラリのタグの使用を開始します。このライブラリへのアプリケーションの依存関係をベンダー化することをお勧めします。

  • v0.1.0は、メインにあり、APIを壊すことなく維持されている、ライブラリの元の安定バージョンです。これは、バージョン0.7.0より前の領事によって使用されていました。

  • v1.0.0は、library-v2-stage-oneブランチでステージングされた変更を取得します。このバージョンは、UUIDを使用してサーバーIDを管理するため、APIに重大な変更が加えられています。また、Raftプロトコルをバージョン管理し、古いバージョンのライブラリを実行しているRaftサーバーと相互運用する場合は、いくつかの特別な手順が必要です(バージョンの互換性についてはconfig.goの詳細なコメントを参照してください)。Consulをこれらの新しいインターフェイスに移植するために必要なものについては、https://github.com/hashicorp/consul/pull/2222を参照してください。

    このバージョンには、非投票サーバー、トランスポート層での新しいアドレスプロバイダーの抽象化、より復元力のあるスナップショットなど、いくつかの新機能も含まれています。

プロトコル

いかだは「いかだ:理解できるコンセンサスアルゴリズムを求めて」に基づいています

Raftプロトコルの概要を以下に説明しますが、詳細については、 Raftの論文全体 と、それに続くRaftのソースをお読みください。raftプロトコルに関する質問は、 raft-devメーリングリストに送信する必要があります。

プロトコルの説明

いかだノードは常に、フォロワー、候補者、リーダーの3つの状態のいずれかになります。すべてのノードは、最初はフォロワーとして開始されます。この状態では、ノードはリーダーからのログエントリを受け入れて投票することができます。しばらくの間エントリが受信されない場合、ノードは候補状態に自己昇格します。候補状態では、ノードはピアからの投票を要求します。候補者が定足数の票を獲得した場合、その候補者はリーダーに昇進します。リーダーは新しいログエントリを受け入れ、他のすべてのフォロワーに複製する必要があります。さらに、古い読み取りが受け入れられない場合は、すべてのクエリもリーダーで実行する必要があります。

クラスタにリーダーが含まれると、新しいログエントリを受け入れることができます。クライアントは、リーダーに新しいログエントリを追加するように要求できます。これは不透明なバイナリブロブであり、Raftに追加されます。次に、リーダーは永続ストレージにエントリを書き込み、フォロワーのクォーラムに複製しようとします。ログエントリがコミットされたと見なされると、有限状態マシンに適用できます 。有限状態マシンはアプリケーション固有であり、インターフェースを使用して実装されます。

明らかな質問は、複製されたログの無制限の性質に関連しています。Raftは、現在の状態をスナップショットし、ログを圧縮するメカニズムを提供します。FSMの抽象化により、FSMの状態を復元すると、古いログの再生と同じ状態になる必要があります。これにより、Raftはある時点でFSM状態をキャプチャし、その状態に到達するために使用されたすべてのログを削除できます。これはユーザーの介入なしに自動的に実行され、無制限のディスク使用を防ぎ、ログの再生に費やされる時間を最小限に抑えます。

最後に、新しいサーバーが参加しているとき、または既存のサーバーが離れているときに、ピアセットを更新するという問題があります。ノードのクォーラムが使用可能である限り、Raftはピアセットを動的に更新するメカニズムを提供するため、これは問題ではありません。ノードのクォーラムが利用できない場合、これは非常に困難な問題になります。たとえば、ピアがAとBの2つだけであるとします。クォーラムサイズも2です。つまり、両方のノードがログエントリをコミットすることに同意する必要があります。AまたはBのいずれかが失敗した場合、クォーラムに到達することは不可能になります。これは、クラスターがノードを追加または削除したり、追加のログエントリをコミットしたりできないことを意味します。これにより、使用できなくなります。この時点で、AまたはBのいずれかを削除し、残りのノードをブートストラップモードで再起動するには、手動による介入が必要になります。

3ノードのRaftクラスターは1つのノードの障害に耐えることができ、5つのクラスターは2つのノードの障害に耐えることができます。推奨される構成は、3台または5台のいかだサーバーを実行することです。これにより、パフォーマンスを大幅に犠牲にすることなく可用性が最大化されます。

パフォーマンスの面では、ラフトはパクシに匹敵します。安定したリーダーシップを前提として、ログエントリをコミットするには、クラスターの半分への1回のラウンドトリップが必要です。したがって、パフォーマンスはディスクI/Oとネットワーク遅延によって制限されます。