Application layer: P2P ======================= *** Outline *** - P2P file transfer: BitTorrent - Distributed Hash Tables * So far, we have seen client-server application architectures. What is the limitation? Scalability / cost. Suppose a server needs to distribute a large file to a large number of clients. The server needs to be very powerful and have a high bandwidth link. Instead, the server can send the file to a few clients, and the clients can help distribute to other clients. This is the idea behind peer-to-peer (P2P) architectures. * Most popular P2P application: BitTorrent. How does BitTorrent work? The collection of all peers that participate in distributing a file is called a "torrent" or a "swarm". A file is divided into chunks (say 256KB) and peers download chunks from one another. Peers that have a chunk also upload the chunk to other peers. * How to locate peers in a torrent/swarm? Each torrent has a centralized node called "tracker" (information about the swarm and tracker can be got from other means, say webpage). Every peer informs tracker when it joins, so tracker knows which peers exist. When a new peer joins, the tracker picks a random subset of peer and introduces them to the new peer (i.e., provides IP addresses of other peers). The new peer then establishes TCP connections to other peers. * Peers exchange information on who has which chunks of files. Then a peer will request chunks that it does not have from other peers. Peers use "rarest first" policy. That is, they first download the chunk that has least presence amongst peers. This way, less popular chunks get distributed fast. * In addition to downloads, peers also have to help other peers by uploading. BitTorrent uses a tit-for-tat policy, where a peer uploads most to those peers who are supplying it data at highest rate. It calculates these peers every few seconds and these peers are said to be "unchoked". Typically, 4 unchoked peers. A peer may also choose to optimistically unchoke a random peer (so that new peers can find someone to download from). Lot of research done on the incentives of BitTorrent, can it be gamed etc. * But the tracker is centralized and can become a bottleneck / point of failure. How to deal with it? We could build a distributed tracker that maps a file to a node/nodes that is/are responsible for it. We need this information to be distributed across several nodes, so that no one node is the bottleneck. The generalized version of such a distributed application is called a DHT (Distributed Hash Table). DHTs store (key,value) pairs. For example, in BitTorrent, the key is name of torrent identifier (say, movie name) and value is list of IP addresses of peers. These key-value pairs are not stored in a central database but distributed over several nodes. A DHT can survive even if some nodes join/leave etc. * Let's design a simple DHT. What is the key step in a DHT? We should be able to map keys to nodes. Once we know which nodes are responsible for which set of keys, then any operation like creating / searching / updating / deleting a key-value pair can happen by simply going to the node responsible for the key, and requesting the specific operation. So the key step is, given key, identify node. * How do DHTs solve this problem? The basic recipe of all DHTs is as follows. Pick a name space (say 160 bit numbers), and map keys and nodeIDs in this region. For example, key=hash(movie_name), and nodeID = hash(node IP address). Now, assign every key-value pair to its closest (or immediately suceeding) node in the 160-bit space. This is called "consistent hashing". For example, if we consider 4 bit name space, let the keys to be assigned be 2, 7, 10. Let the nodes have IDs 3, 6, 9. Then key 2 will be assigned to node 3, 7->9, 10->3. So every time you want to search / update a key, go to the node with the ID immediately after the key and ask for the key-value pair. * But how do you know which node ID is close to which key? Must maintain a list of all nodeIDs and their IP addresses. Or, learn about a small subset of "neighbors" (e.g., nodes with IDs just before and after yours), and pass on the query. All DHTs have this basic tradeoff - the more neighbors you have, the faster you will be able to search/update a key-value pair. * Let's see a simple example of a DHT, a circular DHT, approximation of the "Chord" DHT. In such a DHT, a set of nodes come together to cooperatively store/search/update key-value pairs. Each node in the DHT / peer picks a random n-bit identifier in the range 0 to 2^n -1. Every piece of content is also assigned a n-bit "key", say, by hashing the name of the movie. Then, the key-value pair is stored at the peer whose ID is immediately after the content's hash. Every peer/node in the DHT knows about its successor and few other peers (their IDs, IP addresses etc). * In the simple case, every node only knows its successor. So to locate any key-value pair, you need to "walk around the circle" to find the correct node. That is, every operation thats O(N). Alternately, you can maintain pointers to a few other nodes on the circle. Chord proposes that you maintain pointers to a node that is half-way across in ID space, 1/4th across, 1/8th across etc. That is, you maintain around log N "fingers", where the i-th finger is first node that suceeds your nodeID by 2^i. Basically, you are maintain more pointers to nodes near you and fewer pointers to nodes far away. So, you can search logarithmically in O(log N) time for a key. * DHTs are a special case of what are called "overlay networks". In an overlay network, a subset of nodes together create their own network and topology. For example, in the circular DHT, nodes emulate a circular topology over the physcial topology. DHTs are structured overlay networks. You can also have unstructured overlays, where a bunch of nodes form a virtual network between themselves. * Note that the Internet itself was built as an overlay network over telephone lines. * Hybrid architectures: combination of client-server and P2P. Example is multimedia services any VoIP service / Skype. Suppose you want to start a voice call between users A and B. First thing to do would be for A to obtain B's IP address (or vice versa), after which the call can proceed in a P2P fashion. However, we need a service to map VoIP user names to IP addresses. This is handled by SIP (Session Initiation Protocol). User A contacts its SIP proxy asking it to resolve user B's name. SIP proxy contacts the SIP registrar in B's domain and obtains B's IP address. All this while, user A hears the "ringing" sound. The registrars and proxies can run on same machine. Note how this is a hybrid architecture. The call setup is in a client-server model, but the actual media flows in a P2P fashion. SIP is called a "signaling protocol". * Further reading - "Chord: A Scalable Peer-to-peer Lookup Service for Internet Applications", Stoica et al. This paper describes the circular DHT we discussed above. It is worth understanding how Chord approximates a binary search over the ID space, so that you can get to any content in O(log N) steps instead of O(N) steps if you walk around the circle. - "Do incentives build robustness in BitTorrent?", Piatek et al. This paper studies the issue of freeriding in perr-to-peer networks, using Bit Torrent as an example.