Sistemi Peer to Peer Gennaro Cordasco Dipartimento di Informatica e Applicazioni Università degli Studi di Salerno cordasco[@]dia.unisa.it cordasco+p2p[@]gmail.com http://www.dia.unisa.it/~cordasco Laboratorio ISISLAB2 (DIA Piano 2) 18/09/2018
Materiale didattico i) Peer-to-Peer Systems and Applications Series: Lecture Notes in Computer Science , Vol. 3485 Sublibrary: Information Systems and Applications, incl. Internet/Web, and HCI www.peer-to-peer.info Steinmetz, Ralf; Wehrle, Klaus (Eds.) 2005, XVII, 629 p. With online files/update., Softcover ISBN: 978-3-540-29192-3 ii) Research papers (http://www.dia.unisa.it/~cordasco) iii) JXTA java Programmers guide (http://www.dia.unisa.it/~cordasco) iv) JXTA Protocol Specifications (http://www.dia.unisa.it/~cordasco) v) Le slide del corso (http://www.dia.unisa.it/~cordasco) … che ovviamente non sono sufficienti per superare l’esame!!! 18/09/2018
20/10 Chord (2a parte) + Consistent Hashing 27/10 Altre DHT + LB 13/10 DHT + Chord (1a parte) 20/10 Chord (2a parte) + Consistent Hashing 27/10 Altre DHT + LB 03/11 Koorde 10/11 JXTA 17/11 JXTA 24/11 Esercitazioni (parte teorica) 1/12 Prova scritta 15/12 JXTA 22/12 JXTA 18/09/2018
Le vostre domande Nessun pervenuto!!! 18/09/2018
Esercizi Consideriamo la rete a s dimensioni proposta nel modello di Kleinberg. Se eliminiamo i long-range allora il diametro è: log2 n n n/s s n1/s Supponiamo che l’attore mister x ha Bacon number 4. Sapendo che Tom Hanks ha Bacon number 1 (hanno girato insieme Apollo 13). Cosa possiamo dedurre sull’ Hanks number di mister x: vale 3 vale 2 è compreso tra 3 e 5 non possiamo dedurre niente Nè le reti random nè quelle regolari permettono di modellare le reti reali in quanto: le reti random hanno un coefficiente di clustering troppo alto mentre quelle regolari hanno una APL troppo basso le reti random hanno un coefficiente di clustering troppo basso mentre quelle regolari hanno una APL troppo alto Entrambe le reti hanno un coefficiente di clustering troppo basso Nessuna delle precedenti 18/09/2018
Sommario Introduzione Reti P2P non strutturate Random Graphs, Small-Worlds and Scale-Free Networks Reti P2P strutturate Distributed Hash Tables Chord (1° parte) Lower Bound Reti non Uniformi JXTA 18/09/2018
Capitolo 7: Distributed Hash Tables
DHT: Obiettivi D ? Data item „D“ distributed system 7.31.10.25 peer - to peer.info 12.5.7.31 95.7.6.10 86.8.10.18 planet lab.org berkeley.edu 89.11.20.15 I have item „D“. Where to place „D“? I want item „D“. Where can I find „D“? Qual’è l’obiettivo fondamentale nella maggior parte dei sistemi P2P? Trovare la posizione nella quale è stato allocato un determinato elemento Colui che pubblica l’elemento, dove deve memorizzarlo? Chi ha bisogno di un elemento, dove deve cercarlo? Scalabilità: in termini di numero di messaggi e dimensione della memoria Robustezza e affidabilità in caso di fallimenti o continui cambiamenti nella topologia della rete
DHT: Obiettivi ? Strategie Server Centrale Flooding Data item „D“ distributed system 7.31.10.25 peer - to peer.info 12.5.7.31 95.7.6.10 86.8.10.18 planet lab.org berkeley.edu 89.11.20.15 I have item „D“. Where to place „D“? I want item „D“. Where can I find „D“? Strategie Server Centrale Flooding Distributed indexing (DHT)
Central Server Una strategia semplice: Server Centrale Il Server memorizza informazioni su tutti i nodi Il nodo A (provider) informa il Server che ha a disposizione D Il nodo B (requester) chiede al Server: “dove si trova D”? Il Server S informa B che D si trova presso A Il node B richiede D ad A “A stores D” Server S “Where is D ?” Node B “A stores D” “A stores D” Transmission: D Node B Node A
Server Centrale Vantaggi Problemi In ogni caso, … Compelessità di ricerca O(1) – “just ask the server” Possibilità di fare query complesse (Fuzzy query) Semplice e veloce Problemi Non è scalabile O(n) è lo spazio richiesto al server per memorizzare le informazioni di tutti i nodi O(n) è il carico richiesto al server (banda e computazione) Facile da attaccare In ogni caso, … E’ la migliore scelta per sistemi piccoli e semplici!
Flooding Search Approccio completamente distribuito Recupero dei dati Approccio opposto rispetto ai sistemi centralizzati Nessuno mantiene informazioni su chi ha cosa Il provider dei contenuti è anche responsabile della loro memorizzazione Recupero dei dati Non ci sono informazioni che possano guidare il routing L’unica via e inoltrare la query verso quanti più nodi è possibile Approcci Flooding: crea un mare di traffico nella rete, non è scalabile Crawling: può essere estremamente lento
Flooding Search Approccio completamente decentralizzato: Flooding E’ necessaria una visita completa del grafo Il node B (requester) chiede ai suoi vicini se hanno l’elemento D - I nodi inoltrano la richiesta ad altri nodi (breadth-first search / flooding) Il nodo A (provider of item D) invia D al nodo B “B searches D” Node B “I have D ?” & Transmission: D Node B “I store D” Node A
Communication overhead vs. node state Flooding O(N) Bottleneck: Communication Overhead False negatives Communication Overhead Bottlenecks: Memory, CPU, Network Availability ? O(log N) Central Server Scalable solution between both extremes? O(1) O(1) O(log N) O(N) Node State
Communication overhead vs. node state Flooding Scalability: O(log N) No false negatives Resistant against changes Failures, Attacks Short time users O(N) Bottleneck: Communication Overhead False negatives Communication Overhead Bottlenecks: Memory, CPU, Network Availability Distributed Hash Table O(log N) Central Server O(1) O(1) O(log N) O(N) Node State
DHT L’obiettivo è scalare la complessità in termini di Comunicazione: O(log(N)) passi Utilizzo della memoria: O(log(N)) entry nella tabella di routing Routing in O(log(N)) passi Ogni nodo memorizza O(log(N)) informazioni utili per il routing
Sommario System Per Node State Communi-cation Overhead Fuzzy Queries No false negatives Robust-ness Central Server O(N) O(1) Flooding Search O(N²) Distributed Hash Tables O(log N)
Distributed Hash Tables Obiettivi nella progettazione di DHTs Caratteristiche richieste Flessibilità Affidabilità Scalabilità Bilanciamento del carico sui nodi Utilizzo della memoria Utilizzo della banda Responsabilità Devono essere robuste anche in caso di frequenti faults, joins, exits dei nodi
Gestione distribuita dei dati Sequenza delle operazioni I dati e e nodi vengono mappati nello stesso spazio degli indirizzi Viene assegnato un ID univoco ad ogni nodo e ad ogni dato Ogni nodo è responsabile di una porzione dello spazio degli indirizzi L’associazione dei dati ai nodi cambia continuamente a seguito di Join e Leave dei nodi Memorizzazione / Richiesta dei dati nella DHT La richiesta di un dato corrisponde alla richiesta del responsabile di quel dato Il responsabile di un determinato dato non si conosce a priori Si utilizza una tabella di routing per velocizzare la query
Gli indirizzi nelle Distributed Hash Tables Passo 1: Mapping Assumiamo che il numero di oggetti da memorizzare è molto più piccolo di 2m Si utilizza una funzione hash E.g., Hash(String) mod 2m: H(„my data“) 2313 Si associano porzioni dello spazio [0,2m-1] ai nodi H(Node Y)=3485 3485 - 610 1622 - 2010 611 - 709 2011 - 2206 2207- 2905 (3485 - 610) 2906 - 3484 1008 - 1621 Y X 2m-1 Di solito lo spazio degli indirizzi prende forma di un anello. Data item “D”: H(“D”)=3107 H(Node X)=2906
Associazione dello spazio ai nodi Ogni nodo è responsabile di una parte dello spazio degli indirizzi In alcuni casi si può introdurre ridondanza (overlapping of parts) Associazione nodo spazio è dinamica La rete reale (sottostante) e quella logica (overlay) non sono correlate Es. Chord, il nodo 3485 è responsabile per i dati nel range da 2907 a 3485 Logical view of the Distributed Hash Table Mapping on the real topology 2207 2906 3485 2011 1622 1008 709 611
Routing Passo 2: localizzare i dati (il routing è basato sui contenuti) Goal: localizzare i dati con un piccolo sforzo O(1) con una hash table centralizzata Ma: non è questo il nostro obiettivo (server!) Basso overhead con distributed hash tables O(log n): DHT passi per trovare un dato O(log n): informazioni per il routing memorizzate da ogni nodo (n = # nodes)
Initial node (arbitrary) Routing Routing di una coppia chiave/valore La lookup inizia da un nodo arbitrario Ogni nodo che viene contattato o è il responsabile oppure conosce un nodo che si trova + vicino al responsabile H(„my data“) = 3107 1622 1008 2011 Node 3485 manages keys 2907-3485, 709 2207 ? 611 2906 3485 Key = H(“my data”) Initial node (arbitrary) (3107, (ip, port)) Value = pointer to location of data
Routing ? Getting the content La coppia chiave valore è restituita la nodo che ha fatto partire la query Il nodo analizza la coppia chiave/valore ed è in grado di accedere ai dati nella loro attuale posizione (indirect storage) In case of indirect storage: After knowing the actual Location, data is requested H(„my data“) = 3107 Get_Data(ip, port) 1622 1008 2011 709 2207 ? 611 2906 3485 Node 3485 sends (3107, (ip/port)) to requester
Direct Storage Come sono memorizzati i contenuti nei nodi? Esempio: H(“my data”) = 3107 Direct storage Il contenuto è memorizzato direttamente nel nodo responsabile dell’ID 3107 utilizzato quando i dati hanno dimensioni piccole D 134.2.11.68 2207 2906 3485 2011 1622 1008 709 611 HSHA-1(„D“)=3107
Indirect Storage Indirect storage I nodi della DHT memorizzano coppie (chiave,valore) Chiave = Hash(„my data”) 2313 Valore è in questo caso l’indirizzo del nodo che dispone del dato richiesto (IP, Port) = (134.2.11.140, 4711) + flessibile, ma richiede un ulteriore passo per raggiungere i dati richiesti 2207 2906 3485 2011 1622 1008 709 611 HSHA-1(„D“)=3107 Item D: 134.2.11.68 D 134.2.11.68
Join L’operazione di Join richiede i seguenti passi Il nodo calcola il suo ID Il nuovo nodo accede alla DHT contattando un nodo già presente nella DHT Al nodo viene assegnato il suo spazio degli indirizzi Il nodo copia le coppie chiave/valore appartenenti al proprio spazio Il nodo costruisce la propria tabella di routing 1008 1622 2011 709 2207 611 2906 3485 ID: 3485 134.2.11.68
Node Failure / Departure Fallimento di un nodo Le coppie chiave/valore mantenute dal nodo sono perse (a meno che non ci sono repliche) Il routing continua a funzionare Leave L’intervallo delle chiavi gestito dal nodo che lascia la DHT viene assegnato a un altro nodo e con esso tutte le coppie chiave/valore ad esso associate
DHT: Interfaccia Interfaccia di una DHT Pubblicazione di un dato Publish(key,value) Richiesta di un dato (search for content) Get(key) Risposta value Put(Key,Value) Get(Key) Value Distributed Application Node 1 Node N Node 2 . . . . Node 3 Distributed Hash Table (CAN, Chord, Pastry, Tapestry, …)
DHT vs. DNS Domain Name System Distributed Hash Table Mapping: nomi simboliciIP address Utilizza una struttura gerarchica I nomi seguono delle regole particolari Distributed Hash Table Mapping: key value può esser utilizzato per un DNS E completamente decentralizzata No ci sono particolari regole da rispettare DHTs offrono un servizio + generico e non sono vincolate a un particolare tipo di applicazione „valore“ nella coppia (chiave, valore) può essere un indirizzo un documento o qualsiasi altro tipo di dato…
Summary & Conclusions Caratteristiche delle DHTs Utilizzano una struttura particolare che permette di reperire qualunque informazione in pochi passi Le chiavi sono distribuite in maniera equa fra i nodi: Non ci sono colli di bottiglia Sono scalabili Sono stabili anche in presenza di fallimenti Resistono ad attacchi tipo DoS Sono decentralizzate Sono semplici efficienti e facili da realizzare Supportano un ampio spettro di applicazioni
Capitolo 8: Chord: A Scalable Peer-to-Peer Lookup Protocol for Internet Applications Autori: I. Stoica, R. Morris, D. Liben-Nowell, D. R. Karger, M. F. Kaashoek, F. Dabek, H. Balakrishnan MIT and Berkley http://www.pdos.lcs.mit.edu/chord/
Chord: Obiettivi Load Balance Decentralization Scalability Availability Flexibility
Chord: Lookup Come trovare risorse in un sistema completamente decentralizzato? La lookup è semplicemente una operazione, a disposizione di tutti i peer di un sistema P2P, che data una chiave (una risorsa), restituisce il gestore/responsabile della risorsa. Possiamo vedere l’operazione lookup come una funzione (dinamica) che prende in input una chiave (un identificatore a 160 bit) e restituisce un indirizzo IP. Lookup(id)IP address
Chord Quale è il miglior modo per costruire le tabelle di routing? Come facciamo a mantenere sempre corrette le tabelle di routing in situazioni “molto” dinamiche? Come gestire l’ingresso (join) e l’uscita (leave) dei nodi? Quale è il miglior algoritimo di routing?
Chord: Consistent Hashing Fondamentalmente, l’architettura di Chord è basata su un ring di 2m identificatori [0, 2m-1] (di solito m = 160) Chord usa Consistent Hashing per assegnare identificatori sia ai nodi/peers sia alle risorse Consistent Hashing permette: bilanciamento del carico sui nodi (con n nodi e k risorse, ogni nodo gestisce circa (1+)k/n chiavi (risorse), dove =O(log n)) basso numero di operazioni di manutenzione a seguito di join/leave dei nodi (quando entra l’n+1th nodo nel sistema circa O(k/n) chiavi (risorse) devono cambiare posizione) Discuteremo in dettaglio Consistent Hashing nelle prossime lezioni
Chord: Overview La tabella di routing relativa alle risorse è distribuita su tutti i nodi attivi del sistema Per risolvere una lookup è necessario che i nodi si scambino informazioni Prestazioni: In una rete “stabile” di n nodi, ogni nodo mantiene informazioni relative a O(log n) vicini e risolve qualsiasi lookup con al più O(log n) messaggi Tuttavia anche se la rete non è “stabile” con poca informazione (1 solo link) il protocollo Chord garantisce la correttezza della lookup
Chord: Identificatori Lo spazio degli identificatori a m bit è utilizzato sia per le risorse che per i nodi identificatore di Chiave = SHA-1(Risorsa) identificatore di Nodo = SHA-1(indirizzo IP) chiave=“LetItBe” ID=60 SHA-1 IP=“198.10.10.1” ID=123 SHA-1
Chord: Identificatori Gli identificatori ottenuti utilizzando Consistent Hashing vengono mappati su un ring circolare modulo 2m 000000 m=6 111000 001000 110000 010000 101000 011000 100000
Chord Il responsabile di una risorsa x con ID k è il primo nodo che si incontra procedendo in senso orario a partire da k. m=6 nodi 1 risorse 8 56 10 54 14 51 48 21 42 38 24 38 30 32
Chord Esempio leave (nodo 14) 1 8 56 10 54 14 51 48 21 42 38 24 38 30 nodi 1 risorse 8 56 10 54 14 51 48 21 42 38 24 38 30 32
Chord Esempio join (nodo 26) 1 8 56 10 54 51 48 21 42 38 24 38 26 30 nodi 1 risorse 8 56 10 54 51 48 21 42 38 24 38 26 30 32
Chord: Lookup Ogni nodo ha informazioni su tutti gli altri Supponiamo che il nodo 8 è interessato alla chiave 54: poiché il nodo 8 conosce tutti i nodi, è in grado di sapere senza fare nessuna richiesta che la chiave 54 è gestita dal nodo 56 Richiede info globali Tabella di routing n Costo lookup O(1) msg Manutenzione: Praticamente ingestibile!!! m=6 nodi 1 risorse 8 56 10 54 51 48 21 42 38 24 38 26 30 32
Chord: Lookup(2) Ogni nodo conosce solo il proprio successore Supponiamo che il nodo 8 è interessato alla chiave 54: ogni nodo conosce solo il proprio successore e quindi la query attraversa l’anello in senso orario finché non raggiunge il predecessore della destinazione Richiede poche info: Tabella di routing 1 entry Costo lookup O(n) msg m=6 nodi 1 risorse 8 56 10 54 51 48 21 42 38 24 38 26 30 32
Simple Key location Il nodo n chiama lookup(id) Il nodo 8 chiama lookup(54)
Chord: Correttezza Routing Ogni nodo n di Chord mantiene log n successori del nodo u più il predecessore Questo insieme di nodi viene usato per dimostrare la correttezza del Routing nodi 1 risorse 8 56 10 54 51 21 38 24 38
Chord: Lookup(3) Ogni nodo conosce, al più, altri m nodi nel sistema (fingers) Mostreremo che w.h.p. il numero di finger è O(log n) La distanza fra i finger cresce esponenzialmente In particolare, il finger i del nodo u connette il nodo al responsabile (successor) della chiave u+2i-1 m=6 nodi 1 risorse 8 56 10 54 51 48 21 42 38 24 38 26 30 32
Chord: Ricapitolando Ogni nodo u di Chord mantiene la connessione con log n successori (successors) del nodo u più il predecessore Inoltre, ogni nodo conosce, al più, altri O(log n) w.h.p, nodi nel sistema (fingers) In totale ogni nodo mantiene log n +1 + O(log n)=O(log n) connessioni m=6 nodi 1 risorse 8 56 10 54 51 48 21 42 38 24 38 26 30 32
Tavola dei finger m=6 Successors Predecessor Nodo 1 indice Nodo 1 14 2 21 4 32 5 38 6 42 3 24 ID Resp. 8+1=9 14 8+2=11 8+8=16 21 8+16=24 24 8+32=40 42 8+4=12 Predecessor Nodo 1 m=6
successor(0)=0 1 14 successor(1)=1 15 1 successor(14)=15 2 successor(2)=3 14 10 2 13 3 12 4 5 11 6 10 successor(6)=6 successor(10)=13 6 7 9 8 successor(9)=9 9
Qualcuno vuol provare a descrivere la tabella di routing del nodo 9? 1 14 15 1 i succ node 1 2 3 5 6 4 9 2 14 10 i succ node 1 14 15 2 3 4 5 6 2 13 3 Qualcuno vuol provare a descrivere la tabella di routing del nodo 9? 12 4 i succ node 1 10 13 2 11 3 4 5 11 ? ? ? ? 6 10 ? ? ? ? 6 7 9 8 9
Il nodo n chiama lookup(id) Algoritmo Lookup Il nodo n chiama lookup(id)
14 15 1 2 14 i succ node 1 14 15 2 3 4 5 6 i succ node 1 2 3 5 6 4 9 13 3 12 4 i succ node 1 10 13 2 11 3 4 5 11 6 10 7 9 8
n’=qualunque nodo attivo Join e Stabilization Crea Anello Vuoto Join n=N26, n’=qualunque nodo attivo Stabilize n=N26 n=N21
Join e Stabilization Altre operazioni periodiche ma utilizzate con frequenza minore sono fix.finger e check.predecessor
Chord: Risultati Lemma Dato un qualunque intervallo di ampiezza 2m/n, il numero di ID di nodi atteso in questo intervallo è 1 e O(log n) w.h.p.
Chord: Risultati Teorema Il numero dei nodi che deve essere contattato per risolvere una lookup è O(log n) w.h.p., Dim Supponiamo che il nodo u deve risolvere una lookup per l’id k Siano p e s, rispettivamente, il predecessore e il successore dell’ID k Se up e us, u non è in grado di risolvere da solo la query p u k s
Chord: Risultati Teorema Il numero dei nodi che deve essere contattato per risolvere una lookup è O(log n) w.h.p. Dim … u contatta, quindi, il più vicino predecessore di k a lui noto (il più grande finger che non va oltre k). Sia i tale che p [u+2i-1, u+2i) Poiché tale intervallo contiene almeno un nodo (p) il nodo u contatterà l’i-esimo finger f. Ovviamente tale nodo, ha ID minore o uguale di p. Per definizione di finger la distanza fra u e f è almeno 2i-1 f p u id s
Chord: Risultati Teorema Il numero dei nodi che deve essere contattato per risolvere una lookup è O(log n) w.h.p. Dim … Per definizione di finger la distanza fra u e f è almeno 2i-1 Inoltre f e p sono entrambi nell’intervallo [u+2i-1, u+2i), quindi la loro distanza è al più 2i-1 In altre parole, f è più vicino a p che a u, e quindi ad ogni hop la distanza nel caso peggiore si dimezza f p u id s
Chord: Risultati Teorema Il numero dei nodi che deve essere contattato per risolvere una lookup è O(log n) w.h.p. Dim …. Ad ogni hop la distanza nel caso peggiore si dimezza La distanza maggiore fra due ID è 2m-1, poiché tale distanza ad ogni hop si dimezza, in m hop siamo in grado di eseguire qualunque lookup f p n id s
Chord: Risultati Teorema Il numero dei nodi che deve essere contattato per risolvere una lookup è O(log n) w.h.p.. Dim Sappiamo che ad ogni hop la distanza, in termini di id fra sorgente e destinazione si dimezza. Supponiamo di effettuare log n hops, dopo questi passi la distanza dalla destinazione si riduce ad al più 2m / 2 logn = 2m/n. Sappiamo dal lemma precedente che in un tale intervallo ci sono al più O(log n) nodi w.h.p. Quindi effettuando altri O(log n) passi (anche usando solo i successori) arriviamo alla destinazione. In totale log n + O(log n) = O(log n) passi.
La Lookup impiega O(log n) hop 5 10 110 20 19 99 32 Lookup(19) 80 60
Chord: Risultati Abbiamo detto che i nodi di Chord mantengono O(log n) informazioni relative ad altri nodi, d’altra parte abbiamo detto che un nodo può avere m fingers. In realtà, è possibile mostrare che non tutti gli m i finger sono nodi distinti. Quello che accade è che, w.h.p., i primi m-2logn finger cadono nell’intervallo che va dal nodo al suo successore. Infatti un lemma analogo a quello mostrato in precedenza permette di dimostrare che la distanza minima fra due nodi (w.h.p.) è almeno 2m/n2 Abbiamo detto che il finger i del nodo n cade nel successore dell’ID n+2i-1 Di conseguenza, per ogni i ≤ m - 2log n +1, il responsabile dell’ID u+2i-1 ≤ u+ 2m/n2 cade nel successore di u. In totale il numero dei nodi distinti che bisogna mantenere nella tabella di routing è m – (m - 2log n) = O(log n)
Grazie per l’attenzione 18/09/2018