Chord: Scable P2P Lookup Service Paper Review
Chord: A Scalable Peer-to-peer Lookup Service for Internet Applications
Buzzwords
- P2P, DHT
- Consistent Hashing
- Finger Table
- Automatically Load Balance
- Stabilization
Summary
The paper introduces the lookup service in the P2P applications named
Chord
. The Chord
introduces the consistent hashing algorithm for
each node only needs to remember O(log N) other nodes and resolves all
lookup via O(log N) messages. What\’s more, it can also maintain the
information as nodes join and leave the system in no more than n
O(log^2^ N) messages even concurrently.
The Chord
assigns each node and key with an m-bit identifier using
SHA-1 and each key are assigned to nodes when successor(key) = node in
clockwise. In order to lookup the key, we should forward and find the
key to known information. The paper uses the finger table
which keeps
successor of nodes exponentially further away. The pseudocode is shown
below. In the above algorithm, every forward take almost half way of the
target, just like binary search in terms of consistency hashing.
// The pseudocode to find the successor node of an identifier . Remote procedure calls and variable lookups are precede-d by the remote node.
// ask node n to find id's successor
n.find_predecessor(id):
n' = find_predecessor(id)
return n'.successor
// ask node n to find id's predecessor
n.find_predecessor(id):
n' = n
while (id ∉ (n', n'.successor):
n' = n'.closest_preceding_finger(id)
return n'
// return closest_preceding_finger(id)
n.closest_preceding_finer(id):
for i = m downto 1
if (finger[i].node ∈ (n, id)):
return finger[i].node
return n
When a new node joins the system. Instead of finding all fingers\’
successor using the find_successor
shown above, we can do a little
optimization just like pseudocode shown below, which is O(log^2^ N)
according to the paper. (If two fingers\’ interval contains no nodes,
the two fingers\’ node is the same.)
// node n joins the network
// n' is an arbitrary node already in the network
n.join(n'):
if (n'):
init_finger_table(n')
update_others()
// move keys in (predecessor, n] from successor
else: // n is only node in the network
for i = 1 to m:
finger[i].node = n
predecessor = n
// initialize finger table of local node
// n' is an arbitrary node already in the network
n.init_finger_table(n'):
finger[1].node = n'.find_successor(finger[1].start)
predecessor = successor.predecessor
successor.predecessor = n
for i = 1 to m - 1:
if (finger[i+1].start ∈ [n, finger[i].node)):
finger[i+1].node = finger[i].node
else:
finger[i+1].node n'.find_sucessor(finger[i+1].start)
// update all nodes whose finger
// tables should refer to n
n.update_others():
for i = 1 to m:
// find last node p whse i^th finger might be n
p = find_predecessor(n - 2^(i-1))
p.update finger_table(n, i)
// if s is i^th finger of n, update n's finger table with s
n.update_finger_table(s, i):
if (s ∈ [n, finger[i].node)):
finger[i].node = s
p = predecessor
p.update_finger_table(s, i);
In terms of concurrent joins, the paper introduces a new algorithm to
replace the above one, which is called Stabilization
. The algorithm is
just periodically asking its successor who its predecessor is, and If
that node is closer to you, switch to that one. And after some time, all
nodes will be correct according to the paper. Moreover, the nodes should
periodically refresh its finger tables for correctness. The pseudocode
is shown below.
n.join(n'):
predecessor = nil
successor = n'.find_successor(n)
// periodically verify n's immediate successor,
// and tell the successor about n
n.stabilize():
x = successor.predecessor
if (x ∈ (n, successor)):
successor = x
successor.notify(n)
// n' thinks it might be our predecessor
n.notify(n'):
if (predecessor is nil or n' ∈ (predecessor, n)):
predecessor = n'
// periodically refresh finger table entries
n.fix_fingers():
i = random index > 1 into finger[]
finger[i].node = find_successor(finger[i].start)
Finally, nodes failure needs to be solved. As we all know, dealing with unreachable nodes during routing is important in reality. The paper uses successor-list, so lookup first finds live successor >= key, or forward to successor < key if possible. The paper says it can be routed successfully with high probability.
Above all, although the Chord
guarantees weak consistency and alive
data, it keeps less information needed to be kept, fewer messages needed
to be sent and eventually consistency guarantees. The distributed hash
table exposes a powerful design in P2P systems.
Strength of the paper
The paper introduces the P2P system with distributed hashing table. It is nice for load balance problem with less information stored.
The paper uses
finger table
to store the minimal necessary information to lookup instead of storing all information to perform a binary search style lookup.
Weakness of the paper
- No introduction to security problem such as malicious nodes which may be common in the P2P system.
Suggestion to the paper
- We can make use of geographic information to decided the closest available nodes.