Livio Torrero - Politecnico di Torino Algoritmi per protocolli peer-to-peer Reti non strutturate: casi di studio 09/2008 Livio Torrero - Politecnico di Torino Napster: introduzione • Nato come applicativo per lo scambio di file musicali • Nel 1999 le major discografiche fanno causa a Napster => il bacino di utenza decolla – 13,6 milioni di utenti nel febbraio 2001 • Nel settembre 2001 viene ordinata la chiusura di Napster • Napster si converte in servizio a pagamento • Nel 2002 chiude 2 Livio Torrero - Politecnico di Torino Funzionamento di Napster • Quando un nodo entra nell’infrastruttura si registra presso il server – Upload della lista delle risorse gestite Peer Server centrale Upload • Quando un nodo cerca una risorsa fa un lookup sul server centralizzato Peer query Server centrale answer • In base ai risultati ottenuti il peer si connette a un altro peer per scaricare la risorsa Peer Downloa d Peer Server centrale 3 Livio Torrero - Politecnico di Torino Gnutella introduzione • Gnutella è un client p2p sviluppato nel 2000 da Justin Frankel e Tom Pepper di Nullsoft, appena acquisita da AOL – Pare sia stato scritto in 14 giorni… • In origine il codice sorgente doveva uscire in formato GPL • Tuttavia attraverso tecniche di reverse-engineering sono stati sviluppati numerosi cloni open-source – Limewire è software open-source che supporta la rete Gnutella 4 Livio Torrero - Politecnico di Torino Gnutella: evoluzione • Originariamente tutti i nodi in Gnutella erano uguali – I peer erano detti servent • Tuttavia questo approccio non scalava – Fare un flooding su tutti i nodi della rete non funziona – Bisogna tenere conto del fatto che non tutti i nodi sono uguali • Per meglio tenere conto delle caratteristiche della rete Gnutella è stato riorganizzato • Il risultato è una rete gerarchica a 2 livelli 5 Livio Torrero - Politecnico di Torino Gnutella(limewire): rete gerarchica (1/2) leaf leaf leaf ultrapeer ultrapeer ultrapeer ultrapeer leaf leaf leaf leaf • Ultrapeer – Fa da proxy per i nodi leaf • Sono loro ad effettuare le ricerche • Impediscono che i nodi leaf siano investiti dal traffico ad alta banda che investe gli ultrapeer – Un nodo ultrapeer deve avere una connessione Internet veloce non bloccata da firewall • Deve accettare connessioni TCP da nodi esterni • Deve essere possibile mandare pacchetti UDP entranti • limewire => upload 10kB/s, download 20kB/s 6 Livio Torrero - Politecnico di Torino Gnutella(limewire): rete gerarchica (2/2) leaf leaf leaf ultrapeer ultrapeer ultrapeer ultrapeer leaf leaf leaf leaf • Nodi leaf – Es: nodi con connessioni dialup – Sono fuori dall’overlay (si connettono agli ultrapeer come client) – Non accettano connessioni Gnutella – Cercano un ultrapeer a cui collegarsi il prima possibile • Dipendono dall’ultrapeer – Se un nodo leaf vuole diventare ultrapeer, prima si disconnette dalla rete per ripresentarsi tentando di diventare ultrapeer – Un nodo leaf dovrebbe restare leaf per almeno un’ora 7 Livio Torrero - Politecnico di Torino Perché una rete a 2 livelli? • La divisione tra ultrapeer e nodi normali permette solo ai nodi “migliori” entrare nell’overlay – Gli host lenti rallenterebbero le prestazioni dell’intero sistema se posti nell’overlay – L’overlay diventa più piccolo ma più funzionale – Dal punto di vista dei nodi leaf gli ultra-peer sono dei server 8 Livio Torrero - Politecnico di Torino Gnutella: overlay discovery • Un nodo per accedere all’overlay Gnutella deve conoscere almeno un ultrapeer – Le modalità con cui questo avviene non sono oggetto di Gnutella – Cache, well known nodes… • Come scoprire altri nodi? Pong caching • Messaggio Ping (richiesta): chi lo riceve risponde con un messaggio Pong • Messaggio Pong (risposta): contiene le informazioni relative a un computer (IP + porta) – Solo gli ultrapeer mandano i pong • Quando un ultrapeer riceve dei messaggi pong li mette nella sua pong cache – Solo gli ultrapeer hanno la pong cache • Quando un ultrapeer riceve un messaggio ping risponde con tutti i pong nella sua cache 9 Livio Torrero - Politecnico di Torino Gnutella handshake • Ogni connessione Gnutella comincia con un handshake – Un nodo accede all’overlay con un messaggio GNUTELLA CONNECT che apre un socket TCP • I messaggi di handshake sono costituiti da gruppi di header di formato simile ad HTTP (testo ASCII) – Ogni header è nella forma <nome>:<valore1>,<valore2>… – Ogni gruppo inizia con una greeting line che identifica il messaggio • Handshake a 3 vie: Host che si connette Host che riceve la connessione CONNECT OK OK 10 Livio Torrero - Politecnico di Torino Esempi di handshake Gnutella(1/3) • Un nodo leaf si connette a un UltraPeer (connessione generica) – 0.6 è la versione corrente di Gnutella leaf ultrapeer GNUTELLA connect/0.6 X-Ultrapeer=false • GNUTELLA/0.6 200 OK Un nodo leaf dietro un NAT si connette a un ultrapeer – Listen-IP indirizzo del peer che manda messaggio – Remote-IP indirizzo nodo leaf visto da UltraPeer leaf NAT GNUTELLA connect/0.6 X-Ultrapeer=false ultrapeer 217.254.98 .153 GNUTELLA/0.6 200 OK Listen-IP:68.37.233.44:9376 Remote-IP: 217.254.98.153 11 Livio Torrero - Politecnico di Torino Esempi di handashake Gnutella (2/3) • Un ultrapeer si connette a un ultrapeer ultrapeer ultrapeer GNUTELLA connect/0.6 X-Ultrapeer=true • GNUTELLA/0.6 200 OK Un nodo si connette a un ultrapeer che rifiuta la connessione – L’ultrapeer deve fornire peer alernativi Nodo Gnutella generico ultrapeer GNUTELLA connect/0.6 GNUTELLA/0.6 service unavailable X-Try-Ultrapeers:68.37.233.44:9376, 172.195.105.218:3988… 12 Livio Torrero - Politecnico di Torino Esempi di handshake Gnutella(3/3) • Un nodo si connette a un ultrapeer che accetta e fornisce indirizzi alternativi – È consigliato fornire altri ultrapeer a cui connettersi – Limewire ne fornsice 10 Nodo Gnutella generico ultrapeer GNUTELLA connect/0.6 GNUTELLA/0.6 200 OK X-Try-Ultrapeers:68.37.233.44:9376, 172.195.105.218:3988… 13 Livio Torrero - Politecnico di Torino Da nodo leaf a ultrapeer • I nodi decidono da soli se connettersi alla rete come Ultra peer o nodi normali – Un nodo DEVE restare leaf per un ora ultrapeer 1h leaf ultrapeer ultrapeer ultrapeer – Poi può tentare di connettersi a un ultrapeer come ultrapeer ultrapeer? ultrapeer connect ultrapeer ultrapeer ultrapeer ultrapeer – Se l’ultrapeer lo rifiuta, torna leaf per un’altra ora ultrapeer? Refuse connection ultrapeer ultrapeer ultrapeer ultrapeer Leaf for 1h leaf (!) leaf connect ultrapeer ultrapeer ultrapeer ultrapeer 14 Livio Torrero - Politecnico di Torino I Connection Slot: organizzazione delle connessioni in Gnutella • Un connection slot rappresenta la necessità di un nodo di creare una connessione verso un altro o la disponibilità ad accettare le connessioni • Un nodo leaf ha 3 connection slot verso gli Ultrapeer – Creerà fino a 3 connessioni verso ultrapeer diversi • Un ultrapeer si connetterà con al più 32 altri ultrapeer – questo valore è detto network degree • Un ultrapeer ha 30 connection slot verso i nodi leaf – Un ultrapeer non permette a più di 30 nodi foglia di connettersi a lui 15 Livio Torrero - Politecnico di Torino Lookup in Gnutella: introduzione • L’algoritmo di lookup è il dynamic querying – Obiettivo: localizzare una risorsa con il minor numero di messaggi possibile • Avvio mandando pochi messaggi • Intensifica alle fine • Se una risorsa è popolare la trovo subito – Viene eseguito solo dagli ultrapeer – Si articola in 3 fasi: • “Search our leaves” • “Probe Query” • “Controlled Broadcasting” • Il dynamic querying interagisce con il Query Routing Protocol (QRP) – Obiettivo: impedire che siano inviati messaggi di lookup che non ritornerebbero risultati 16 Livio Torrero - Politecnico di Torino Dynamic Querying: search our leaves • L’ultrapeer manda a tutti i suoi nodi foglia una query di lookup con TTL=1 • Dopo l’invio si attende per 2,4s • I nodi foglia che hanno copia della risorsa risponderanno alla query leaf T leaf TTL =1 1 L= T leaf 1 ultrapeer = L T T 1 = L T r T e sw n A leaf 17 Livio Torrero - Politecnico di Torino Dynamic Querying: probe query • L’ultrapeer manda a tutti gli ultrapeer ad esso collegati una query di lookup con TTL=1 • Gli Ultrapeer che hanno copia della risorsa risponderanno alla query • Gli ulrapeer inoltrano la richiesta ai loro nodi leaf – Reimpostano TTL=1 • Questa query serve a stimare la popolarità della risorsa • Se si ottengono 150 risposte positive in tutto l’algoritmo finisce leaf TTL=1 ultrapeer Answer leaf =1 L T T ultrapeer TTL =1 1 ultrapeer = L T T 1 = L T r T e sw n ultrapeer A 18 Livio Torrero - Politecnico di Torino Dynamic Querying: controlled broadcasting • Ogni 2.4s ultrapeer manda una query a uno solo degli ultrapeer connessi – TTL=2 oppure TTL=3 a seconda del numero di risposte ottenute nella fase precedente • Se si ottengono 150 risposte positive l’algoritmo finisce • Se trascorrono più di 200s dall’inizio della ricerca l’algoritmo è interrotto • E’ una ricerca in profondità: – La probe query stimava la popolarità della risorsa presso i soli ultrapeer vicini – Il controlled broadcasting effettua una ricerca approfondita partendo da uno solo degli ultrapeer vicini • A seconda del valore del TTL si parla di: – Ricerca TTL2 – Ricerca TTL3 19 Livio Torrero - Politecnico di Torino Ricerca TTL2 e ricerca TTL3 Ultrapeer A TTL=2 Ultrapeer B TTL=1 Leaf 1 Ultrapeer C Leaf 2 • A inizia la ricerca: manda query con TTL=2 SOLO a B • B decrementa il TTL=> TTL=1 – TTL<>0 => inoltra la query a TUTTI gli ultrapeer ad esso collegati (in figura, C è il solo connesso) • C decrementa il TTL => TTL=0 – TTL=0 => inoltra la query a TUTTI i leaf ad esso collegati • La TTL3 funziona nello stesso modo (TTL=3) – la ricerca coinvolge un numero elevato di ultrapeer – Limewire non usa MAI TTL>3 20 Livio Torrero - Politecnico di Torino Gnutella: Query Routing Protocol • Nel Dynamic Querying gli ultrapeer inoltravano le query ai nodi leaf collegati – Se il nodo leaf non mantiene risorse, è inutile propagare la query – Se l’utente del nodo leaf non vuole rispondere alle query, è inutile propagargli la query • Il QRP a questo scopo permette al nodo leaf di mandare all’ultrapeer una descrizione delle risorse gestite – Le informazioni sono contenute nella QRP table – Inviata dopo la connessione – Appositi messaggi permettono l’aggiornamento delle informazioni della QRP table 21 Livio Torrero - Politecnico di Torino QRP table • Array di 65,536 byte – Un nodo che non condivide nulla li setta tutti a 0 – Se il nodo leaf condivide il file limewire.exe: • Calcola l’hash del nome del file • Setta a 1 il bit corrispondente nella QRP table • Verranno inoltrate le query per limewire.exe • Gli ultrapeer possono generare QRP table composite – Vengono scambiate tra gli ultrapeer – Sono generate a partire dalle QRP table delle foglie • Se un bit è a 1 in una QRP table di una foglia, viene settato a 1 nella QRP table dell’ultrapeer • Last hop saving: – Se un ultrapeer riceve query con TTL=1 e la QRP table composita blocca, la query non è inoltrata 22 Livio Torrero - Politecnico di Torino Algoritmi per protocolli peer-to-peer Reti strutturate: casi di studio 09/2008 Livio Torrero - Politecnico di Torino CHORD • CHORD realizza un DHT con le seguenti caratteristiche: – Load balance: CHORD distribuisce uniformemente le chiavi fra i nodi – Scalabilità: le operazioni di lookup sono efficienti • Richiedono O(log(N)) messaggi scambiati fra i nodi (N = #peer) – Robustezza: CHORD è in grado d modificare dinamicamente le routing table dei nodi per riflettere i mutamenti della rete (nodi che entrano o escono) • CHORD fornisce il metodo lookup(key) che ritorna l’indirizzo IP del nodo responsabile per la chiave • CHORD si basa sul consistent hashing 24 Livio Torrero - Politecnico di Torino Consistent hashing in CHORD • Se N è il numero di nodi presenti sulla rete, al variare di N si desidera che: – Si garantisca l’uniformità della distribuzione delle chiavi sui nodi – La quantità di dati da rimappare nel sistema sia bassa • Il consistent hashing organizza i nodi in un cerchio modulo m 2 (m = #bit ID) 0 1 6 m=3 #bit chiave 2 4 3 • L’algoritmo di hash usato è SHA1 • Gli ID dei nodi sono i codici hash ottenuti dagli indirizzi IP • Gli ID delle chiavi sono i codici hash ottenuti dalle chiavi • NOTA: gli ID dei nodi e gli ID delle chiavi sono nello stesso spazio 25 Livio Torrero - Politecnico di Torino CHORD: assegnazione delle chiavi (1/2) • La chiave k è assegnata al primo nodo n sull’anello il cui identificatore è uguale o maggiore all’identificatore di k • La metrica di distanza in CHORD è la differenza lineare • Si dice n=successor(k) – n, il nodo responsabile di k è detto successore di k – CHORD espone la chiamata find_successor per localizzarlo 26 Livio Torrero - Politecnico di Torino CHORD: assegnazione delle chiavi (2/2) • La metrica di distanza è unidirezionale – Data una distanza D e un nodo x, esiste un solo nodo y per cui d(x,y) = D – Tutti i lookup per una stessa chiave convergono sullo stesso path – E’ utile fare caching dei risultati dei lookup sui nodi intermedi • All’arrivo di un nuovo peer questi riceve alcune chiavi del nodo che lo segue sull’anello – Ora è il nuovo responsabile per quelle chiavi – Es: cosa succede in figura se entrasse il nodo 7? – 7 = successor(6) => la chiave 6 è spostata dal nodo 0 al nodo 7 27 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (1/7) • Per fare le ricerche ogni nodo in teoria ha bisogno solamente di conoscere il nodo che segue Dove si trova la chiave 5? 0 1 6 2 Chiave 5 4 3 • CHORD assicura la validità di questi puntatori • Tuttavia questo non è sufficiente per garantire prestazioni accettabili – Ricerca lineare 28 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (2/7) • Si supponga invece che il nodo abbia informazioni su TUTTI gli altri nodi (routing table completa) Dove si trova la chiave 5? 0 1 6 2 Chiave 5 4 3 • Impraticabile: richiede N entry nella routing table! – N = numero nodi nell’overlay! 29 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (3/7) • Per ottimizzare CHORD mantiene le finger table – Al più m nodi, a regime O(log(N)) distinti in finger table i−1 • [entry ‘i’ nella finger table di un nodo n] = successor(n +2 con 1≤i≤m ) (chiavi di hash su m bit) – La entry contiene l’ID del nodo e il suo IP – il primo finger è l’immediato successore del nodo sull’anello 0 1 m=3 #bit chiave Finger table(1) Valore i entry 1 successor(2)=3 2 successor(3)=3 3 successor(5)=0 3 30 Livio Torrero - Politecnico di Torino Chord: lookup sacalabile (4/7) • CHORD utilizza le entry nella finger table per coprire tutto l’anello • La entry –iesima della finger table del nodo n copre l’intervallo di chiavi [n.finger[i].start, n.finger[i+1].start) – n.finger[i].start = (n + 2 i −1 ) mod 2m – Per definizione la entry della finger table sta dentro l’intervallo • ‘succ’ nella figura m=3 #bit chiave 31 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (5/7) • Obiettivo dell’algoritmo di lookup: – Se eseguo la ricerca di una chiave k partendo da un nodo n, se esiste una entry s della finger table di n tale per cui: • La chiave k sia più grande di s • La chiave k sia più piccola di s’=successor(s) essendo per definizione s’ il nodo che segue immediatamente s sull’anello, ed essendo k posta fra s ed s’, non potrà esserci alcun nodo fra k e s’: quindi s’ è successore di k • Ovvero s’ è il nodo che memorizza la coppia <chiave, valore> con chiave=k 32 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (6/7) • Algoritmo di lookup: – Cerco la chiave k partendo dal nodo n Cerco nella finger table di n il nodo n’ con l’identificativo più grande che sia minore di k k ∈(n’,n’.successor] No n=n’ ? Sì n’.successor è il nodo responsabile di k 33 Livio Torrero - Politecnico di Torino CHORD: lookup scalabile (7/7) • Esempio: • Nodo 3 vuole trovare chi gestisce la chiave 1 (= successor(1)) • 1 ∈[7,3) : quindi 3 manda una query al nodo 0 (entry #3 della finger table) • 1 ∈[1,2): il nodo 0 conosce successor (1) e lo dice a 3 34 Livio Torrero - Politecnico di Torino CHORD: join dei nodi • L’entrata o l’uscita dei nodi nell’overlay può avvenire in qualsiasi momento • Perché tutto funzioni si DEVE garantire che: – Il successore di ogni nodo sia noto – Per ogni chiave k, successor(k) ne sia il responsabile • Inoltre è auspicabile che le finger table siano corrette • Al join, un nodo n deve: – Inizializzare le entry della sua finger table • Per ogni i calcola finger[i].start e lo fa cercare da un qualsiasi nodo della DHT – Aggiornare le finger degli altri nodi inserendosi in esse se necessario – Muovere sul nodo n tutte le chiavi di cui è responsabile • La join realizzata in questo modo è molto aggressiva. • In realtà si utilizza un algoritmo più leggero ma più complesso che supporta join multiple simultanee – stabilizzazione 35 Livio Torrero - Politecnico di Torino CHORD: uscita dei nodi • L’uscita dei nodi si potrebbe trattare come una failure degli stessi e non fare nulla • Per ottimizzare, quando un nodo esce dall’overlay (graceful leave): – Trasferisce le chiavi di cui è responsabile al suo successore – Aggiorna il puntatore al nodo che lo precede del nodo che lo segue sull’anello – Aggiorna il puntatore al nodo che lo segue del nodo che lo precede sull’anello 36 Livio Torrero - Politecnico di Torino CHORD: ridondanza informazioni • Perché CHORD funzioni occorre che ogni nodo conosca il suo immediato successore sull’anello • Per evitare problemi dovuti a failure dei nodi, ogni nodo mantiene una lista dei nodi che lo seguono (lista di successori) – Nel caso in cui un nodo non è utilizzabile attraverso la lista di successori è possibile individuare percorsi alternativi. 37 Livio Torrero - Politecnico di Torino Kademlia • Sistema di lookup che utilizza una metrica di distanza basata su XOR • Date due chiavi x e y la loro distanza è d(x,y)=x xor y – Xor bit a bit • Realizza una topologia ad albero basata sulla metrica • Kademlia utilizza query parallele asincrone • Gli identificatori delle risorse sono chiavi su 160 bit (SHA-1) 38 Livio Torrero - Politecnico di Torino Proprietà della metrica • Lo XOR è unidirezionale – Data una distanza D e un nodo x, esiste un solo nodo y per cui d(x,y) =D – Tutti i lookup convergono sugli stessi path – E’ utile fare caching dei risultati dei lookup sui nodi intermedi • Lo XOR è simmetrico – d(x,y) = d(y,x) – La metrica viene usata per popolare le routing table dei nodi – Se x è nella routing table di y, x è nella routing table di y – I refesh delle routing table sono eseguiti direttamente durante le operazioni normali fra i nodi – La stabilizzazione è meno problematica 39 Livio Torrero - Politecnico di Torino Kademlia: binary tree • Kademlia tratta i nodi come foglie di un albero binario – La posizione di un nodo è determinata dal suo prefisso univoco più corto • Il primo sottoalbero a sinistra è la prima metà che non contiene il nodo e così via, ricorsivamente • Kademlia garantisce che il nodo con prefisso univoco 000 conosca almeno un nodo in ciascuno degli altri sottoalberi 40 Livio Torrero - Politecnico di Torino Kademlia: binary tree • Grazie alla conoscenza di tutti i sotto alberi ogni nodo può trovare qualsiasi altro nodo dell’albero • Un nodo attraverso la sua routing table riesce a localizzare in una serie di passaggi successivi qualsiasi nodo sull’albero in modo ottimale • La routing table è organizzata come un insieme di k-bucket 41 Livio Torrero - Politecnico di Torino Kademlia: k-buckets (1/5) • Per ogni 0 ≤ i<160, ogni nodo ha una lista di <IP,porta,NodeID> per i nodi che distano tra 2^i e 2^(i+1) da se => k-buckets m=3 #bit chiave Tabella nodo 0 0 [1,2) 1 [2,4) 2 [4,0) nodo1 nodo2 nodo3 nodo4 nodo5 K-bucket K = numero massimo di elementi in un k-bucket: parametro di sistema fisso (qui k=2) 42 Livio Torrero - Politecnico di Torino Kademlia: k-buckets (2/5) • Quando un nodo riceve un qualsiasi messaggio, aggiorna il k-bucket corrispondente • Algoritmo (il nodo A riceve un messaggio dal nodo B): 43 Livio Torrero - Politecnico di Torino Kademlia: k-buckets (3/5) • Esempio: Tabella nodo 0 0 [1,2) 1 [2,4) 2 [4,0) nodo1 nodo2 nodo3 nodo4 nodo5 nodo4 m=3; k=2 1. 6 manda un messaggio a 0, ma il k-bucket è pieno (k=2) 2. 0 interroga 4 3. 4 risponde e viene spostato al fondo (6 è fuori) 44 Livio Torrero - Politecnico di Torino Kademlia: k-buckets (4/5) • Esempio: Tabella nodo 0 miss 0 [1,2) 1 [2,4) 2 [4,0) nodo1 nodo2 nodo3 nodo4 nodo5 nodo6 m=3; k=2 1. 6 manda un messaggio a 0, ma il k-bucket è pieno (k=2) 2. 0 interroga 4 (nodo in testa) 3. 4 non risponde: 6 è messo in fondo al k-bucket 45 Livio Torrero - Politecnico di Torino Kademlia: k-buckets (5/5) Tabella nodo 0 Tabella nodo 0 0 [1,2) 1 1 [2,4) 2 3 2 [4,0) 4 5 6 0 000- 1 1 001- 2 3 2 01-- 4 5 6 k-bucket 1 k-bucket 2 k-bucket 0 46 Livio Torrero - Politecnico di Torino Kademlia: metodi esportati • Kademlia offre 4 funzioni: – PING: verifica se un nodo è attivo – STORE: memorizza la coppia <chiave, valore> nel nodo più vicino alla chiave • STORE(chiave) Le informazioni vengono replicate <chiave, valore> – FIND_NODE: data una chiave ritorna (IP, porta, NodeID) per i k nodi più vicini alla chiave. • I k nodi possono provenire da più k-bucket se il k-bucket più vicino non è pieno – FIND_VALUE: variante della precedente per ottenere un valore data una chiave 47 Livio Torrero - Politecnico di Torino Kademlia: node lookup (1/4) • Obiettivo: localizzare il nodo più vicino a un Node ID A. • E’ possibile dimostrare che il numero di passi per localizzare un nodo è logaritmico • Nell’algoritmo reale vengono inviate più richieste in parallelo – Si manda un numero di richieste < k (alfa) – In questo modo si evitano problemi con i timeout dei nodi offline • Le risposte alle richieste contengono i k nodi più vicini • L’algoritmo ricorsivo termina quando i k nodi più vicini al nodo destinazione hanno risposto 48 Livio Torrero - Politecnico di Torino Kademlia: node lookup (1/4) • Se il nodo 1 vuole contattare il nodo 5: 0 1 1 6 0 1 0 4 1 3 1 0 0 1 2 1 0 0 5 1. Nodo 1 manda FIND_NODE(5) a uno dei nodi nel k-bucket 1--. (perche il bucket 1– è il più vicino a 5) (si suppone che 5 non sia nei k-bucket di 1) 49 Livio Torrero - Politecnico di Torino Kademlia: node lookup (2/4) 1 1 6 0 0 1 5 0 4 1 3 1 0 0 1 2 1 0 0 2. Il nodo 6 ritorna al nodo 1 l’indirizzo del nodo 4 (il più vicino a 5) (si suppone che 5 non sia nei k-bucket di 6) 3. Il nodo 1 manda una FIND_NODE(5) al nodo 4 50 Livio Torrero - Politecnico di Torino Kademlia: node lookup (3/4) 1 1 6 0 0 1 5 0 4 1 3 1 0 0 1 2 1 0 0 4. Il nodo 4 risponde infine al nodo 1 dicendogli l’indirizzo del nodo 5 5. Il nodo 1 può contattare il nodo 5 51 Livio Torrero - Politecnico di Torino Kademlia: refresh periodico • i k-bucket sono rinfrescati periodicamente dal passaggio delle richieste attraverso i vari nodi. • Può tuttavia accadere che uno specifico k-bucket non sia rinfrescato per un certo periodo – mancanza di richieste sui nodi del range coperto dal kbucket • Per questa ragione un refresh viene effettuato entro un'ora – si prende a caso un ID all'interno del range del bucket e se ne fa il lookup 52 Livio Torrero - Politecnico di Torino Kademlia: join, leave • Per fare join un nodo ‘u’ deve conoscere in qualche modo un nodo ‘w’ dentro l'overlay. • Procedura di join: 1) ‘u’ inserisce ‘w’ nel k-bucket ad esso relativo 2) ‘u’ fa un lookup di se stesso attraverso ‘w’ • ‘u’ inizia così a riempire i suoi k-bucket 3) farà un refresh di tutti i suoi k bucket • effettua ricerche nei range degli ID gestiti da ogni k-bucket • L’uscita di un nodo non richiede operazioni aggiuntive 53 Livio Torrero - Politecnico di Torino Kademlia: memorizzare dati sull’overlay • Procedura utilizzata per memorizzare nuovi dati nell’overlay – Un nodo desidera memorizzare una entry contenente dati sull’overlay • Il nodo che vuole inserire nuovi dati, localizza i k nodi più vicini alla chiave relativa ai dati da memorizzare • Viene quindi eseguita una STORE su ciascuno di essi • Ogni nodo che ha memorizzato una coppia chiave valore ripubblica ogni coppia chiave/valore entro un ora • L’originatore della coppia ripubblica la coppia ogni 24 ore 54 Livio Torrero - Politecnico di Torino Confonto tra CHORD e Kademlia • In CHORD la routing table è rigida – Richiede costose operazioni per essere mantenuta in caso di failure di un nodo • Kademlia offre una routing table flessibile – Metrica di distanza simmetrica oltre che unidirezionale – Esiste sempre più di un percorso alternativo – Le ricerche sono parallelizzate – La manutenzione della routing table è più bassa – I k-bucket sono liste di nodi: maggiore robustezza • E’ possibile dimostrare che il numero di entry nella routing table di Kademlia è logaritmico 55 Livio Torrero - Politecnico di Torino Limiti delle DHT (1/3) • I client p2p sono transienti per natura – Il tempo di connessione media per un nodo è di 60min • In Gnutella se un nodo perde tutti i vicini prova semplicemente a riconnettersi • Nelle DHT il problema è più grave (almeno in CHORD) – L’uscita di un nodo graceful (=“annunciata”) comporta in genere O(log(n)) operazioni per mantenere coerenti le strutture dati – Un uscita graceless (senza annuncio è trasferimento preventivo di informazioni di stato) ha esiti peggiori • Richiede tempo per: – Rilevare la failure – Replicare i dati persi dal peer disconnesso 56 Livio Torrero - Politecnico di Torino Limiti delle DHT (2/3) • Le ricerche di parole chiave sono più numerose delle ricerche esatte – Le DHT si prestano a ricerche esatte • Dato il nome esatto di un file lo localizzano – E’ possibile implementare ricerche per parole chiave nelle DHT, ma è costoso – Le p2p non strutturate non hanno di questi problemi: perché le ricerche si fanno sulla base di informazioni contenute nei singoli nodi • Le DHT trovano un ago in un pagliaio, i p2p non strutturati no – Gnutella non può garantire di poter trovare una singola copia di un file a meno che la query non raggiunge tutti i nodi 57 Livio Torrero - Politecnico di Torino Limiti delle DHT (3/3) • Tuttavia la distribuzione delle richieste privilegia i file più replicati – Questo limita gli svantaggi delle reti non strutturate 58 Livio Torrero - Politecnico di Torino Algoritmi per protocolli peer-to-peer Bittorrent (caso di studio) 09/2008 Livio Torrero - Politecnico di Torino Bittorent: concetti base (1/2) • La rete Bittorrent si basa su tracker – Spesso integrato con servizio di lookup – Il tracker è un web server che offre supporto per il download • I Bittorrent indexer localizzano i file • Per condividere un file il client creano un torrent – Il torrent è un metadata che descrive il file • La pubblicazione di un file su Bittorrent richiede: – Creazione di un file “.torrent” che descrive un file – Creare un tracker per quel file sul webserver locale – Creare una copia “seed” per quel download • La copia seed altro non è che una copia integrale del file 60 Livio Torrero - Politecnico di Torino BitTorrent: concetti base (2/2) • Scopo: razionalizzare le risorse di rete – = banda e spazio sui dischi • Gli algoritmi visti fino ad ora mirano ad un lookup il più veloce possibile • BitTorrent mira a garantire la massima replicabilità delle risorse • Componenti base: – Torrent = descrittore del file – Tracker • Entità centralizzata che gestisce il download – Peer: • Seed: peer che hanno una copia integrale del file • Leechers: peer che non hanno ancora una copia intera 61 Livio Torrero - Politecnico di Torino BitTorrent: funzionamento di base • Un peer ricava in qualche modo un torrent – Tipicamente da web server – Il torrent contiene l’indirizzo del tracker • Il peer contatta il tracker e fa la join del torrent – Il tracker ritorna gli indirizzi di almeno 50 peer che gestiscono il file – Il peer mantiene connessioni con almeno 20 (fino a 40) • Se no riesce ad averne almeno 20 ricontatta il tracker • Ciascun peer che partecipa al torrent invia ogni 30 minuti un report al tracker – Informazioni di stato – Lo fa anche al join e al leave 62 Livio Torrero - Politecnico di Torino BitTorrent: tecniche di swarming (1/2) • La velocità in download e quella in upload dei PC domestici sono differenti • chi scarica da un peer è limitato dalla velocità in upload di quest’ultimo • Idea: scaricare in parallelo da più peer • Le tecniche di swarming consistono nella suddivisione di un file chunk – Chunk = blocchi di dati tipicamente da 256 kB – I peer formano uno swarm 63 Livio Torrero - Politecnico di Torino Bittorrent: tecniche di swarming (2/2) • I chunk sono scambiati tra i peer • In questo modo è possibile scaricare in parallelo i chunk – Download paralleli di chunk diversi da peer diversi – Ogni volta che un peer ottiene un chunk, informa i peer a lui collegati • Come decide un peer quale chunk scaricare prima? Scarico prima il chunk più raro – Il peer decide sulla base delle informazioni ottenute dal tracker • Manca una visione globale reale, si ha solo una stima – Politica atta a massimizzare l’entropia dei chunk 64 Livio Torrero - Politecnico di Torino BitTorrent: choke e unchoke • Un peer manda dati a peer che ne hanno mandati a lui (Tit-for-tat) • Ogni peer serve al più 4 peer – Se è un seed cerca i 4 migliori downloader (in base al bit rate) – Se è un leecher cerca i 4 migliori uploader (in base al bit rate) • Questo è realizzato con choke/unchoke – Choke: mi rifiuto di servire un peer (tuttavia non chiudo la connessione) – Un leecher si collega i 4 migliori uploader e fa choke con gli altri – Ogni 10 secondi un leecher verifica quale dei 4 è più lento in upload e ne fa il choke – Un seed si collega i 4 migliori downloader e fa choke con gli altri – Ogni 10 secondi un seed verifica quale dei 4 è più lento in download e ne fa il choke • Optimistic unchoke: – Ogni 30 s un leecher abilita un nuovo uploader fra quelli in choke, a prescindere dalle sue prestazioni – Ogni 30 s un seed abilita un nuovo downloader fra quelli in choke, a prescindere dalle sue prestazioni – Posso scoprire così nuovi peer che offrono migliori prestazioni 65 Livio Torrero - Politecnico di Torino BitTorrent trackerless • Idea: il tracker è l’unica entità centralizzata in Bittorrent, sostituiamolo con una DHT – A partire dalla versione 4.2.0 (2005) – Ogni peer diventa un un tracker collegato agli altri sulla DHT • L’algoritmo DHT usato è Kadmelia • Coppie <chiave, valore> nella DHT: – Chiave=Info-hash: identifica univocamente un torrent – Valore= lista dei peer nello swarm • Esempio: un peer vuole entrare a far parte di un torrent: – Cerca l’info-hash del torrent nella DHT – Manda un messaggio ANNOUNCE al/ai nodo/i responsabili della chiave • I nodi aggiungono il nuovo peer alla lista dei peer del torrent 66