Kademlia
概要
Kademlia は二分木構造に基づくシンプルで実用的な分散ハッシュテーブル (DHT; distributed hashtable) アルゴリズム。ネットワークの中から目的のノードを効率よく検索することのできる分散オブジェクトロケーション/ルーティング (DOLR; decentralized object location and routing) の一つである。Kademlia は、P2P のような大規模ネットワークにおいて長期間安定して駆動しているノードを優先的にキャッシュするルーティングテーブルの構築アルゴリズムを示している。
Kademlia のアプローチはノード ID のビットの先頭から二分木 (トライ木
) を構築する (接頭辞で区分けする点では Tapestry と似ている)。Kademlia は構造のシンプルさや
P2P ファイル共有では Gnutella, BitTorrent, IPFS で使用されている。またブロックチェーンでの PoC として Ethereum 1 や Storj, Dfinity などのノード検索で検討されている。
Table of Contents
アルゴリズム構造
Kademlia では検索キーに最も近い ID を持つノードをそのキーに対応するノードとしている。"対応" が意味するところはアプリケーションに依存する。例えば KVS であれば key-value の保存と参照の責務を持つノードとなるだろう。Kademlia の論文 [1] では KVS の実装として紹介しているが、キーに対応するノードを特定した後にシステムがどのように動作するかについて設計上の制約はない。
検索キーとノード ID は同じサイズのデータである。[1] ではともに 160-bit の空間としている (この 160-bit は任意長のキーを SHA-1 でハッシュ化することを意図してるだけで、アルゴリズムの設計としてキーのサイズに制限はない)。
Kademlia ネットワークのノードは Fig 1 に示すように各ノード ID の 2 進数表現に基づいて概念上の二分木構造に配置される。
ノード ID に偏りがあるとキーレンジの広いノードに負荷が集中し Kademlia ネットワーク全体の性能が低下する。したがってノード ID も検索キーも一様にランダムに分布するように設計する必要がある。
ルーティングテーブル
Kademlia の各ノードはそれぞれ独自のルーティングテーブルを持っている。ルーティングテーブルは二分木の根から自身のノード ID までを結ぶ経路 (Fig 2 の青いライン) から分岐した部分木に含まれるノードを最大
00111 のルーティングテーブルの例。00111 を結ぶ経路から分岐した先に存在する最大 最上位の部分木は二分木を 2 分割した空間のうち自身のノードが含まれていない方である。二層目の部分技はさらに 2 分割したうちの自身のノードが含まれていない方である。
Kademlia ネットワーク開始時の最初のノードはすべての名前空間を範囲とする一つの
- 含まれている場合、ノード B をバケットの末尾に移動する。
- 含まれていない場合、バケットのノード数が:
-
個より少なければ単純にその末尾にノード B を追加する。 -
個の場合、その -バケットの範囲に自身のノード ID が: - 含まれる場合、
-バケットを二分割し、すでに存在する 個のノードをそれぞれの -バケットへ分配する。その後にノード B に対応する方の -バケットにノード B の追加を再帰的に試行する。 - 含まれない場合、
-バケットのノード交換用キャッシュに保存する。後の動作で応答しないノードが発生したとき、この交換用キャッシュのもっとも最近に追加されたノードと疎通確認を行い、正しい応答があれば応答しなくなったノードと置き換える。
- 含まれる場合、
-
以上の動作で Kademlia のルーティングテーブルはトラフィックによって最新の状態に保たれる構造をしている。一定時間 (論文では 1 時間) ノード検索が行われていない
いっぱいになった
XOR 距離関数
Kademlia は検索キーに最も近い ID を持つノードがそのキーを「担当」する。例えば KVS であれば、key-value ペアはキーとの距離がもっとも近い ID を持つノードに保存される。Kademlia でのノード ID とキーとの距離関数はそれらのビット単位での XOR (排他的論理和) と定義されている。例えばノード 3 (b011) とノード 5 (b101) が存在するとき、それぞれからキー 1 (b001) に対する距離は:
距離関数に XOR を使用する利点はトポロジーの距離の捉え方が単純になることである。ノード ID やキーを点
-
, 例えば -
のとき - すべての
に対して -
、すなはち と の直線距離 よりも - 距離が短くなるような中継点 は存在しない
Chord のようにある範囲での剰余による循環値
一方、XOR 距離関数では 2 つの点
特徴 4 は、
| XOR | 0 (b000) | 1 (b001) | 2 (b010) | 3 (b011) | 4 (b100) | 5 (b101) | 6 (b110) | 7 (b111) |
|---|---|---|---|---|---|---|---|---|
| 0 (b000) | 0 (b000) | 1 (b001) | 2 (b010) | 3 (b011) | 4 (b100) | 5 (b101) | 6 (b110) | 7 (b111) |
| 1 (b001) | 1 (b001) | 0 (b000) | 3 (b011) | 2 (b010) | 5 (b101) | 4 (b100) | 7 (b111) | 6 (b110) |
| 2 (b010) | 2 (b010) | 3 (b011) | 0 (b000) | 1 (b001) | 6 (b110) | 7 (b111) | 4 (b100) | 5 (b101) |
| 3 (b011) | 3 (b011) | 2 (b010) | 1 (b001) | 0 (b000) | 7 (b111) | 6 (b110) | 5 (b101) | 4 (b100) |
| 4 (b100) | 4 (b100) | 5 (b101) | 6 (b110) | 7 (b111) | 0 (b000) | 1 (b001) | 2 (b010) | 3 (b011) |
| 5 (b101) | 5 (b101) | 4 (b100) | 7 (b111) | 6 (b110) | 1 (b001) | 0 (b000) | 3 (b011) | 2 (b010) |
| 6 (b110) | 6 (b110) | 7 (b111) | 4 (b100) | 5 (b101) | 2 (b010) | 3 (b011) | 0 (b000) | 1 (b001) |
| 7 (b111) | 7 (b111) | 6 (b110) | 5 (b101) | 4 (b100) | 3 (b011) | 2 (b010) | 1 (b001) | 0 (b000) |
プロトコル
Kademlia の論文で紹介している RPC は以下の 4 つである。ただし STORE と FIND_VALUE は参照実装的な KVS を実装するための機能であるため、ルーティングとしての機能は PING と FIND_NODE で充足している。
def PING(contact:Contact)def FIND_NODE(key:ID): List[Contact]def STORE(key:ID, value:Array[Byte])def FIND_VALUE(key:ID): Array[Byte]
参考文献
- Maymounkov P., Mazières D. Kademlia: A Peer-to-Peer Information System Based on the XOR Metric (日本語訳). In: Druschel P., Kaashoek F., Rowstron A. (eds) Peer-to-Peer Systems. IPTPS 2002. Lecture Notes in Computer Science, vol 2429. Springer, Berlin, Heidelberg.
- Xing Shi Cai, Luc Devroye. The Analysis of Kademlia for random IDs
- Distributed Hash Tables with Kademlia, Stanford Code the Change Guides


