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