Pastry - Tapestry Raimar Wagner November 2006 1 Einleitung Das Schlagwort Peer-to-Peer ist in den heutigen Medien zu einem Synonym für Filesharing geworden, es wird jedoch meist nur die juristische und gesellschaftliche Relevanz des Themas aufgegriffen. Deren Scheitern oder Erfolg lässt sich meist in direkten Zusammenhang mit den technischen Grundlagen von Peer-to-Peer Systemen bringen, da sich ihr Design erheblich auf die spätere Leistungsfähigkeit und Zuverlässigkeit auswirkt. Auch die Wissenschaft beschäftigt sich seit geraumer Zeit mit den technischen Problemen die ein Peer-to-Peer System mit sich bringt. Die Ziele eines Peer-to-Peer Systems nach [Jan04] sind vereinfacht: • Sichere Ortung: Da es per Definition keinen Server gibt, muss auf anderem Weg gewährleistet werden dass, falls ein Objekt im Netzwerk vorhanden ist, es auch gefunden wird. • kürzeste Routingstrecke: Das Routing zu einem Zielknoten sollte auf dem schnellst möglichen Weg im Sinne der Nachbarschaftsmetrik1 der darüberliegenden Schicht erfolgen. • Lastausgleich: Kein Knoten im Netzwerk sollte übermäßig belastet werden. • Skalierbarkeit: Das System muss auf ankommende und gehende Knoten gut reagieren können. • Gleichberechtigung: Kein Knoten darf besondere wichtige Kompetenzen allein besitzen, da sonst ein Single Point of Failure2 möglich wird. Im Folgenden will ich zwei Systeme vorstellen, die diese Eigenschaften erfüllen. Damit sind Pastry und Tapesty echte Peer-to-Peer Systeme, im Gegensatz zu hybriden Systemen wie Napster. Auf Ähnlichkeiten und den Vergleich der beiden Systeme will ich am Ende der Ausarbeitung eingehen. 2 Pastry Pastry wurde 2001 von Antony Rowstron (Microsoft Research, Cambridge, GB) und Peter Druschel (Rice University, Houston, Texas) entwickelt und veröffentlicht [RoDr01]. In Pastry wird jedem Client eine eindeutige 128-bit lange Identifikationsnummer (NodeID) zugewiesen. Dies geschieht entweder durch bildes eines Hashwerts der IP-Adresse oder durch Zufallsgeneratoren. Im Weiteren müssen wir 2 Metriken unterscheiden: 1 2 In unserem Fall meist die Messung der Pingzeit oder die Anzahl der Routing Hops. Ein Knoten mit zuvielen Kompetenzen kann die Integrität des Netzes beschädigen, falls er ausfällt. 1. Nachbarschaftsmetrik : Eine Nachbarschaftsmetrik distP (x, y) gibt den Abstand zweier Knoten x und y auf Basis von Pingzeiten oder Hops an. 2. numerische Metrik : Eine numerische Metrik distN (x, y) gibt den Abstand zweier Knoten in Form von der numerischen Nähe von x und y wider. In der Praxis bedeutet das dass die Präfixe von N odeID(x) und N odeID(y) verglichen werden und je größer die Übereinstimmung ist, desto näher sind sich die Knoten nach der numerischen Metrik. Durch die zufällige Verteilung der NodeIDs wird gewährleistet, dass numerisch nahe Knoten nach der Nachbarschaftsmetrik gut gestreut sind. Eine Verklumpung“ hätte erhebliche Routingnachteile, da ” bei einem Ausfall von z.B. einem IP Segment möglicherweise einige Knoten komplett vom Restnetz abgeschnitten werden könnten. 2.1 Der Pastry Node Ein Pastry Node besteht aus drei Tabellen: • Die Routing Table: Die für das Routing zuständige Tabelle • Das Neighborhood Set: Hier ist Nähe im Sinne der Nachbarschaftsmetrik gemeint. • Die Leaf Set: Hier ist Nähe im Sinne der numerischen Metrik gemeint. Mit der Routing Table wird später, wie der Name schon sagt, das Routing ausgeführt. Basierend auf einem Konfigurationsparameter b besteht die Routing Table aus dlog2b N e Zeilen mit je 2b −1 Einträgen. Die Zahl N entspricht im weiteren der Anzahl der möglichen Nodes im NodeID Space. Die genaue Herkunft dieser Zahlen wird bei praktischer Betrachtung klar. Des weiteren ist die NodeID dargestellt als Sequenz von Ziffern der Basis 2b . In unserem Fall wählen wir b = 2 und einen NodeID-Bereich von 0 bis 2128 − 1 an, dann hat unsere Routing Table acht Zeilen zu je drei Einträgen. In der nullten3 Zeile der Routing Table stehen IPAdressen von NodeIDs, deren NodeID keinen Präfix mit der NodeID des Knotens selbst gemeinsam hat. In der ersten Zeile die IP-Adressen deren NodeID Präfix eine Ziffer mit Abbildung 1: PastryNode 10233102 der NodeID des Knoten gemeinsam hat und so weiter. Allgemein gesagt: Die Knoten in der Zeile n teilen mit dem nach [RoDr01] Knoten selbst die ersten n Ziffern im Präfix. In jeder Zeile muss auch gewährleistet sein, dass das n + 1te Zeichen nicht doppelt vorkommt. Das Neighborhood Set enthält NodeIDs und die dazugehörigen IP-Adressen von nahen Knoten im Sinne der Nachbarschaftsmetrik. Diese Tabelle ist am Routingvorgang nicht beteiligt, aber wichtig für das Erhalten der Lokalitätseigenschaft (z.B.: beim Einfügen). Das Leaf Set enthält die numerisch nahen Knoten, die für das Routing wichtig sind. Es werden zu gleichen Teilen Knoten mit größerer und kleinerer NodeID gespeichert. Die Bezugsgröße ist hier die 3 Man zählt die Zeilen ab 0, dies ist reine Definitionssache. eigene NodeID. Die Anzahl der Einträge im Leaf Set und im Neighborhood Set sind Definitionsssache und werden meist 2b oder 2b+1 gewählt. 2.2 Routing Das Routing beschreibt den Vorgang wie ein Knoten auf das Ankommen einer Nachricht, die nicht für ihn bestimmt ist, reagiert. Eine Nachricht ist in Pastry immer mit einer NodeID für den Empfänger (auch MessageID genannt) gekennzeichnet. Für die Weiterleitung der Nachricht werden zwei der drei vorhanden Tabellen die im Knoten vorgehalten werden gebraucht, nämlich die Routing Table und das Leaf Set. Der Algorithmus sieht wir folgt aus: 1. Vergleiche die NachrichtenID zuerst mit allen NodeIDs im Leaf Set, falls die MessageID der Nachricht in dem vom Leaf Set abgedeckten Bereich fällt wird die Nachricht sofort zugestellt. 2. Ermittele Präfixübereinstimmung i mit eigener NodeID. (z.B.: wäre bei NodeId 10222102 und NachrichtenID 10232120 die Präfixübereinstimmung i = 3) 3. Gehe nun in die i-te Zeile der Routing Table und wähle diejenige NodeID aus, deren i + 1-tes Zeichen mit dem i + 1-ten Zeichen der MessageID übereinstimmt. Leite nun die Nachricht an diesen Knoten weiter. 4. Falls kein so ein Knoten gefunden wird, schicke die Nachricht an den numerisch nächsten Knoten aus Leaf Set ∪ Routing Table ∪ Neighborhood Set. Nach [RoDr01] liegt die Wahrscheinlichkeit pro Nachricht dass dieser Fall auftritt zwischen 0.02 und 0.006. 2.2.1 Performance Da im ersten Fall der Knoten sofort gefunden ist und im zweiten Fall die Anzahl von Knoten mit längerem Präfix immer um 2b sinkt, hat dieser Algorithmus eine Laufzeit von dlog2b N e. Der dritte Fall kann vernachlässigt werden, da er nur selten auftritt (siehe oben). 2.3 Einfügen eines Knoten Zuerst braucht der neu hinzukommende Knoten φ die NodeID eines vorhanden Knoten ϕ, der nach der Nachbarschaftsmetrik nah sein sollte. Warum dies der Fall sein sollte wird später klar. Diesem Startknoten (hier ϕ) sendet φ eine spezielle Join-Message deren Aufgabe es ist die 3 Tabellen von φ zu füllen. Die Beitrittsnachricht hat als Zieladresse die NodeID von φ selbst. Dies garantiert dass die Nachricht die Knoten erreicht, die dem neuen Knoten nach der Umgebungsmetrik nahe sind. Das Leaf Set kann der neue Knoten einfach von dem letzten Empfänger der Beitrittsnachricht kopieren, da er φ numerisch am nächsten ist. Das Neighborhood Set lässt sich ebenfalls einfach füllen, da angenommen wird dass ϕ topologisch nah zu φ ist. Falls das nicht gegeben sein sollte, hat dies nur zur Folge dass das Netzwerk langsamer wird. Die Join-Message versucht nun die eigene NodeID zu finden. Auf dem Weg verlängert sich das gemeinsame Präfix immer weiter um eins und der Knoten kann so aus den Routing Tables der anderen Knoten die Einträge übernehmen. Anschaulich gesagt, wenn der Knoten die ersten k Stellen mit dem neu hinzugekommenen Knoten gemeinsam hat, kann dieser die ersten k Zeilen seiner Routing Table übernehmen. 2.4 Löschen eines Knotens In einem dezentral organisierten Netz muss gewährleistet werden, dass Knoten ordnungsgemäß aus dem System gelöscht werden. So ist gewährleistet dass keine Nachrichten ins Leere laufen. Hier kommt nun das Neighborhood Set zum tragen, denn hier sind alle topologisch nahen Knoten verzeichnet. Jeder Knoten sendet in periodschen Abständen eine Art Ping“ an die Knoten im Neighbor” hood Set, denn hier ist die Laufzeit eines Lebenssignals“ am kürzesten. Falls nun ein Knoten nicht ” antwortet, wird eine Nachricht an die NodeID des betreffenden Knoten geschickt. Diese erhält nun ein Knoten in dessen Leaf Set der tote Knoten steht. Dieser wird gelöscht und alle anderen Knoten im Leaf Set erhalten eine Nachricht diesen Knoten zu löschen. Falls es sich nun bei einem Routingvorgang rausstellt, dass ein Eintrag der Routing Table defekt ist, muss dieser repariert werden. Dazu werden nach und nach die anderen Knoten in der selben Zeile der Routing Table nach ihrem Eintrag an dieser Stelle befragt. Falls ein Eintrag passt wird dieser übernommen. Falls nun in der gesamten Zeile kein Knoten diesen Eintrag vorhält wird in der nächsten Zeile inspiziert und so weiter. 2.5 Objektmanagement Um das Management von Objekten vergleichen zu können wird in [Her02] beschrieben wie Past, eine Anwendung des Pastry Algorithmus, Objekte verwaltet. In Past wird einem Objekt ein Hashwert zugeordnet und dann das Objekt an den, dem Hashwert numerisch nächsten Knoten geschickt. Von dort aus wird die Datei noch an k Nachbarknoten verteilt. So ist statistisch eine gute Verteilung des Objekts gewährleistet. 2.6 Experimentelles In [RoDr01] werden noch ausführliche Experimente mit Pastry dokumentiert. Die wichtigsten Punkte sind: • Skalierung: Die Anzahl der Hops zur Anzahl der Knoten verhält sich logarithmisch. Das kann als optimal bezeichnet werden. Die meisten Knoten konnten in einem großen Netz über nur 4 Hops erreicht werden, kein Routingvorgang hat mehr als 5 Hops gebraucht. • Distanz: Die Distanz zweier Knoten ist um nur 30-40% größer als bei direktem Routing. Sie nimmt auch bei steigender Knotenmenge nicht zu. 3 Tapestry Tapestry wurde 2001 von Ben Y.Zhao, John D. Kubiatowicz und Anthony D. Joseph von der University of California in Berkely (CA) entwickelt und veröffentlicht [ZhKuJo01]. Dieses System besteht ebenfalls aus Knoten (englisch Nodes), die ebenfalls durch NodeIDs gekennzeichnet sind. In Tapestry sind diese NodeIDs 40-stellige Hexadezimalzahlen zur Basis 16. Die NodeIDs werden ebenfalls zufällig mittels Hashing vergeben. 3.1 Der Tapestry Node und das Objekt Der Tapestry Knoten hat im Gegensatz zu einem Pastry Knoten nur eine Tabelle: die sogenannte Neighborhood Map. Dort sind, nach Leveln geordnet, die Nachbarknoten gespeichert. Die Level geben an, ab der wievielten Stelle sich die NodeID von der eigenen NodeId unterscheidet. Bei Level 4 ist die 4. Stelle eine andere (Siehe Abbildung 2). Der numerisch nächste Knoten in einem Level wird primärer Knoten genannt. Diese werden aktiv beim Routing benutzt, die restlichen Einträge dienen nur der Ausfallsicherheit. Jeder Knoten hält auch noch Referenzen, sogenannte Vorgänger-Zeiger (im englischen backpointer) auf Knoten die auf ihn verlinken. Diese Verweise sind aber nur für das Einfügen von Knoten relevant. Bei Tapestry gibt es, im Gegensatz zu Pastry, eine ausgefeilte Objekt-Behandlung. Objekte sind Dateien oder Pakete mit Inhalt die ausgetauscht werden sollen. Jeder Knoten der ein Objekt vorhält nennt man Speicher-Server (im englischen Storage-Server). Jedes Objekt hat eine Menge von sogenannten Wurzel-Knoten (im englischen Root-Peers) deren Aufgabe die Verwaltung der Links der Speicher-Server ist. Im System existiert eine Funktion M apRoots(ϑ) die für jeden Knoten ϑ die zugehörigen Wurzel-Knoten zurückgibt. Die genaue Funktionsweise dieses Algorithmus wird im Abschnitt Surrogate-Routing beschrieben. 3.2 Routing Abbildung 2: Tapestry Knoten 4231 frei nach [Roe05] Das übermitteln von Nachrichten in Tapestry geht ähnlich von statten wie bei Pastry. Wenn eine Nachricht an einen Knoten ζ weitergeleitet werden soll, wird in der Neighborhood Map der Knoten gesucht dessen NodeID in den meisten Stellen mit der NodeID von ζ übereinstimmt. So kommt die Nachricht dem Knoten ζ in jeden Schritt um ein Stelle in der NodeID näher. 3.3 3.3.1 Surrogate Routing Objektbereistellung Falls ein Knoten nun ein Objekt in das Netzwerk einbringt besteht die erste Aufgabe darin bei dem Wurzel-Knoten bekannt zu machen dass er nun als Speicher-Server fungiert. Dazu werden als erstes die eindeutigen Wurzel-Knoten mittels M apRoots(·) bestimmt. Nun wird an die Wurzel-Knoten eine Nachricht geschickt, dass ein neuer Speicher-Server vorhanden ist. Alle Knoten, die die Nachricht auf dem Weg zum Wurzel-Knoten passiert, speichern nun auch ein Tupel aus Referenz auf den SpeicherServer und der ObjektID. Die Referenzen auf Speicher-Server verfallen nach einiger Zeit, sodass der Speicher-Server diese Prozedur in regelmäßigen Abständen wiederholen muss. 3.3.2 Objektsuche Falls nun ein Knoten ein Objekt sucht bestimmt er als erstes die dazugehörigen Wurzelknoten. Nun schickt er eine Nachricht an die Wurzel-Knoten in denen er die Adressen der Speicher-Server anfordert. Da die Nachricht aber über mehrere andere Knoten geht ist sehr wahrscheinlich dass einer der Knoten zwischen dem Wurzel-Knoten und dem Anfordernden Knoten schon eine Referenz auf den Speicher-Server vorliegen hat. Das kommt daher dass ja beim Bekanntmachen des Speicher-Servers mit dem Wurzel-Knoten alle Knoten die auf dem Weg zwischen den beiden liegen auch eine Referenz auf den Speicher-Server speichern. In so einem Fall wird die Nachricht sofort an den Speicher-Server weitergeleitet. 3.3.3 Surrogate Routing Das Tapestry System kann nur funktionieren wenn M apRoots(·) immer die selben Wurzel-Knoten zurückliefert. Hier kommt das sogenannte Surrogate Routing (zu deutsch Stellvertreter-Routing“) ” zum tragen. Die NodeIDs der Wurzel-Knoten werden durch verschiedene Hashfunktionen oder Varianten bestimmt. Nun kann aber vorkommen dass die so errechnete NodeID des Wurzel-Knotens nicht existiert. Beim Routing auf solche nicht existenten Wurzel-Knoten können die Nachrichten auf Löcher“ in den Neighborhood Maps stoßen. In so einem Fall wird das erste Zeichen das nicht gerou” tet werden kann um eins erhöht und dann erneut ab diesem Knoten das Routing versucht. Dies wird solang wiederholt bis kein Knoten mehr in dem momentanen Level oder den darüberligenden Leveln zu finden ist. So ist gesichert dass M apRoots(·) immer die selben Wurzel-Knoten zurückgibt. 3.4 Einfügen von Knoten Falls ein neuer Knoten α das Tapestry System betritt braucht er einen Zugangsknoten β, über den er Zugang zum Netz bekommt. α sucht nun im Netz nach der eigenen NodeID und erreicht so seinen Stellvertreter-Knoten. Auf dem Weg von α zu seinem Stellvertreter-Knoten bekommt α alle Neighborhood Maps aller Knoten dazwischen. Aus diesen Knoten extrahiert der Algorithmus die besten Knoten für die eigene Neighborhood Map unter Berücksichtigung der toplogischen Parametern. 3.4.1 Bekanntmachen eine neuen Knoten Da einige Knoten möglicherweise auch Löcher in ihrer Neighborhood Map haben können, in die unser α passen könnte, ist es nun die Aufgabe von α seine Existenz anderen Knoten mitzuteilen. Wie wir noch aus dem Abschnitt Surrogate Routing wissen, wurden dort für nicht existierende Knoten Nachfolger gesucht. Falls nun nach unserem neuen Knoten α gesucht wurde finden wir die Knoten mit einem Loch in der Neighborhood Map indem wir die Vorgänger-Zeiger des Knoten Nachfolgers zurücklaufen und dort den neuen Knoten α eintragen. Da laut experimentellen Messung das Surrogate Routing in der Mehrzahl der Fällen [ZhKuJo01] nach 2 Hops beendet ist, genügt es in den allermeisten Fällen die Vorgänger-Zeiger 3 Schritte zurückzuverfolgen. Des weiteren wird eine Nachricht an alle primären und sekundären Nachbarn geschickt und diesen die Gelegenheit gegeben einen vorhanden Knoten in der Neighborhood Map durch α zu ersetzen. Hier ist primär die topologische Entfernung von Bedeutung. 3.5 Löschen von Knoten Das Löschen von Knoten ist dank der Vorgänger-Zeiger trivial, da so alle auf einen Knoten zeigenden Knoten informiert werden können. 4 Vergleich Wenn man Pastry und Tapestry vergleicht fällt einem Zuerst auf, dass der eigentlich Aufwand für verschiedene Operationen auf dem Papier identisch ist [Jan04]: System Pastry Tapestry Einfüge-Kosten O(log 2 (N )) O(log 2 (N )) Routing-Hops O(log(N )) O(log(N )) Balance ja ja Abbildung 3: Nodesuche nach Node 022 Des weiteren fällt sofort ins Auge dass die Routingmechanismen sich vom Prinzip her sehr ähnlich sind, da sie beide auf dem selben Prinzip, dem sogenannten Plax” ton Routing“ 4 basieren. Doch wenn man sich die Systeme genauer anschaut sind einige Unterschiede zu erkennen. Es ist zu erkennen dass Pastry mehr auf heuristische Methoden setzt deren Funktion aber dennoch durch Experimente gut nachgewiesen ist. Tapestry dagegen ist wesentlich analytischer aufgebaut, aber damit auch komplizierter [Sch06]. Es fällt besonders auf dass Pastry selbst kein wirkliches Objekt-Management besitzt. Dies wird vollständig der Implementierung überlassen (z.B.: Past). Insbesondere die Past-Implementierung achtet viel weniger auf die Organisation von Objekten als es Tapestry tut. In Pastry sind daher Duplikate von Dateien möglich ohne dass eine Kontrollinstanz davon etwas mitbekommt. Das Verteilen basiert darauf, dass ein Objekt in einem Bereich des Netzes gestreut wird in dem später andere Knoten suchen werden. Solche eher unsicheren Algorithmen bezeichnet man als heuristisch. Tapestry dagegen hat ein ausgeklügeltes System aus verschiedenen Knotentypen die es ermöglicht die Verteilung von Dateien besser zu kontrollieren und bei massiven Anfragen auf einzelne Dateien flexibler reagieren kann. Bei Past wird in dem Fall eine große Nachrichtenkaskade auf ein bestimmtes Knotengebiet zukommen, während bei Tapestry diese Kaskade durch Referenzen in anderen Knoten abgeschwächt wird. Auch haben Experimente gezeigt [Roe05] dass es kein perfektes Peer-to-Peer-System gibt. Keines der Systeme kann bei minimaler Anzahl an Hops mit minimaler Bandbreite auskommen, auch nicht Konkurrenten wie Chord oder Can. Es ist immer ein Trade-Off zwischen Leistung und Kosten. 5 Fazit Die in der Einleitung geforderten Eigenschaften erfüllen beide Systeme mit Bravour. Diese beiden Systeme sind eine neue Generation von Peer-to-Peer Systemen und logische Weiterentwicklungen von System der alten Generation wie Napster. Der Verzicht auf die Hybridität bringt ernorme Ausfallsicher, geschickte Routing-Algorithmen erzeugen angemessende Geschwindigkeit und die Erweiterbarkeit ist durch variable Strukturen gesichert. Inbesonders die Beachtung der zugrundeliegenden Netzwerkstruktur macht beide Algorithmen sehr schnell. Tapestry hebt sich durch sein Objektmanagement-System zusätzlich in den Vordergrund, ist aber im Vergleich zu Pastry wesentlich komplizierter. Dennoch sind einigene Probleme noch ungelöst; so ist bei beiden Systemen kein Ansatz zum erkennen und behandeln von potentiell systemschädigenden Knoten vorhanden. Des Weiteren kann beim Aufall einer großen Anzahl von Knoten es immer noch zu Instabilitäten kommen. Neue Tendenzen zeigen dass Peer-to-Peer-Systeme immer mehr Einfluß im Internet bekommen wer4 Dieser Algorithmus basiert darauf, dass das Routing sich an den aufsteigen Präfixen der NodeIDs orientiert. Die Laufzeit von O(log(N )) wird an der Abbildung 3 deutlich. Das Ganze ähnelt der Suche in einem binären Suchbaum. den, und das nicht nur im illegalen Bereich. Inbesondere Linux Distributionen werden heute schon über Peer-to-Peer-Systeme angeboten um die Server zu entlasten. Literatur [ZhKuJo01] Ben Y.Zhao, John D. Kubiatowicz, Anthony D. Joseph, Tapestry: An Infrastructure for Fault-tolerant Wide-area Location and Routing, University of California, Berkely, [RoDr01] Antony Rowstron, Peter Druschel, Pastry: Scalable, decentralized object location and routing for large-scale peer-to-peer systems, Microsoft Resarch (Cambridge, UK), Rice University (TX), 2001 [Jan04] Peter Janacik, Theorie von Peer-to-Peer-Netzwerken: Tapesty, Seminararbeit, Universität Paderborn, 2004 http://wwwcs.uni-paderborn.de/cs/ag-madh/vorl/Perlen/ PJANACIK.pdf [Sch06] Christian Schindelhauer, Skript zur Vorlesung Peer-to-Peer-Netzwerke SS06, Universität Freiburg, 2006 http://cone.informatik.uni-freiburg.de/teaching/ vorlesung/peer-to-peer-s06/skript/p2pb00k.pdf [Her02] Andre Herms, Seminararbeit - Pastry, Universität Magdeburg, 2002 http://ivs.cs. uni-magdeburg.de/bs/lehre/wise0102/sem_bs/t13/pastry.pdf [Roe05] Holger Röder, Peer-to-Peer Internet Systeme, Hauptseminar Autonomic Computing, Universität Stuttgart, 2005 http://www.ipvs.uni-stuttgart.de/abteilungen/ vs/lehre/lehrveranstaltungen/hauptseminare/WS0405/Autonomic_ Computing_termine/dateien/Roeder_P2P_2.pdf