5.4 CAN (Content Addressable Network) Arbeit: Ratnasamy u. a. (2001). Hashing und Abstände: • Wieder unabhängige Hashfunktionen für Knoten und Schlüssel. • Hashwerte (IDs) aus [0, 1]d . • Euklidischer Abstand, aber Wraparound“ an den ” Rändern → Abstand auf Torus-Oberfläche. Für Implementierung endliche Approximation, hier nicht. 46 J OIN am Beispiel (d = 2): 1 0 0 1 47 J OIN am Beispiel (d = 2): 1 1 0 0 1 47 J OIN am Beispiel (d = 2): 1 1 0 0 1 47 J OIN am Beispiel (d = 2): 1 1 0 0 2 1 47 J OIN am Beispiel (d = 2): 1 1 0 0 2 1 47 J OIN am Beispiel (d = 2): 1 3 2 1 0 0 1 47 J OIN am Beispiel (d = 2): 1 3 2 1 0 0 1 47 J OIN am Beispiel (d = 2): 1 3 2 1 0 0 4 1 47 Balance: Knoten ist für alle Schlüsseln in Hyperrechteck in [0, 1]d zuständig, genannt Zone. Gute Balance, ohne Beweis: Satz 1.8: Sei c > 0. Mit Wahrscheinlichkeit 1 − n−c ist jeder von n Knoten für höchstens O(log n · m/n) Schlüssel zuständig. (Durchschnittliche Rechteckgröße 1/n, Rechteck der Größe c ′ (log n)/n wird nur mit kleiner Wskt. weiter unterteilt.) Datenstruktur für Knoten: • Eigene ID und Zone. • IDs und Zonen der 2d Nachbarn. Insgesamt O(d). 48 L OOKUP : Suche nach einer beliebigen ID: • Starte mit bekanntem aktiven Knoten. • Finde Nachbarn, dessen ID geringsten Abstand zum Ziel hat (Greedy-Vorgehensweise). 49 Idee für Analyse: • Knoten-IDs von n Knoten gleichverteilt in [0, 1]d : Approximieren durch Gitter mit Abstand n−1/d zwischen benachbarten Gitterpunkten. • Durchschnittlicher Abstand zwischen zwei beliebigen Punkten auf dem Gitter mit Wraparound in jeder der d Dimensionen: 1 d · 1/4 · −1/d = (d/4)n1/d . n L OOKUP benötigt dann O dn1/d Botschaften. (Analyse nur mit Gleichverteilung? M. h. W.“-Aussage?) ” Für d = log n: L OOKUP mit O(log n) Botschaften. Dann aber auch Speicherplatz 2(log n) pro Knoten. 50 J OIN : • Generiere zufällige ID x ∈ [0, 1]d . • L OOKUP, um aktiven Knoten zu finden, dessen ID geringsten Abstand zu x hat. • Teile Zone des aktiven Knotens. • Korrektur der Nachbarschaften. Anzahl Botschaften: O dn1/d . 51 L EAVE : • Knoten überwachen ihre Nachbarn. • Falls einer verschwunden, übernimmt dessen Zone der aktive Knoten mit kleinster Zone. • Verschmilz Zonen, falls dies legale Zone ergibt. Ansonsten muss Knoten mehrere Zonen verwalten. Aufwand O(d) für das Verschmelzen. Problem: Fragmentierung des ID-Raumes. 52 Lösung: Defragmentierungsprozedur. Beseitigung von Extrazone nach L EAVE: • Finde irgendwelche benachbarte Hyperrechtecke, die zu größerem Hyperrechteck verschmolzen werden können (gibt es immer – Übungsaufgabe). • Verschmilz diese. Benutze freien Knoten, um Extrazone abzudecken. Kosten: Tiefe des Partitionsbaumes. Falls Zonen alle gleich groß ⇒ Baum balanciert und Tiefe O(log n). Für zufällige Verteilung bisher keine Analyse. 53 Kostenübersicht: Anzahl Schlüssel pro Knoten: Lokaler Platz für Routing-Infos: L OOKUP: J OIN: L EAVE: O(log n · k /n) O(d) O dn1/d Botschaften (?) O dn1/d Botschaften (?) ? Noch fehlende Analysedetails: • Hashfunktionen mit endlichem Wertebereich. • Obere Schranke für L OOKUP, die mit hoher Wskt. gilt. • Overhead für und Auswirkungen von Defragmentierung. 54 5.5 Kademlia (KAD) Arbeit: Maymounkov und Mazières (2002). Implementierung in verschiedenen aktuellen Clients für P2P-Netze, z. B. eMule (eDonkey), Azureus (BitTorrent). Ziel Verbesserung von Chord: • Finger-Routing-Tabellen starr, richtiger“ nächster ” Knoten bei Suche fest vorgeschrieben. Heuristiken zur Berücksichtigung von Antwortzeiten schwierig zu integrieren. • Asymmetrische Abstandsfunktion → Routing-Infos aus ankommenden Anfragen helfen nicht. Wichtigste neue Idee bei Kademlia: Symmetrische, XOR-basierte Abstandsfunktion. 55 Hashing und IDs: • Wie bei Chord: Knoten und Daten unabhängig auf Hashwerte, genannt IDs, abbilden. • IDs aus 0, . . . , 2m − 1 . • Original-Kademlia: Hashing mit SHA-1, m = 160. Abstände: Für zwei IDs x, y ∈ 0, . . . , 2m − 1 : d(x, y ) := |x ⊕ y |2 , wobei |z|2 Wert von Bitvektor z als Binärdarstellung. • Dies ist tatsächlich Metrik, insbesondere symmetrisch. • Für jedes x ∈ {0, 1}m und d ∈ 0, . . . , 2m − 1 genau ein y ∈ {0, 1}m mit d(x, y ) = d. 56 L OOKUP intuitiv: Von 1101 nach 0011: Abstand (1110)2 = 14. 0 0 0 1 1 1 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 In jedem Schritt: Finde nächsten Zwischenknoten in Teilbaum, in dem vorderstes falsches Bit geflippt. → Abstandshalbierung, O(log n) Suchzeit. 57 Datenstruktur für Knoten: Kontakt: Tripel (IP-Adresse, UDP-Port, ID). k -Buckets: Für i = 0, . . . , m − 1: Queue mit bis zu k Kontakten im Abstand [2i , 2i+1 , sortiert nach Zeit seit letztem Zugriff (frischeste am Ende). • Original-Kademlia: k = 20. So wählen, dass Ausfall aller k Kontakte eines Buckets innerhalb einer Stunde hinreichend unwahrscheinlich. • Typischerweise Buckets mit kleinem Index leer. Ähnlich zu Chord, aber hier mehrere Kontakte für jede Abstandsklasse → Auswahlmöglichkeiten. 58 Updates der Kontakte: Für jeden Konkakt, mit dem kommuniziert wurde: Ans Ende des zugehörigen Buckets verschieben (Kontakt vorhanden) bzw. dort einfügen (neuer Kontakt). Falls bereits k Einträge und neuer Kontakt: • Teste, ob Knoten zu ältestem Kontakt im Bucket antwortet. • Falls ja, dann neuen Kontakt verwerfen, sonst alten. • Übernommenen Kontakt ans Ende der Queue. Bevorzuge alte Kontakte, da für diese statistisch höhere Wskt., dass sie weiter aktiv bleiben. Im Folgenden: Kontakt → Knoten“. ” 59 Bemerkung: In der Originalarbeit alternative Speicherung der k -Buckets in binärem Baum: • Zu Anfang Baumknoten für [0, 2m . • Falls Bucket voll und neuer Knoten in Teilintervall zu betrachtetem Knoten: Splitte Intervall und erzeuge neuen Baumknoten. • Ansonsten: Neuen Knoten wegwerfen. 60 Beispiel: 0 1 0∗∗ 0 1 0 100 1 11∗ 101 Damit nur O(log n) Platz pro Netzknoten (ohne Beweis). Vgl. Chord: Dort ähnlicher Trick und Beweis, dass jeder Knoten nur O(log n) verschiedene Finger hat. 61 Operationen: Elementare Operationen (greifen nur auf lokale Datenstruktur eines Knotens zu): • F IND C LOSEST N ODES (v , ID): Liefert k Knoten aus Datenstruktur des Knotes v , die am nächsten zu ID. • S TORE (v , ID, (Schlüssel, Wert)): Speichert (Schlüssel, Wert) in Knoten v . 62 L OOKUP : I TERATIVE F IND C LOSEST N ODES (v, ID): Queue R mit maximal k bereits erreichten Knoten, sortiert nach Abstand zu ID. R := F IND C LOSEST N ODES (v , ID). repeat • Wähle a bisher nicht kontaktierte Knoten aus R und stelle parallel Anfragen mit F IND C LOSEST N ODES. • Sortiere Ergebnisse erfolgreicher Anfragen in R ein (verdränge ggf. Einträge mit größerem Abstand). Entferne Knoten, die nicht geantwortet haben. • Falls keine Knoten mit kleinerem Abstand gefunden, Anfragen an alle noch nicht kontaktierten Knoten R. until R unverändert; return Liste der Knoten in R. 63 Bemerkungen: • Original-Kademlia: a = 3. • Parallele Aufrufe verschränkt mit Such-Prozedur, neue Aufrufe nach Verzögerung starten. Ergebnisse trudeln nach und nach ein. • Sollte mindestens einen Aufruf für Knoten in R mit minimalem Abstand durchführen (→ später). • Spezielle Prozedur für Suche nach Daten-ID: Kann stoppen, sobald Datum gefunden. Speichern von Daten: I NTERATIVE S TORE (v, ID, (Schlüssel, Wert)): Findet k Knoten, die zu gegebener ID geringsten Abstand haben (mit I NTERATIVE F IND C LOSEST N ODES) und speichert Schlüssel-Wert-Paar darin (mit S TORE). 64 Redundante Datenspeicherung: Zur Absicherung gegenüber Ausfällen jedes Schlüssel-Wert-Paar k -fach gespeichert. • Bei neuer Speicherung mit Prozedur I NTERATIVE S TORE I N C LOSEST N ODES erfüllt. • Jeder Knoten veröffentlicht sein ggf. vorhandenes Schlüssel-Wert-Paar nach jeder Stunde neu: Sende dies dazu an k nächste Nachbarn. • Knoten, der Paar neu erzeugt hat, muss dieses alle 24 Stunden neu veröffentlichen. Daten, die nicht aufgefrischt werden, verfallen nach einiger Zeit (spätestens 24 Stunden). 65 Satz 1.9: Für jeden Knoten v gelte, dass sein i-tes Bucket nicht leer ist, sobald ein Knoten im Netz mit Abstand in [2i , 2i+1 von v existiert. Außerdem wähle I TERATIVE F IND C LOSEST N ODES immer mindestens einen Knoten mit minimalem Abstand unter den bereits gefundenen. Dann kontaktiert für c > 0 die Prozedur mit Wskt. mindestens 1 − n−c höchstens O(log n) Knoten. 66 Beweis: Sei t die gesuchte Ziel-ID. Betrachte Iteration, bei der bereits Knoten mit ID s erreicht. Es ist d(s, t) ∈ [2i , 2i+1 für irgendein i ∈ {0, . . . , m − 1}. Die Prozedur fügt i-tes Bucket von s zur Queue hinzu und wählt nach Voraussetzung Knoten mit ID s ′ aus diesem für nächste Runde. Falls gewünschtes Bucket leer, dann fertig. Beobachtung: IDs in i-tem Bucket stimmen in höchstwertigsten m − i Bits überein. ⇒ d(s ′ , t) ≤ 2i − 1. Darstellung von d(s ′ , t) um ein Bit kürzer als die von d(s, t). Nach log n + 1 Schritten hat Abstand Darstellung mit höchstens m − log n − 1 Bits, d. h. Abstand höchstens 2m−log n − 1 < 2m /n. 67 Sei s Knoten nach erster Phase mit Abstand höchstens 2m /n vom Ziel. Analog zu Argument bei Chord: M. h. W. O(log n) Knoten mit Abstand höchstens 2m /n von s. In jedem weiteren Schritt echte Abstandsverringerung oder gewünschtes Bucket leer (dann fertig). Also insgesamt O(log n) Schritte. 68 Wie Voraussetzungen erfüllen? • Kompletter Ausfall eines ganzen Buckets unwahrscheinlich. • Buckets werden stündlich durch Refresh aktualisiert → Knoten-Zugänge und -abgänge richtig reflektiert. B UCKET R EFRESH : Falls für ein Bucket keine Suchanfrage nach ID in dessen Bereich innerhalb einer Stunde: • Wähle ID zufällig im Bereich des Buckets. • Führe I TERATIVE F IND C LOSEST N ODES für diese ID durch. 69 J OIN : Sei u aktiver Knoten, v neuer Knoten. IDs Xu , Xv . • Trage Xu in passendes Bucket von neuem Knoten v ein. • Rufe I TERATIVE F IND C LOSETS N ODES (u, Xv ) auf. Liefert k nächste Nachbarn von v . • Sei i kleinster Index eines nicht leeren Buckets. Führe BUCKET R EFRESH für alle Buckets mit Index ≥ i durch. • Übertragung der Schlüssel-Wert-Paare: Entweder auf Wiederveröffentlichung warten oder k nächste Nachbarn aktiv danach befragen. 70 Kosten für J OIN bisher scheinbar nirgendwo genau analysiert. Ideen: • Balance genauso wie bei Chord, direkte Verschiebung von Daten daher effizient machbar. • Maximal O(log n) Buckets besetzt, jeweils O(log n) Botschaften pro Refresh: O log2 n Botschaften für Intialisierung der neuen Buckettabelle. L EAVE : Nichts tun. Bereits erledigt durch Daten-Replikation und Bucket-Refreshes (und flexibles Routing, das Umwege um evtl. Lücken findet). 71 Kostenübersicht: Anzahl Schlüssel pro Knoten: Lokaler Platz für Routing-Infos: L OOKUP: J OIN: L EAVE: O(log n · k /n) O(log n) O(log n) Botschaften O log2 n Botschaften? ? (siehe unten) Noch fehlende Analysedetails: • Kosten für J OIN. • Overhead durch Refresh und Wiederveröffentlichung. → Kosten für L EAVE. • Beweis für Fehlerschranke, die Refresh und Wiederveröffentlichung berücksichtigt. Algorithmenbeschreibung in der Originalarbeit ungenau, mehr Details in der Spezifikation des XLattice-Projekts: xlattice.sourceforge.net. 72 Fazit P2P-Netze: Noch zu lösende Probleme (aktuelle Forschung): • Teilstring-Suchanfragen: DHTs: Exakte Suche nach einzelnem Schlüssel. Für Tauschbörsen-Anwendung nicht typisch. ( Stirb langsam“, Stirb langsam 4.0“, Die hard“, ” ” ” Live Free or Die Hard“ sollten nach Möglichkeit alle ” ähnlich interessante Ergebnisse liefern.) • Sicherheit gegen gezielte Manipulation des Netzes. • Anonymität. Und: Theoretische Analysen bekannter Verfahren. Kosten für Netzreparatur abhängig von Zugangs-/Abgangsrate, Modelle für P2P-Netze usw. 73