Skip to content

Instantly share code, notes, and snippets.

@t3t5u
Last active February 14, 2016 06:23
Show Gist options
  • Save t3t5u/d8c1b65e7dbd54ae4549 to your computer and use it in GitHub Desktop.
Save t3t5u/d8c1b65e7dbd54ae4549 to your computer and use it in GitHub Desktop.
Plumtree

Push-Lazy-Push Multicast Tree.

高いスケーラビリティ、信頼性 (Reliability) 、回復力 (Resiliency) を達成するため、 流行性のブロードキャスト (Epidemic Broadcast) と、 決定論的なツリーに基づくブロードキャスト (Deterministic Tree-Based Broadcast) を統合する。

純粋な Gossip Protocol と異なり、ブロードキャスト用のツリーを構築するフェーズで、冗長な転送経路が取り除かれるので、重複するメッセージが大量に転送されることはない。

Peer Sampling Service: HyParView

メンバーシップの維持と隣接ノードの情報を取得するためのコンポーネント。

Plumtree Protocol コンポーネントに対して NeighborUp / NeighborDown を通知する。

  • all nodes should have in their partial views, at least, another correct node.
  • all nodes should be in the partial view of, at least, a correct node.
  • the peer sampling service should be able to operate correctly in such large systems (e.g. with more than 10.000 nodes).

Example:

eagerPushPeers

  • ブロードキャスト用のツリー。
  • 受け取ったメッセージを Eager Push Approach で直ぐに転送するのに使う。
  • 最初は Peer Sampling Service コンポーネントから取得 (GetPeers) する。
  • 最初はランダムに選ばれた幾つか (riak_core の場合は round(math:log(length(Members)) + 1)) のノードを含む。
 3 = round(math:log(10) + 1).
 6 = round(math:log(100) + 1).
 8 = round(math:log(1000) + 1).
10 = round(math:log(10000) + 1).

lazyPushPeers

  • フォールトトレラント用のスパニングツリー。
  • 定期的に Lazy Push Approach でツリーを修復するのに使う。
  • 最初は空。

Plumtree Protocol

Gossip Protocol により、ツリーの構築と修復を実現するためのコンポーネント。

Example:

Tree Construction

eagerPushPeers から lazyPushPeers へ隣接ノードを移動することで、スパニングツリーを構築する。

  • あるメッセージを初めて受け取ったら、それを送信したノードを eagerPushPeers に追加する。
  • 再度、同じメッセージを受け取ったら、それを送信したノードを lazyPushPeers に移動する。
  • ノードを lazyPushPeers に移動したら、そのノードに PRUNE メッセージを送信する。
  • PRUNE メッセージを受信したら、それを送信したノードを lazyPushPeers に移動する。

Example:

%% 隣接ノードのリスト.
Members = [1,
           11, 12,
           111, 112, 121, 122,
           1111, 1112, 1121, 1122, 1211, 1212, 1221, 1222],
%% 各ノードが K (= 4) 個の子ノードを持つ木.
Tree = [{   1, [  11,   12,  111,  112]},
        {  11, [ 121,  122, 1111, 1112]},
        {  12, [1121, 1122, 1211, 1212]},
        { 111, [1221, 1222,    1,   11]},
        { 112, [  12,  111,  112,  121]},
        { 121, [ 122, 1111, 1112, 1121]},
        { 122, [1122, 1211, 1212, 1221]},
        {1111, [1222,    1,   11,   12]},
        {1112, [ 111,  112,  121,  122]},
        {1121, [1111, 1112, 1121, 1122]},
        {1122, [1211, 1212, 1221, 1222]},
        {1211, [   1,   11,   12,  111]},
        {1212, [ 112,  121,  122, 1111]},
        {1221, [1112, 1121, 1122, 1211]},
        {1222, [1212, 1221, 1222,    1]}],
%% 隣接ノードのリストから各ノードが K 個の子ノードを持つ木を構築する.
Tree = riak_core_util:build_tree(round(math:log(length(Members)) + 1), Members, [cycles]).

Tree Repair

lazyPushPeers に追加されたノードと定期的にメッセージを交換することで、ツリーの故障を検知して修復する。

  • ブロードキャストされたメッセージの識別子を、定期的 (riak_core の場合は 1 秒ごと) に IHAVE メッセージで lazyPushPeers に追加されたノードに送信する。
  • IHAVE メッセージを受信したら、一定時間 eagerPushPeers からブロードキャストされたメッセージが転送されて来るのを待つ。
  • 一定時間以内にブロードキャストされたメッセージが転送されて来なければ、IHAVE メッセージを送信して来たノードを eagerPushPeers に移動する。
  • ノードを eagerPushPeers に移動したら、そのノードに GRAFT メッセージを送信する。
  • GRAFT メッセージを受信したら、それを送信したノードを eagerPushPeers に移動する。
  • ノードを eagerPushPeers に移動したら、そのノードにブロードキャストされたメッセージのペイロードを送信する。

重複したメッセージを受信すると PRUNE メッセージによって、冗長な転送経路が取り除かれるので、eagerPushPeers が増え続けることはない。

Example:

その他

Sender-Based Tree (Single Sender)

ノードごとに異なるブロードキャスト用のツリーを使う。

転送のホップ数を最適化できる。

riak_core はこのモード。

Shared Tree (Multiple Senders)

すべてのノードが単一の共有されたブロードキャスト用のツリーを使う。

ホップ数が閾値を超えた eagerPushPeers のノードを lazyPushPeers のノードと入れ替えることで最適化できる。

参考資料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment