As professional tides bring me into P2P once again and I revisit some classics of the P2P literature, it is disconcerting to realize just how poorly did I really understand some of those things in the past. And one of those things is the expected lookup complexity of Chord [1].
From the outset, the problem seems simple enough. We start with a set of nodes O={o1,⋯,on}O={o1,⋯,on} that is arranged in a ring (Fig. 1) and to which Chord assigns, for each node oi∈Ooi∈O, a random non-negative integer id – let’s call it id(oi)id(oi) – such that id(oi)∈[0,2m)id(oi)∈[0,2m) for some natural number mm.
Fig. 1 shows a fake network with m=6m=6 in which all ids are assigned to nodes. This would never happen in practice as the id space is made to be way bigger than the network size, but it illustrates the shape of the network well, and makes it easier to explain how routing – which is the main point here – works.
The Chord protocol guarantees that each node oioi eventually builds a local routing table, named a finger table, which contains up to mm entries such that the kthkth entry in its table points to a node oj∈Ooj∈O that has the closest id to id(oi)+2kid(oi)+2k, where 0≤k≤m0≤k≤m1. Fig. 1 depicts finger tables for nodes with ids 00 and 2020.
Figure 1: A full-network Chord DHT with m = 66
When a node oaoa wishes to find a node obob, then, all it needs to do is to lookup the node in its own routing table that has the id that is closest to id(ob)id(ob). Because of the way fingers are arranged, oaoa is guaranteed to have in its routing table some node ococ such that id(oc)id(oc) is at least within a distance of 2m−12m−1 of id(ob)id(ob).
oaoa can then ask ococ to repeat this process, and return the node odod that it knows to be the closest to obob. Again, because of the way fingers are constructed, we know that odod must have a node in its finger table that has an id within at least 2m−22m−2 of the target. By continuing this process iteratively, it is not difficult to see that, after mm steps, we will necessarily get to obob as we will find a node that is within distance 2m−m=12m−m=1 of it.
And this completes the basic intuition I already had: lookups always take less than O(m)=O(log2m)O(m)=O(log2m) steps. Chord, however, makes a more subtle guarantee: namely that lookups take O(logn)O(logn) with high probability for a network with size n<2mn<2m. And that is the problem we want to get into. Let us put that as a theorem, like the original paper [1] does:
Theorem. With high probability, the number of nodes that must be contacted to resolve a successor query in an nn-node network is O(logn)O(logn).
Proof sketch. Suppose there are two nodes oaoa and obob that are part of a network containing nn nodes, such that oaoa is looking obob up. Following the reasoning we outlined before and assuming wlog that finger tables are complete, Chord guarantees that oaoa should know a node ococ such that (id(ob)−id(oc))mod2m≤2m−1(id(ob)−id(oc))mod2m≤2m−1; i.e. ococ is within distance 2m−12m−1, in id space, of obob. Note that this is irrespective of the number of nodes nn in the network.
As before, this means once again that, after logNlogN forwardings, we are guaranteed to have found a node that is within a distance of:
2m−logn=2m2logn=2mn of node ob.
Ignoring rounding issues – and recalling ids are integer valued – this means that there are 2mn “vacant” ids between node oc and ob. To prove the theorem, we would have to show that there are O(logn) nodes occupying these ids, with high probability. This would mean that, with high probability, there would be a logarithmic number of hops that need to be followed before we reach ob, thus satisfying the bound. We will appease ourselves, however, with just showing that the expected number of nodes between oc and ob has to be 1; namely, that on average there is only one more hop to follow before we reach ob.
To see that this is true, let us start by looking at the probability that some random id in the DHT is occupied. Since ids are assigned uniformly at random and there are 2m such ids, it follows that each id can be occupied with probability 12m2. This means that the probability p that an id is occupied by one out of n nodes is given by:
p=n2m
We can then treat id occupation as a Bernoulli experiment, meaning that for a given range of s distinct ids, the probability of having k≤s occupied ids follows a binomial distribution B(s,p). If X∼B(s,p), it follows that the expected number of occupied ids between oc and ob is given by:
E[X]=s×p=2mn×p=2mn×n2m=1
which is what we wanted to demonstrate. ◼
This is not a complete proof, and it sweeps a number of important points under the rug - most notably that ids cannot be occupied twice, and that the expectation being 1 may not trivially imply that O(logn) bound is satisfied whp. But we will defer the complete proof to another day.