 Hallo und herzlich willkommen zu meinem Vortrag über RobustIRC, der Untertitel ist IRC ohne Netzsplits. Mein Name ist Michael Stapelberg und zunächst gehen wir mal darauf ein, was euch in den Vortrag erwartet. Am Anfang möchte ich erst mal motivieren, warum haben wir das Projekt überhaupt gestartet. Dann gebe ich einen Überblick darüber, wie es als Ganzes funktioniert, werde und detail auf die sogenannte Robust Session eingehen und erkläre ich ein bisschen, wie RAVT das System, worauf unser System basiert, funktioniert. Dann sprechen wir ein bisschen über das Kleingedruckte, also was sind so die Sachen, die ihr im Hinterkopf behalten müsst. Es ist nicht alles Gold, was glänzt. Und dann kommt, was ich persönlich besonders spannend finde, die lessons learned. Also was haben wir im Umgang mit dem System in den letzten paar Monaten daraus gelernt. Zu Fragen, sofern ihr Fragen habt, die wichtig sind, dass sie sofort beantwortet werden. Also für den weiteren Fall auf das Vortrag, dann meldet euch bitte, also einfach kurz Handzeichen geben, dann nehme ich euch dran. Ansonsten haben wir am Ende des Vortrags noch Zeit für generelle Fragen. Gut, Hintergrund, wer von euch kennt IAC, bitte Handheben. Das sind ausnahmslos alle, okay super. Trotzdem, Internet Relate Chat ist, wofür IAC steht. Es ist in einem oder mehreren RFCs spezifiziert. Ich habe mir die jeweiligen RFCs durchgelesen, also es gibt das Original 1459, dann gibt es 281, 02811 und so weiter. Da gibt es so 3, 4 verschiedene RFCs, die ein bisschen aktuelleren Stand beschreiben als das Original von damals 1989, was jetzt dann doch schon eine Weile her ist. Das Problem ist, dass alle diese RFCs zwar etwas beschreiben, aber das, was die Server implementieren, ist dann entweder nicht ganz das, was die RFCs beschreiben oder mehr, als die RFCs beschreiben. Und das sieht man sehr häufig. Also fast jeder IAC Server hat die eine oder andere Extension zusätzlich eingebaut oder verhält sich in einen kleinen wenig anders. Ich habe hier zwei Bilder noch auf der Folie, einfach um zu verdeutlichen, dass IAC ein Protokoll ist, welches von sehr, sehr vielen Geräten unterstützt wird. Also es gibt sowohl Clients für Android, also für jede andere erdenkliche Mobilplattform, es gibt sie für Desktops und so weiter, einfach weil das Ding schon so alt ist. Und die Motivation, warum wir uns jetzt überhaupt noch mal mit IAC beschäftigen, was ja jetzt schon ein wirklich sehr altes Protokoll ist, und man denken könnte, okay, da ist schon alles gemacht, was man machen könnte, ist, dass IAC in manchen Kreisen einfach noch weit verbreitet ist. Also das muss ich euch nicht erzählen, ihr habt bestimmt ein oder mehrere Channels, in denen ihr häufig seid. In der Open Source Szene ist das einfach, einen gebenen IAC-Channel zu haben. Ich habe einen IAC-Channel für unseren lokalen Chaos-Treff, von damals, den ich immer noch häufig benutze. Und wir haben uns dann auf dem Kongress, also gerade der aktuell vergangenen Kongress, mal umgeschaut, so können wir eigentlich unseren IAC-Channel durch irgendwas ersetzen. Und haben einfach keine überzeugende Alternative gefunden. Also es gibt vielversprechende Ansätze, so wie Talks oder so, aber da sind dann entweder die Clients noch zu weit am Anfang des Entwicklungsstadiums, oder es gibt andere Nachteile, also nichts hat uns zu Recht überzeugt, weil man muss ein paar Sachen angeschaut. Das einzige Problem, also wir sind dann in uns gegangen, haben uns überlegt, was ist eigentlich das Problem mit IAC? Eigentlich taugt das doch, wir verwenden es ja, also offensichtlich muss es okay genug sein, aber die Stabilität ist einfach verbesserungswürdig. Also immer, wenn du einen Abbruch von der TCP-Verbindung hast, ganz egal wo in dem Netz, also wenn du die TCP-Verbindung zwischen deinem Computer und dem Server verliest, dann fliegst nur du daraus. Aber wenn die TCP-Verbindung zwischen zwei Servern in dem Netz auseinandergehen, aus welchem Grund auch immer, dann ist gleich ein kompletter Teil an Nutzern betroffen von einem Phänomen, das sich Netzblit nennt. Und das ist jetzt per se natürlich ein doofes Problem, was man in der heutigen Zeit nicht mehr haben möchte, aber noch schlimmer wird es dadurch, dass Software-Updates, Reboots und jegliche andere Eingriffe, die dafür sorgen, dass nen IAC-Server kurzzeitig down sein muss, zerteilen ebenfalls das Netz. Also wenn ich jetzt die VM, auf der mein IAC-Server läuft, upgraden will, dann fliegen dadurch Leute daraus. Und das ist ne ganz, ganz schlechte Incentive, weil ich dadurch keine Updates mache auf der Kiste, weil die häufiger ich ein Update mache, dass so schlechter die Qualität des Netzes. Also da stimmt was nicht, finde ich. Und dann haben wir uns überlegt, okay, angenommen, wir könnten die Netzblitz verhindern. Wie würden wir das machen? Wie würden wir kompatibel bleiben? Also können wir das irgendwie schaffen, dass wir genau das Gleiche haben wie IAC, aber ohne die Netzblitz. Und die Idee war dann also, okay, wir müssen TCP-Verbindungsabbrüche transparent handeln. Und weiterhin war die Observation, naja, es gibt hoch verfügbare Datenbanken, also muss das hier irgendwie gehen, dann machen wir es doch so, wir verteilen unseren IAC-Server auf mehrere tatsächliche Server und gestalten ihn sozusagen genauso wie so eine hoch verfügbare Datenbank auf Basis von ParkSource oder RAVT oder eines von diesen anderen Concurrency-Protokollen, die es da so gibt. Wir haben uns dann letztendlich für RAVT entschlossen. Und da werde ich gleich auch noch erklären, wie das genau funktioniert. Das erfordert ein bisschen ein anderes Ein- und Ausgabemodell. Das zeige ich euch auch gleich noch. Okay, also Überblick. Wie funktioniert das jetzt grob, was wir uns überlegt haben? Wir haben N, robust IAC-Server mit N ist mindestens 3, können aber auch 5 sein oder 7 oder noch mehr, je nachdem, wie groß das Netz halt sein soll. Und die bilden einen virtuellen IAC-Server. Das heißt, man hat nicht mehr einen IAC-Netz bestehend aus mehreren zusammengelingten Servern, sondern man hat immer noch mehrere Server, aber die kommunizieren anders miteinander und die bilden quasi einen virtuellen Server. Ausfälle von der Minderheit des Netzes, also abgerundet die Hälfte der Knoten sind noch okay. Das heißt, bei 3 Servern darf einer ausfallen. Bei 5 Servern dürfen 2 ausfallen. Und ein Anwender merkt davon nichts. Also es geht einfach ganz normal weiter. Um das zu realisieren, haben wir uns ein sehr simples Protokoll überlegt und das nennen wir robust Session. Das wird zwischen dem Server und den Clients gesprochen. Jetzt ist aber die Sache okay. Ich habe ja gesagt, wir wollen genau das Gleiche wie IAC haben. Also muss das ja auch mit dem bestehenden IAC-Clients funktionieren. Für das gibt es wiederum die Bridge, die so genannte. Das heißt, es geht so nah zwischen IAC und dem robust Session Protokoll. Idealerweise läuft diese Bridge so nah wie möglich an dem IAC-Client. Das heißt, entweder sie läuft auf dem selben Rechner wie der IAC-Client oder man braucht sogar die Bridge gar nicht und der IAC-Client selber bringt einen Plugin mit oder so. Wir haben tatsächlich mittlerweile einen Plugin für IAC geschrieben. Das funktioniert, das kann man verwenden und einen Plugin für WeChat ist in Arbeit. Was ist das Problem, wenn die Bridge nicht auf dem lokalen Rechner läuft, sind Netzabbrüche zwischen dem lokalen IAC-Client und der Bridge nach wie vor ein Problem. Also dann hat man das Problem nur verlagert und nicht gelöst. Okay, nochmal als Übersicht. Man hat also hier diese robust IAC-Cloud. Das ist also der Verbund von mehreren Servern zu einem virtuellen IAC-Server. Dann hat man verschiedene Bridges und verschiedene IAC-Clients. Und die kann man, wie man möchte, zusammen schalten. Also eine Bridge, die läuft, kann mehrere IAC-Clients handhaben. Das heißt, wir haben zum Beispiel auf unserem Vereinsserver, wo ca. zehn Leute oder so einen IAC-Client am Laufen haben, haben wir einfach eine Bridge installiert und die können sich alle auf LogLost verbinden und dann kommen sie ins robust IAC. Für Leute, die aber nicht extra eine Bridge installieren wollen und sich da gar nicht zum Kümmern wollen, die wollen einfach normales IAC benutzen und denen ist das jetzt erstmal egal, ob das ein Netzplatt hat oder nicht, lassen wir auch Bridges laufen auf unseren tatsächlichen Servern. Da hat man dann natürlich nach wie vor das Problem, wenn die Netzverbindung abreißt, ist man draußen, aber da ist man dann sozusagen selber schuld und man kann immerhin sehr schnell in das Netz einsteigen, ohne dass man irgendwas installieren muss. Okay, wie funktioniert das Robust-Session-Protokoll? Statt puren TCP-Verbindungen verwenden wir HTTP plus JSON. Warum das? Einfach weil JSON sehr, sehr, sehr verbreitet ist. Das heißt, es gibt für jede erdenkliche Programmiersprache und man kann das mit den Python-Parser. Das heißt, es ist keine Hürde für uns, wenn wir Support in einem bestimmten Client einbauen wollen, sondern wir können davon ausgehen, okay, da gibt es auf jeden Fall was und HTTP, weil es einfach so sehr gebräuchlich ist. Also ich habe mal gehört, HTTP ist das neue IP und da macht man dann alles drüber. Das finde ich jetzt eine recht gute Analogie. Die vier Methoden, die wir in Robust-Session bereitstellen, entsprechen den normalerweise über TCP-Verbindungen gemachten Sachen. Also es gibt hier Connect, Send, Receive und Disconnect. Das sind so die vier großen Sachen, die man mit einer TCP-Verbindung macht. Wir haben das einfach umgesetzt auf einen Create-Request, für Connect, einen Post, für Send, einen Get für Receive und einen Delete für Disconnect. Das heißt, von der Logik her, wie das funktioniert, bleibt auch für die IAC Clients, alles gleich. Also Sie haben immer noch genau dieselben Operationen, nur führen Sie sie jetzt ein bisschen anders aus. Für den Nachrichtenversand brauchen wir natürlich einen Retry. Das heißt, wenn einer dieser HTTP-Requests fehlschlägt, haben wir gesagt, das müssen wir abkönnen. Das heißt, da schicken wir dann einfach dieselbe Nachricht nochmal. Und wir haben einen Duplikatfilter. Das heißt, der Client ist dafür zuständig, dass er sich eine Client-Message-ID ausdenkt und der Server kann dann sagen, ah, die Client-Message, die hast du gerade eben schon geschickt. Ich sage jetzt einfach mal, ist alles okay, damit der Client weiß, jetzt ist die endlich akzeptiert. Aber auch wenn der Server die schon mal bekommen hat, dann ist das kein Problem. Das heißt, da gibt es keine Duplikate im normalen Betrieb. Es gibt außerdem Resume für das Empfang von Nachrichten. Das heißt, wenn ich diesen Get mache, den Get-Request, dann ist das nicht ein Get-Request pro Nachricht oder so, sondern es ist ein lang laufender Get-Request und der kriegt dann Nachrichten gestreamt über chunked HTTP. Und wenn der irgendwann abreißt, passiert, zum Beispiel, wenn ich den Server neu starte, dann weiß der Client ja noch die letzte Nachrichten-ID, die er bekommen hat und geht einfach zu einem beliebigen anderen Server, der gerade verfügbar ist und sagt, hey, ich möchte bitte ab hier weiterlesen und dann kriegt er einfach ab da weiter die Nachrichten geschickt. Und es ist außerdem so, dass jeder Server jede Methode beantworten kann, also vor allem auch jeden Endpunkt. Das macht er, indem er eventuell zum aktuellen Leader Reverse proxied. Also alle Sachen, die den State verändern, können nur auf dem Leader passieren, aber es ist nicht notwendig, dass der Client direkt mit dem Leader spricht. Das ist deswegen wichtig, weil wenn man eine Netz hat und angenommen es gibt einen Netzausfall durch ein kaputtes Peering oder so zwischen einem Betreiber und den Endnutzern, dann ist das kein Problem. Die Endnutzer können immer noch über einen von den anderen Servern in das Netz wieder drehen. Also wir machen da quasi einmal proxy spielen, wenn das nötig ist. Aber die Clients versuchen selbstständig, direkt mit dem Leader zu sprechen. Wenn es nicht geht, gibt es den Fallback. Okay, ich habe jetzt schon ein paar Mal Raft erwähnt. Ich lese kurz die Definition auf Wikipedia vor, weil ich finde, dass sie recht präzise ist. Dort steht Raft ist ein Konsensus-Algorithm. Es wird mehr verständlich sein als Pexos, aber es ist auch formally proven safe und offert neue Features. Raft offers a generic way to distribute a state machine across a cluster of computing systems, ensuring that each node in the cluster agrees upon the same series of state transactions. Wer hat noch nie mit einer State-Maschine gearbeitet? Okay, paar Hände. Das funktioniert so, dass man einfach Code hat, und der schaut, in welchem Zustand bin ich gerade, und dann wechselt er in einen anderen Zustand. Das heißt, dass die Ein- und Ausgabe ist immer sehr klar. Und was Raft macht, ist, dass das Modell auf mehrere Computer abbildet. Das heißt, die Konsequenz ist, dass wir unseren IRC-Server so implementieren müssen, dass er immer die gleiche Ausgabe erzeugt, wenn er die gleiche Eingabe erhält. Sonst ist das keine verteilte State-Maschine. Und das ist interessant. Also Leute, die sich mit Funktionalerprogrammierung beschäftigt haben, kennen das Prinzip sicherlich, dass das alles pur ist und wir können auch die Ausgabe von Aus- und Trainkommen und so. Und die allermeisten IRC-Server heutzutage sind halt nicht so gebaut. Deswegen brauchen wir überhaupt auch erst eine eigene IRC-Server-Implementation. Okay, Kurzfassung, wie Raft funktioniert. Ich gehe nochmal kurz zurück. Die links, die ich hier unten hingepackt habe auf die Folie. Zum einen, dass der Wikipedia-Antrag der Erste, der Zweite, ist die eigentliche Website von Raft. Da gibt es einen coolen Überblick, in welchen Sprachen das alles implementiert wurde. Das ist, glaube ich, mittlerweile 20 Implementationen oder so. Und das ganz Letzte ist eine interaktive Visualisierung, die ist sehr cool. Wenn euch das Thema interessiert, dann klickt das einfach mal durch, sind gut verbrachte 5 Minuten und dann wisst ihr genau, ah, so funktioniert das. Und dann geht das hin und her und so. Ich zeige es euch jetzt mal auf einer ganz groben Ebene. Also ich habe hier jetzt drei Knoten abgebildet. Der Knoten links oben auf der Folie, der mit A betitelt ist und grün hinterlegt ist, ist der aktuelle Raft-Lieder. Also es gibt immer einen Lieder und eine bestimmte Anzahl an Followern. Nur der Lieder darf immer State verändern. Also der Lieder steht auch immer in Kontakt mit allen anderen Followern. Das heißt, die Topologie ist immer so, dass alle Knoten sich quasi um diesen Lieder herum sammeln. Deswegen also die Pfeile zwischen A und B und A und C. Die kommunizieren also. So, das Ganze bildet eben ein Raft-Network. Und wenn jetzt der Klein von außen kommt und an den Lieder eine Nachricht schickt, dann passiert folgendes, der Lieder schickt diese Nachricht auch an B und auch an C. Und ich habe jetzt hier die Latenzen notiert. Also die Verbindung zwischen A und B ist jetzt mit sechs Millisekunden betitelt und die Verbindung zwischen A und C mit acht Millisekunden. Was ich damit verdeutlichen möchte, ist, dass der Lieder braucht eine Mehrheit in dem Netz. Also er muss wissen, dass die Nachricht auf der Mehrheit der Knoten angekommen ist, bevor er sich tatsächlich entscheidet und sagt, ja, die habe ich jetzt wirklich bekommen und kann sie verarbeiten. Das heißt, er verteilt sie erst mal und erst dann, wenn genug Knoten gesagt haben, geht es wirklich weiter. Und wenn also B binnen sechs Millisekunden antwortet und A ja ohnehin die Nachricht schon hat, dann hat man damit bei drei Knoten, die Mehrheit nämlich zwei Knoten und dann kann die Nachricht verarbeitet werden und C kriegt sie dann auch irgendwann. Okay, so wie wenden wir jetzt Raft an? Wir replizieren die IAC Nachrichten, also alle Eingaben Nachrichten, das heißt, alles, was die Clients an den Server schicken, replizieren wir über Raft. Und die Antworten, also alles, was der Server schickt, hängen nur von der Nachricht ab. Dadurch wird also gewährleistet, dass jeder Server den selben State generiert und das auch nach einem Neustart derselbe State generiert. Das heißt, man kann sich das so vorstellen, wie das der Server ein komplettes Log auf der Platte hält und nach einem Neustart läuft er dieses Log von Anfang bis Ende wieder durch und dann ist er wieder up to date sozusagen. Also er hat dann genau dasselbe verarbeitet und laut dem Paradigma muss dann auch wieder er in genau derselben Stelle sein. Also so kriegt man das hin, dass alle Prozesse, die ganze Zeit laufen, man ein verteiltes Computing hat. Okay, Übersicht. Wie funktioniert es tatsächlich, wenn da Daten reinkommen? Also hier oben ist das Kästchen mit dem Client. Der Client schickt über Post, über Robust Session, eine Message. Und eine Message kann zum Beispiel so was sein, wie join hash i3 für den i3 Channel. Das ist also was direkt IAC on the wire schickt. Also IAC ist ein ASCII-Protokoll, das kann man wirklich mitlesen. Der Lieder bekommt das dann und er interessiert das auf die drei Knoten, wie gerade angedeutet. Mit eins und zwei hat er Quorum erreicht, also die Mehrheit. Und drei ist dann der Rest. Dann sowohl der Lieder als auch die Followers rufen dann IAC Server.Process auf und das generiert dann eine Ausgabe, wie eben hier zum Beispiel doppelpunkt secure join hash i3. Das ist also die Nachricht, die das Server an die Client schickt und dann fügt er sie dem sogenannten Output Stream hinzu das worauf der Client mit dem GetRequest zugreifen kann. Also so funktioniert das. Okay, jetzt haben sicherlich einige aufgepasst und haben aufgestreckt bei dem Satz, als ich erzählt habe, der IAC Server hat ein komplettes Lock. Das ist natürlich blöd, wenn man die IAC Nachrichten zunächst mal für immer speichert. Zum einen hat man ein gravierendes Privacy-Problem, man will ja diese ganzen Nachrichten eigentlich gar nicht vorhalten. Zum anderen hat man effektiv auch irgendwann ein Speicherproblem. Speicher ist ja endlich. Man muss sich überlegen, wie kann man das periodisch aufräumen und was kann man periodisch aufräumen. Der Prozess des Aufräums, den nennen wir Compaction. Es ist jetzt relativ intuitiv, dass beim Aufräumen zunächst mal so Sachen, die keinen State verändern, so etwas wie eine Nachricht, also ich schicke jemandem eine Nachricht, das kann ich einfach löschen. Die Nachricht ist dann ab einem gewissen Zeitpunkt nicht mehr relevant. Wenn alle Knoten, wenn alle Clients die Nachricht erhalten haben, dann brauche ich sie nicht mehr aufheben. Das ist, denke ich, einleuchtend. Und das ist jetzt in folgendem Beispiel illustriert. Nachrichten, die den State des IAC-Service verändern, und das sind im Wesentlichen alle außer Priv-Message-Notice, was die beiden Arten sind, wie man eine Nachricht schickt. Diese Nachrichten kann man nicht so einfach löschen. Da muss man sich genau anschauen, was kann man löschen. Auf der linken Seite der Folie habe ich jetzt hier illustriert, da wird zuerst Nick auf Secure-Anderscore gesetzt, dann habe ich hier Join-Hash-Lux und dann ändere ich mein Nick auf Secure. Auf der rechten Seite wird dann illustriert, wie das nach der Compaction aussieht. Dort ist also Nick Secure durchgestrichen und Join-Lux ist noch da und Nick Secure ist noch da. Warum das Ganze? Ich kann die erste Nick-Nachricht einfach löschen, weil wenn ich einen Join mache und direkt danach mein Nick ändere, dann ist das ja equivalent, wie als hätte ich ursprünglich mit dem Nick gejoint. Das war jetzt vielleicht ein bisschen verwirrend. Wer hat das nicht verstanden, Handheben? Okay, einer. Das ist vielleicht klar bei der nächsten Folie, ansonsten versuche ich das nochmal von vorne. Jetzt schauen wir uns folgendes Beispiel an. Ich setze meinen Nick auf Secure-Anderscore, joine den Looks-Channel, setze in dem Looks-Channel ein Topic und ändere dann meinen Nickname auf Secure. Jetzt könnte man sich eben wieder überlegen, okay, die alte Nick-Nachricht könnte ich ja jetzt wieder löschen, aber das Problem ist, dass die Topic-Nachricht, wenn es die Antwort auf die Topic-Nachricht ist, dass an alle anderen Kleins eben geschickt wird, hey, hier wurde das Topic geändert, das ist die Nachricht mit dem Code 332 und dann kommt der Clue, nämlich die Nachricht 333, die sagt, von wem an welchem Zeitstempel das Topic geändert wurde. Und jetzt ist das Problem, wenn ich meinen Nick von Anfang an auf Secure gesetzt hätte und dann einen Join verarbeitet und dann ein Topic, dann würde ja hier was anderes stehen und damit ist das nicht mehr deterministisch. Und das ist ein Problem. Erst wenn danach, nachdem ich meinen Nick geändert habe, nochmal das Topic gesetzt wird, ist quasi diese dependency zwischen den beiden Nachrichten weg und erst dann kann ich die Nachrichten löschen. Genau, hier ist das illustriert, also wenn ich nachdem ich den Nick-Änderen nochmal ein Topic setze, dann wiederum kann ich sowohl das alte Topic löschen, weil das interessiert ja keinen mehr, das neue Topic überschreibt ja das alte, als auch den alten Nick, als ich zum Zeitpunkt des Joints hatte, interessiert auch keinen, das ist auch in der Nachricht nicht enthalten. Das ist vielleicht nicht hundertprozentig klar, ich wollte es hauptsächlich nur erwähnt haben, damit man einen Eindruck davon bekommt, wo liegen eigentlich die Schwierigkeiten in so einer Implementation. Ich kann darüber gleich noch ein bisschen mehr sprechen. Schauen wir dann einfach, wie das bei dem Fragenteil des Vortrags ist. So, jetzt das Kleingedruckte. Das Problem, das eine Problem, was man hat oder die eine Eigenschaft, die man hat, das ist per se in der Praxis kein Problem, ist, dass der Speed des Netzes, also die Geschwindigkeit, wie schnell ich eine Nachricht auf alle Teilnehmer verteilen kann, ist durch die Serververbindung limitiert. Das heißt, die Latents zwischen ich schicke eine Nachricht und die Nachricht wird an alle anderen Leute verteilt, ist zumindest mal die Medienlatents zwischen Leader und Followern, weil wir erinnern uns, man braucht ja eine Mehrheit. Aber die lassen wir jetzt mal außen vor. Weiterhin ist es so, dass die Ausfallsicherheit des Netzes mindestens drei Standorte erfordert. Da muss man jetzt vielleicht ein bisschen mehr dazu erzählen. Angenommen, ich mache einen robust ARC-Netz und lasse das auf 3 VMs auf demselben Host laufen. Das ist natürlich eine sehr blöde Idee, weil wenn ich den Host reboote, sind alle VMs weg, sind alle Server weg und dann kann das nicht mehr funktionieren. Jetzt ist die Frage, wie weit geht man da? Also ich könnte jetzt sagen, okay, dann verteile ich es halt auf 3 VMs und dann kann ich einen Host rebooten und dann hat das Netz kein Problem. Dann geht das. Jetzt ist aber die Frage, sind alle diese 3 Hosts im selben Rack und was passiert, wenn der Strom zu meinem Rack unterbrochen wird? So, dann ist die nächste Frage, okay, ich verteile sie auf verschiedene Racks, aber die sind ja alle im selben Datacenter. Was passiert, wenn im selben Datacenter der Link unterbrochen, und so weiter? Also geht man quasi stückweise nach oben und eigentlich, wenn man um ein gutes robust ARC-Netz zu fahren, dem Netz, was wir betreiben, haben wir zum Beispiel einen Server bei Hetzner, einen Server bei Vollmar und einen Server in den Schweizer Alpen und dann hat man einfach so viele verschiedene Anbindungen, so viele verschiedene Stromzufuhren, so viele verschiedene Hardware, so viele verschiedene Betriebssysteme auch und Laufzeitumgebungen, dass da einfach es sehr, sehr, sehr unwahrscheinlich ist, dass es einen koordinierten Fehler zwischen verschiedenen Knoten gibt. Und der Punkt ist halt, je nachdem, wie ausversichert man das jetzt haben will, das heißt, wenn man den Netz mit fünf Knoten fährt, dürfen da auch schon mal zwei davon ausfallen. Allerdings ist es mir natürlich klar, dass jetzt die Mindestanforderungen an so einen IR10-Netz auf einmal höher sind. Also jetzt kann man nicht mehr einfach sagen, ich mache ein IR10-Netz, okay, ich hau hier meinen einen Prozess auf den einen Server und link den mit einem anderen Server, der hier gerade mein anderer Kumpel gemietet hat, im selben Rek, dann kriegt man das nicht hin. Andererseits, der Anspruch, den wir hier haben, ist natürlich auch sehr viel höher, also es ist klar, dass mit einem höheren Anspruch an das Netz auch der Anspruch an die Umgebung höher wird. Und zu guter Letzt ist es so, dass der Durchsatz eventuell auch nicht hoch genug ist für große Netze. Wir haben uns das mal angeschaut und der Durchsatz, den wir momentan erzielen können, ist so ungefähr ein bisschen über 1000 Messages pro Sekunde. Es gibt einen Proposal dazu, wie man das schön verteilen kann, dass man mehr Messages tatsächlich persistieren kann. Aber wenn man sich mal anschaut, wie man die tatsächliche Netze haben, also große Netze, bei denen man diese Zahlen erheben kann, ich glaube bei Free Note haben wir geschaut oder bei Irknet oder beiden, dann ist das nicht signifikant höher als das. Also die Zahlen, die ich kenne, können wir tatsächlich abdecken. Aber ich will nicht ausschließen, dass es Netze gibt, die viel mehr als das handeln. Und da könnte man vielleicht RobustRC nicht einsetzen. Okay, jetzt machen wir erstmal eine Demo, weil Demo ist cool, und dann habt ihr auch gleich einen viel besseren Eindruck davon, wie das funktioniert. Also, ich habe hier mal etwas vorbereitet. Hier oben rechts habe ich einen IRC-Klein. Und dann habe ich hier noch einen IRC-Klein. Und hier auf der linken Seite starte ich jetzt mal ein RobustRC-Netz. Es gibt dafür so ein cooles Tool, das nennt sich RobustRC-Locanet. Das haben wir geschrieben, damit man eben schnell so ein Netz aufbauen kann. Das hat das jetzt gemacht. Das macht einfach alles. Also wenn man keine SSL-Zertifikate hat, dann generiert das eins. Dann baut es drei verschiedene Knoten auf und linkt die alle zusammen und so weiter. Also es ist alles fix und fertig. Wenn ich jetzt hier sage, connect localhost, dann bin ich verbunden. Also so einfach geht das. Man sieht hier oben, in dieser Zeile sagt er, welcome to RobustRC. Der Server teilt einem mit, was er kann und so weiter. Und dann kann man ganz normal IRC benutzen, wie man das so gewohnt ist. Also jetzt habe ich hier diesen Channel gejoint damit das Ganze auch spannender wird. So, jetzt sieht man auch hier, okay, in dem ersten wurde angezeigt, der zweite ist jetzt in den Raum gekommen. Das kann ich in dem zweiten sagen, hey, und dann sehe ich das. Okay, also soweit, alles klar, oder ihr habt alle schon mal IRC gesehen. So, jetzt ist es allerdings so, hier in dieser Zeile im RobustRC-Locanet-Output hat er gesagt, note is available at und dann hat er mir hier so eine Adresse gegeben. Dann gehe ich doch da mal drauf auf die Status-Seite. Jeder dieser Knoten hat, dadurch dass er ohnehin überhatte TP ansprechbar sein muss, weil das unser Protokoll ist, haben wir uns gedacht, naja gut, machen wir auch noch eine Status-Seite dran, da kann man sehen, was der Server eigentlich gerade macht. Hier sieht man jetzt, der erste Knoten ist im Zustand Lieder, das ist nicht weiter verwunderlich, weil der erste muss als Lieder gestartet werden und das Netz konfiguriert sich nur dann um, wenn es tatsächlich irgendeinen Ausfall gibt. Also wenn wir jetzt gleich den Liederknoten abschießen, den Zeug eingestellt, also die Konfig wird gedammt und Raft-Statistiken gibt es, dann sehen wir hier, wer uns gerade einen Get-Messages-Request geschickt hat, also welche gerade am Laufen sind. Man sieht, welche Kleinversion die haben, was eine gute Sache ist, wenn man Updates machen will und sicherstellen will, dass die Kleinste alle haben. Man sieht, welche Sessions aktiv sind und was über die Leitung geht. Also hier sieht man tatsächlich die kompletten IRC-Nachrichten, wie sie der Klein geschickt hat und das ist ja auch alles, was ausschlaggebend ist, weil die Antworten sind ja wie gesagt deterministisch. Okay, so viel dazu, das ist die erste Status-Seite, es gibt hier noch eine zweite Status-Seite, die mache ich mal in einem anderen Tab auf und dann gibt es noch eine dritte, weil LocalNet ein Netz mit drei Knoten startet. So, sehen wir also, wenn ich hier durchgehe, der erste ist Lieder, der zweite Follower, der dritte auch Follower, so weit so gut. Jetzt ist natürlich die Frage, was passiert, wenn ich zum Beispiel den Lieder abschieße. Also ich schaue doch jetzt mal, was sind hier meine Prozesse in der Prozessliste. Das ist der erste Prozess, da sage ich kill, zack. Okay, jetzt schauen wir in dem ersten Tab. Okay, das funktioniert jetzt nicht mehr. Also der Lieder ist jetzt nicht mehr da. Ich schaue in dem zweiten Tab und in dem dritten Tab und sehe, aha, der zweite ist jetzt Lieder geworden, der dritte ist nach wie vor Follower. Und wenn ich jetzt wieder zurückgehe und hier schaue, dann sehe ich, okay, mein Netz funktioniert immer noch. Und da muss man jetzt auch noch mal kurz schauen. Es war ja so, dass auf dem ersten Knoten angezeigt wurde, dass beide Get-Messages, also von meinen beiden Clients auf dem ersten Knoten waren. Und jetzt habe ich den ersten abgeschossen und jetzt sehe ich, okay, auf dem dritten ist ein Get-Messages und auf dem zweiten ist ein Get-Messages. Also die Clients merken das sehr schnell, wenn die Verbindung fehlgeschlagen ist. Die haben da auch ein entsprechendes Time-Out, wenn nichts passiert, und feilen dann over zu einem anderen Knoten. Also das geht einfach nahtlos weiter. Was passiert, wenn ich den zwei Knoten abschieße? Das können wir jetzt auch einfach mal machen. 1, 2, 3, und jetzt sehen wir, okay, der zweite ist nicht mehr verfügbar, der dritte ist verfügbar. Der sagt jetzt, er ist im State Candidate. Das bedeutet, er versucht gerade, einen Lieder zu wählen und schlägt vor, hey, wie wär's, wenn ich Lieder wäre und fragt die anderen, und keiner antwortet. Und dann kann er natürlich nichts machen. Und das Netz ist jetzt auch eingefroren. Also wenn ich jetzt hier ein Test 3 schicke, dann sehe ich, das kommt hier oben nicht an. Dann würden die ERC-Kleins irgendwann merken, oh, da ist ein Ping Time-Out, ich muss mich jetzt disconnecten. Jetzt simulieren wir doch mal, was passiert, wenn das Netz wiederkommt. Es gibt hier für im LocalNet so einen schönen Script namens Restart. Jetzt sieht man auch hier unten, der erste ERC-Klein hat gecheckt, oh, es gibt hier einen Lag, hier passiert irgendwas Komisches. Dann gehen wir nochmal auf den zweiten Knoten, der ist jetzt wieder neu gestartet. Er ist jetzt Follower, der dritte hat also diesmal den Liederstatus bekommen. Und genau, jetzt seht ihr hier, das ist ein 3 Lag, 24 Sekunden Lag, aber mittlerweile ist die Test 3 Nachricht hier oben wieder angekommen. Das heißt, selbst im aller aller schlimmsten Fall, wenn tatsächlich mehr Knoten ausfallen, als ihr geplant habt, das ausfallen dürfen, funktioniert das Netz immer noch. Es ist halt eingefroren und wenn das zu lange dauert, dann fliegen die Kleins raus. Aber es fängt sich wieder, sozusagen. Also bei kurzen Unterbrechungen, selbst wenn ihr mit reduzierter Kapazität läuft, dann funktioniert das immer noch. Okay, ich schau kurz auf die Zeit. Okay, wir haben noch gut Zeit. Ich zeige euch noch kurz, wie auf der Folie angedeutet das Monitoring, was dazu entwickelt wurde. Das ist jetzt, ja, man kann es sehr gut sehen. Normalerweise sind da 2 Grafen nebeneinander. Ich gehe hier einfach mal so ein bisschen durch. Also ich habe mir hier Grafen gebaut für Wer ist der aktuelle Lieder? Da kann man hier einfach drüberhabern und dann sieht man, okay, ab dieser Uhrzeit, also ab 10.00 Uhr, 17.00 GMT ist Alp der aktuelle Lieder. Dann kann ich sehen, okay, wie viele Nachrichten pro Sekunde wurden committed. Wenn das auf 0 geht, dann weiß ich, irgendwas ist schief gelaufen, da kommen keine Nachrichten mehr ins Netz. Ich sehe, wie viel CPU-Sekunden brauchen die, also wie es so die Auslastung über die Zeit verteilt. Kann ich hier sehen, okay, hier war irgendwas und was da war, also was diese ganzen Spikes hier jeweils sind, sind die Compaction-Läufe. Also wenn sich der Server anschaut, welche alten Nachrichten kann ich eigentlich löschen. Und das ist halt ein recht CPU-intensiver Prozess, aber auch nicht so mega lang. Da kommt wahrscheinlich die Anzahl an IAC-Sessions. Das kommt wahrscheinlich weg. Die Commit-Time, also wie lange dauert es eigentlich, bis ein Nachricht persistiert wurde. Man kann hier sehen, das hafert so bei 12 Millisekunden, je nachdem, welcher Knoten das ist, 18 Millisekunden, dann die RPCs pro Sekunde. Das ist nicht sonderlich spannend, wenn das Netz ordentlich funktioniert. Der Top-5-IAC-Command-Breakdown, der häufigste Command-Ping und ja, dann kommen andere automatisierte Comands wie Hu und Comands, die tatsächlich irgendwas machen, so hier User-Quit und so. Das ist auch wiederum durch mein Monitoring-System, welches immer schaut, kann ich mich überhaupt noch anmelden. Und wie man sieht, sind tatsächliche Nachrichten verschwindend gering. Dann gibt es noch, ja, die Latents wird geplottet und die Network-Availability. Okay, wenn sowas interessiert, gehe ich noch genauer in meinem Prometheus-Vortrag morgen um 17.30 Uhr drauf ein. Das wollte ich euch nur mal zeigen, dass ihr seht, wie sieht das eigentlich aus, was es betreibt, was kann man sich da so anschauen. Okay, zu den Lessons learned. Wir haben das Projekt gestartet noch auf dem Kongress und hatten den ersten Channel in unser Robusti-Arcinez umgezogen, ich glaube im März. Das heißt, seitdem knapp drei Monate vergangen und was wir gelernt haben. Zum einen die Nutzer-Änderung nur sehr zögerlich, ihr IAC-Setup. Das erstaunt wahrscheinlich keinen, aber es ist trotzdem interessant, mal die Zahlen zu sehen. Wir haben derzeit ca. 50% Nutzer auf Legacy-Arcinez. Das ist der Name von den Bridges, die wir laufen lassen für die Nutzer, die nicht Software installieren wollen. Wir haben 49% Leute, die eine eigene Bridge benutzen oder die Bridge, die auf unserem Verein-Server läuft, benutzen. Und wir haben 1%, das bin genau ich, der das IAC-Plugin benutzt. So viel dazu. Also darauf muss man sich einstellen. Was bedeutet das in der Praxis? Wenn es eine Netzausfall gibt von den Legacy-Arcinez Bridges, dann sind immer noch die Hälfte der Leute einfach aus. Das ist auch der nächste Punkt. Manche Bugs und manche Verhalten sind für Lion einfach ähnlich wie ein Netzblit. Weil sie halt doch nicht mehr mit den Leuten reden können. Das heißt, tatsächlich diese komplette Ausfallsicherheit zu bekommen erfordert auch ein bisschen Mitarbeit von den Nutzern. Deswegen würde ich wahrscheinlich auch sagen, das ist ein guter Anwendungsfall für robustarcy. Eine Community ist bei der die Leute einen recht hohen Zusammenhalt haben und man recht einfach die Leute erreichen kann. Es könnte zum Beispiel ein Firmennet sein, indem man ein stabiles Chat-System haben möchte oder könnte ein kleiner Chaos-Streff sein, sowas in die Richtung. Große Channels, wie zum Beispiel der WeChat-Channel oder so, da ist es wahrscheinlich unrealistisch, dass man jemals alle Leute dazu bekommt, dass ein hoher Prozentsatz auf nativem robustarcy läuft. Okay, zweiter Punkt. Manche Bugs sehen ähnlich aus wie Netzblitz. Es gibt interessante Failure-Modes, wie wir herausgefunden haben in verteilten Systemen. Das ist Leuten, die sich damit schon lange beschäftigen. Wahrscheinlich klar, trotzdem finde ich es spannend, was so alles passiert ist tatsächlich. Wir hatten einmal einen Deadlock. Ein Deadlock bedeutet, du hast verschiedene Threads oder in unserem Fall verschiedene Go-Routine und die möchten auf eine Ressource zugreifen, können das aber nicht gleichzeitig und deswegen muss man einen Mutex einbauen. Damit immer nur einer auf dieses Array zum Beispiel oder was noch immer irgendeine Datenstruktur zugreifen kann. Und wenn jetzt Folgendes passiert, dass jemand, das sich ein Thread den Mutex holt und ihn aber nicht wieder frei gibt, dann ist der Server kaputt. Dann kann kein anderer Thread mehr Progress machen, weil die warten alle auf den Mutex. Und wie ist uns das passiert? Wir hatten einen Fehler und stellte sich raus, dass Go standardmäßig Panics in HTTPS-Handlern einfach schluckt und sagt, wenn mal eine Seite nicht geändert werden, kann es schon nicht so schlimm. Bei uns ist aber ein HTTPS-Handler eben eine Netzwerkaktion, das ist eine robust RC Message im Wesentlichen. Und wenn da irgendwas schief geht und der durch einen Panic nicht wieder den Mutex frei gibt, ist das ganze Ding deadlocked. Wir haben das mittlerweile natürlich gefixt. Also mittlerweile haben wir dieses Verhalten ausgeschaltet, dass Panics automatisch geschluckt werden. Da würde dann also der Server entsprechend abstürzen. Die Kleins würden es checken und würden auf einen anderen Server übergehen. Aber trotzdem war das mal interessant, das zu sehen und es äußert sich tatsächlich darin, dass einfach das Netz irgendwann einfriert. Und dann die Kleins halt sich nach und nach, wie ich das vorhin angedeutet habe, durch den Pingtime-Out vom Netz trennen und sich wieder verbinden. Aber das geht halt nicht, weil das ist ja noch eingefroren. Ein anderer interessanter Punkt ist State Divergence. Wie kann das überhaupt passieren und was meine ich damit? Also was ich damit meine ist, angenommen ihr habt drei Server in eurem Netz und ihr habt zwei Leute, die chatten und die kommen beide in den Channel rein und dann habt ihr in diesem Fall so passiert, ist ein Bug im Compaction Code. Also eine Nachricht wird gelöscht, obwohl sie noch nicht gelöscht werden sollte. Nehmen wir an die Join-Nachricht von dem zweiten Teilnehmer im Netz. Das ist erstmal kein Problem, weil die Server denken ja noch, ja, der ist im Channel, ich habe das ja verarbeitet. Aber sobald man einen der Server neu startet und sie ihr Log replayen, dann ist eben dieser Join nicht mehr da. Und was passiert dann, wenn man an diesen Server eine Nachricht schickt und dann sagt der Server, du bist da gar nicht drin. Und das ist eine State Divergence. Ich habe da auch einen Link jeweils zu einem Bug Fix, wo uns das also passiert ist und das ist einfach auch sehr interessant über sowas nachzudenken. Mittlerweile gibt es auch einen Tool, mit dem wir sowas vorhersehen können und fixen können, in dem einfach eine neue Knoten Read Only in das Netz eingefügt wird, der sie dann alle Nachrichten holt, eine Compaction macht und dann anzeigt, hey, im Vergleich zu dem, was die Server denken, was aktuell Sache ist, das vergleichen, ob das identisch ist oder nicht. Dann hatten wir einmal die Situation, dass es doppelte Nachrichten gab. Da hatten dann manche Leute gesagt, hey, irgendwie die fünf Nachrichten, die hier geschickt wurden, die habe ich gerade eben schon mal erhalten. Und das passierte aber selten und nicht überall. Also war wieder so ein komischer Bug. Und das basierte einfach darauf, dass die Session Resumption, also das Resume Feature nicht ordentlich funktioniert hatte. Da gab es den Bug, wenn der Client dem Server gesagt hat, hey, ich möchte ab hier resumen und der Server an sich war aber durch den State Replay nach einem Neustart erst hier, dann hat er einfach alles nochmal geschickt ab dann. Und das haben wir mittlerweile auch gefixt, ist einfach ein Bug. So, weiter lustige Failure Modes. Ein zu aggressives RPC-Timeout, das war eine lustige Geschichte. Die RPCs, also RAVT erwartet, dass man ihm irgendwie sagt, wie kann ich mit anderen Knoten kommunizieren? Das erfordert die Library. Und wir haben das gemacht einfach über HTTP-Methoden, weil HTTP haben wir eh schon auf allen Knoten und da brauchen wir kein zusätzliches Protokoll, kein zusätzliches Port und so weiter. Und irgendwann haben wir dann aber eingeführt eben als fix für ein anderes Problem, dass alle diese Request, die wir über HTTP schicken, nach 10 Sekunden terminieren sollen. Was für die allermeisten Request okay ist und für den Normalzustand des Netzes okay ist, deswegen ist das nicht gleich aufgefallen. Aber wenn ein Knoten zu weit hinterherfällt, zum Beispiel, weil er für 2 Stunden down ist, weil ein Reboot nicht geklappt hat oder so, dann muss dieser Knoten zunächst ein Snapshot bekommen vom aktuellen Zustand von einem von den anderen Knoten. Und dieser Snapshot ist eben einige Dutzend megabyte groß und bis der übertragen ist, dauert das halt vielleicht schon mal mehr, als 10 Sekunden und dann ist uns dieser RPC nie geglückt und dann konnten wir keine Knoten wieder in das Netz einfügen. Das ist deswegen schlecht, weil man merkt das wieder erst, wenn man ein Knoten neu startet. Die Situation war also, wir haben Netz mit 3 Knoten, wir haben einen neu gestartet, das heißt nur noch 2 sind verfügbar und dann haben wir bemerkt, oh, scheiße, wir kriegen den dritten nicht mehr in das Netz. Wie fixt man das jetzt? Na ja, okay, man stellt das Timeout wieder hoch. Aber wie kann man diese Änderung jetzt ausrollen, ohne dass man die anderen Knoten, weil das sind ja nur noch 2, ja, wenn wir einen davon wegnehmen, dann friert das Netz ein. Also ist man quasi in so einer Situation so, okay, ich habe das Problem identifiziert, ich weiß ihn etwa, wie ich es lösen kann, weil, also ohne eine Downtime. Und tatsächlich haben wir es dann aber hinbekommen, weil, stellt sich raus, der Link zwischen den, also der, okay, da muss ich kurz ausholen, die Art und Weise, wie wir unser Netz aufgebaut haben, ist, wie gesagt, dass wir 3 verschiedene Standorte haben. Das heißt, die kommunizieren alle über das Internet. Da denken jetzt wahrscheinlich einige Leute, die RAV zum ersten Mal, also die RAV benutzt haben so, oh Gott, das kann sie doch nicht machen, RAV über das Internet zu fahren, aber es geht, offensichtlich. Aber der Clue ist eben, dass dieser Snapshot so lange gedauert hat, lag einfach daran, dass der Link zwischen diesen beiden Knoten 100 Mbit war. Jetzt ist es aber so, dass wir 2, die 2 anderen Knoten, also dieser, dieser andere Link war eben Gigabit Link. Das heißt, das Problem reduziert sich auf, wie kriege ich Sinn, dass der andere Knoten der Lieder ist, damit der andere dann mit einem Gigabit den Snapshot überträgt, was schneller ist als 10 Sekunden. Und dann haben wir eben geschaut, okay, wie kann ich jetzt mit einem Six-Stop und Six-Count so die Prozesse einfrieren, dass jeweils die Election so passiert, dass genau der Knoten Lieder wird. Und dann haben wir das gemacht und es ging und seitdem ist das Problem gefixt, also, spannend. Dann, anderer interessanter Failure-Mode. Dadurch, dass wir Nachrichten mit ein ID vergeben müssen, die immer fortlaufend ist, haben wir uns entschlossen, wir nehmen einfach den aktuellen Unix-Time-Stamp auf Nano-Sekunden Precision. Das ist, würde man jetzt sagen, okay, eine blöde Anfänger-Idee in einem verteilten System, das wird gleich sein. Für uns ist es aber gut genug, wenn die Zeit ungefähr gleich ist. Also, wenn die Zeit so auf 1, 2 Sekunden über NTP synchronisiert ist, ist es gar kein Problem. Und was aber passiert, wenn, was normalerweise passiert ist, wenn einer der Server feststellt, hey, ich habe jetzt einen neuen Nachricht bekommen, ich möchte deine ID geben, aber die ID ist auf einmal nicht mehr im Monoton fortlaufend zu der vorherrigen ID, dann sagt er, oh, das kann ich nicht machen und die anderen Knoten ist jetzt weg, die anderen Knoten übernehmen und dann kann der Atmen das fixen. Und was wir jetzt aber hatten, ist, dass nach einem Reboot, nach einem geplanten Reboot von einem unserer Knoten die Zeitabweichung so groß war, also war über eine Stunde, weil die Hardware-Clock nicht mit der System-Clock übereinstimmte, weil sie eben falsch eingestellt war, dass NTP sich entschlossen hat, ich fixe das jetzt nicht, also NTP hat nicht die Zeit synchronisiert. Und was jetzt das Problem ist, ist, wenn einer dieser Knoten, und die Uhr einfach eine Stunde in die Zukunft falsch läuft, dann gibt der neue Message-IDs raus, weil die sind ja fortlaufend, aber wenn danach ein anderer Knoten wiedermaster wird, dessen Uhr im Vergleich zu dem aktuellen eine Stunde zurückversetzt ist, kann der natürlich erstmal eine Stunde lang keine neuen IDs vergeben, bis er wieder aufgeholt hat, sozusagen. Und das haben wir auch erlebt, ziemlich blöde Situation. Und mittlerweile gibt es den sogenannten Time-Safe-Guard, der, wenn ein Knoten in das Netz rein will, sagt, hey, bist du gut genug synchronisiert, und wenn nicht, dann sagt er, du kommst hier gar nicht rein. Kurz noch ein Failure-Mod, den wir von Anfang an sehr gut bedacht hatten, und den wir von Anfang an gehandelt hatten, und das sind Messages of Death. Also das ist eine ERC-Nachricht, die, wenn du sie schickst, dann crasht sie den Server. Und jetzt kann man sich überlegen, okay, wenn ich die schicke, und alle Server wenden, die ja ungefähr gleichzeitig an so bin, 12 Millisekunden, dann wäre das blöd, wenn ich eine schicken kann, und deswegen, wir schicken diese Nachricht, der Server versucht, sie anzuwenden, und wenn er checkt, okay, die kann ich nicht anwenden, dann markiert er sie als Message of Death in seinem Log, und startet sich neu, und beim Neustart macht er dann ja ein Log-Replay, aber überspringt die Message of Death. Und so funktioniert das dann. Okay, das war alles, was ich auf Slides vorbereitet habe. Wir haben aber noch gute 20 Minuten Zeit, um Fragen zu beantworten, und generell einfach ein bisschen zu diskutieren. Zum einen zwei Sachen vorweg. Es gibt ein Feedback-Formular zu diesem Talk. Ich würde euch gerne bitten, dass ihr den QR-Code-Scan oder im Fahrplan dahin geht, oder später auf den Folien dahin geht, und mir Feedback gibt, wie dieser Vortrag war, damit ich in Zukunft bessere Vorträge halten kann. Zum anderen, es wundert euch vielleicht, wie man so eine Bridge eindrichtet. Die Anleitung benötigt einfach nur, dass Go installiert ist auf der Plattform, und dann sind es diese drei Befehle, die hier unten gelistet sind. Also man lädt sich das Paket runter, der Go-Get-Befilm kompliert das dann auch gleich, dann startet man sie, und dann kann man sich verbinden. Also das ist wirklich eine sehr einfache Installation, und die funktioniert sogar auf Debian Old Stable System noch. Also da haben wir extra Wert drauf gelegt. Das Bridge Paket hat eine einzige Dependency, das heißt, es ist auch sehr einfach in Distributionen aufnehmbar. Und die abschließende Frage, die ich stellen möchte, was mich von euch interessieren würde, ist, was haltet ihr davon? Würdet ihr Robust RC nutzen oder nicht? Oder Meinungen? Ja, bitte. Ihr hattet es zu Anfang? Ja. Das finden die meisten von uns einfach irgendwie clumsy. Also Jabber an sich ist für mich persönlich so auf dem absteigenden Ast. Also dadurch, dass jetzt große Hersteller wie Google und Facebook ihre Federation rausgenommen haben, wird es immer schwieriger Leute überhaupt bekommen, Jabber zu benutzen. Und diejenigen Leute, die Jabber benutzen, haben meistens Clients wie Bittlebee oder so, in denen dann Multi-User-Chat-Räume awkward at best sind. Also das Ganze Verhalten hat uns einfach nicht so gut gefallen. Ja, ich denke, das ist so der Hauptgrund. Das ist mehr so eine subjektive Sache. Genau. Also wir wollen halt einfach mal schauen, ist es möglich, IRC incrementell so zu verbessern, dass das, was uns am meisten stört, ist eigentlich weg ist? Außerdem ist es natürlich so, dass wir halt alle Leute, also alle Leute wissen von uns schon, wie man IRC verwendet. Es gibt quasi eine bestehende Nutzer-Base. Es ist quasi der Netzwerkeffekt, der schon da ist. Wir moveen nur den IRC-Channel auf einen anderen Server. Das ist für die meisten Leute transparent, sogar wenn man im DNS dann redirect einbaut, gar kein Problem. Und Sie haben als Upgrade die Möglichkeit, das Ganze auch robust zu machen, indem Sie einfach die Bridge installieren oder einen Plug-in in Ihren Kleintladen. Ja, war nur einfach eine subarchitektur, die dazu vielleicht ein bisschen äußern sich aber ist. Genau. Okay, klar. Man kann auf jeden Fall Parallelen ziehen. Ich meine, bei solchen Messen, schon jeder Art ist es natürlich trivial, die Parallel zu sehen, oder ich meine, es sind Server und die schicken irgendwie Messages. Auf der Ebene ist alles sehr ähnlich, aber ja, wie du erwähnt hast, die Punkte sind ganz klar die Ausfallsicherheit, dass man auch das Netz upgraden kann, ohne dass das irgendjemand mitbekommen. Solche Sachen sind das, was robust IRC als eine Implementation von IRC auszeichnend. Das stimmt. Es gab weitere Fragen, ja, bitte. Ja, sehr gute Frage. Also die Frage war, der Kleint verbindet sich am Anfang mit dem Lieder, woher weiß er dann, welche anderen Knoten noch in dem Netz sind, weil wenn der Lieder ausfällt, hat man ja ein Problem. Die Antwort darauf ist, der allererste Schritt ist, dass der Kleint einen SAV-Record im DNS-Resolft. Das heißt, das ist auch Voraussetzung. Also jede Robustession Implementation muss das machen. Und der SAV-Record zeigt auf alle Knoten, die aktuell in dem Netz sind. Jetzt ist es zusätzlich so, dass alle 30 Sekunden in der Ping Nachricht, wenn man das Netz an den Klein schickt, ist nicht nur ein Ping drin, sondern eben auch die Nutzinformationen, welche Server sind aktuell im Netz. Das heißt, wenn man den Knoten schnell aus dem Netz rausnehmen muss, weil er ausgefallen ist und man ersetzt ihn durch einen neuen, dann bekommt das alle bestehenden Kleins sehr schnell mit binnen 30 Sekunden. Und die neuen Kleins bekommen das dann mit, wenn sie das DNS resolven. Und dann hat man vielleicht einen kaputten Knoten im DNS, das ist kein Problem, solange man noch welche hat, die funktionieren. Das ist ein zwei-stufiges System zum Resolven. Weitere Fragen. Davon. Okay, die Frage war 1.000 ms pro Sekunde. Wo kommt dieser begrenzende Faktor her? Mehrerlei. Zum einen musst du Nachrichten verteilen. Also du musst für jede Nachricht halt diese Nachricht schicken auf die anderen Knoten. Das kannst du natürlich batchen, dann geht aber deine Latents hoch. Und mit der Latents, die wir zwischen den verschiedenen drei Knoten haben, also diese 12 bis 20 Millisekunden Internet-Latents, die man halt so hat, kannst du halt nur eine bestimmte Anzahl an Paketen schicken binnen einer Sekunde. Es sei denn, wie gesagt, du drehst die Bandbreite sehr hoch und batcht halt sehr viel. Also der Trade-Off ist immer, wie viele Nachricht wirst du schicken können und wie groß darf die Latents sein. Und zum anderen kommt noch dazu, dass RAV dann sich natürlich auch CPU braucht. Das ist irgendwann auch CPU am Ende. Und das Dritte, was noch erschwerend hinzukommt, ist, dass wir TLS vorschreiben. Das heißt, du kannst keinen robust ARC starten, ohne TLS zu benutzen. Und das hat natürlich auch einen gewissen Kostenpunkt. Also vor allem das Verteilen von Nachrichten auf die Clients, also Descenten von derselben Nachricht auf Tausende Verbindungen, kostet auch einen entsprechenden Krypto-Overhead. Und die Tests, die wir bislang gefahren haben, haben alle so funktioniert, dass du nicht gesagt hast, okay, ich habe jetzt einen Klein und der flattet einfach mal, sondern ich habe tausend Clients und die haben eine sinnvolle Anzahl an Nachricht pro Sekunde, damit das auch möglichst das Real-Life-Widerspiegel so ein Benchmark. Und dort ist es eben so, dass das einer der bottlenecks ist. Tatsächlich ist es so, dass die Krypto-Implementation von Go, da gab es einen Patch dafür, dass die schneller gemacht wird, aber der ist momentan, soweit ich weiß, noch nicht gemerged wegen Lizenzschwierigkeiten. Vielleicht passiert das noch irgendwann und dann kriegen wir wahrscheinlich mehr Messages pro Sekunde hin. Also das sind hauptsächlich Beschränkungen, die die Infrastruktur unter uns auf uns auferlegt und gegebenenfalls, wo wir halt sagen müssen, okay, wir nehmen höhere Latenz in Kauf, dafür kann das Netz mehr durchsatz. Sind die Messages zwischen den Servern Blocking, also ist darüber einer offen, oder ist das Pipeline? Die Frage ist, sind die Nachrichten zwischen den Servern Blocking oder sind die Pipeline? Es ist eine gute Detailfrage. Ich bin mir recht sicher, dass dadurch das Raft selbst als State Machine implementiert ist, ist das blockierend. Es kann immer nur ein Replication Request gesendet werden, aber die Nachrichten, die zu replizieren sind, die sich aufsammeln, während dieser eine aushängig ist, werden dann ge-batched in den nächsten. Also es ist in der Praxis kein zu großes Problem, aber vielleicht muss man da dann auf Pipeline gehen. Es gibt tatsächlich auch in der Raft Library, die wir haben, eine entsprechende FastPath für Replication über ein Pipeline-Protokoll. Den haben wir momentan aber absichtlich nicht genommen, weil unsere Hoffnung ist, dass die Go-Standard-Net-HTTP-Library eben Pipeline auf HTP-Ebene umsetzt oder uns erlaubt. Aber da kann man vielleicht sich nochmal genauer befassen. Okay, da oben nochmal? Okay. Die Anmerkung war, dass ich gesagt hätte, dass die Nachrichten sofort gelöscht werden, wenn man sie schickt. Aber was passiert dann, wenn die Kleins ein bisschen hinterher hängen? Der Punkt ist, da war ich wahrscheinlich nicht klar genug, die Nachrichten können sofort gelöscht werden, aber werden erst nach einem Zeitfenster, was konfigurierbar ist, gelöscht. Im Moment sind das sieben Tage. Das ist natürlich viel zu hoch. Du kannst auch sagen, okay, das könntest du nach fünf Minuten machen, weil wenn ein Klein fünf Minuten draus ist, dann geht er wahrscheinlich selber in den Ping-Time-Out. Aber wir haben es erst mal gesagt, okay, wir machen das konservativ mit sieben Tagen und dann schauen wir mal, wie wir das drücken können. Die Idee dahinter ist, dass man vielleicht auch noch ein anderes interessantes Feature einbauen könnte. Was nämlich ist, dass du eine Session wieder aufnehmen kannst nach einer Weile. Also, dass du sagen könntest, hey, ich schließe jetzt meinen Klein für heute, und dann kriegst du noch mal alles geschickt und dein Klein macht quasi wie weiter. Also, dann hättest du einen Fenster, welches eben genau von diesem Fenster abhängt. Also, wenn der Server eben zwei Tage Nachrichten vorhält, könntest du zwei Tage lang die Session wieder aufnehmen. Genau, dann wäre ein Bouncer komplett hinfällig und dieses reingefrickelte Backlock wieder aufnehmen, könnte man vielleicht auch ein bisschen eleganter lösen. Da müsste man halt mal schauen. Also, das wäre auch eine interessante Richtung, in die man das Projekt noch ein bisschen führen kann. Aber da haben wir im Moment noch keine Arbeit dran gemacht. Haben es nur immer ein bisschen im Hinterkopf behalten für alles. Okay, weitere Fragen? Ja, bitte. Also, die Frage war, wie flexibel ist es, dass man Server hinzufügen und entfernen kann, im Falle eines Ausfalls? Die Antwort dazu ist, das ist auch in dem Admin Guide dokumentiert. Man kann einen Server aus dem Netz rausnehmen, solange noch einer der anderen Server verfügbar ist. Also, man kann dem Lieder sagen, hey, diese eine Knoten bitte jetzt nicht mehr, der ist kaputt. Und man kann stattdessen dann auch direkt einen neuen Knoten reintun. Das Einzige, was man eben machen muss, das könnte man aber, und das habe ich mir auch überlegt, das mal zu basteln, automatisieren, sodass man sagt, okay, wenn mein Netz ausfällt, also wenn mein Monitoring-System bemerkt, hey, die Kapazität ist auf einmal nur noch zwei Knoten und nicht mehr drei Knoten, dann könnte er ja ein Skrips starten, welches dann automatisch bei, keine Ahnung, Amazon oder Google Cloud Engine eine neue VM hochfährt, den Robustasy-Knoten startet und ins Netz holt. Das kann man also durchaus machen. Und der zweite Teil der Frage war ja, wie kann man manuell passieren? Also da müsstest du dich dann kurz schließen mit den Admins von den anderen Netzen und fragen, hey, ihr habt irgendwie fünf und könnt ihr mir da vielleicht einleihen? Das ginge, ja, genau. Okay, da ganz oben. Die Frage war, ist es möglich, die Anzahl an Knoten im Netz zu verändern, ohne das Netz neu zu starten? Die Antwort ist ja. Sofern du dich in der Range bewegst, die okay ist. Also ich kann zum Beispiel in einem Netz, um das zu reduzieren, sonst friert es ein. Aber in dem Rahmen kann ich das beliebig hoch- und drunter skalieren, das stimmt. Ja, vor? Was der Idee ging, hat das nämlich, dass er sich mal an das Knoten leihen könnte. Könnte man das ja fast so bauen, dass man mit den anderen sich abstreht und dann auch mal Knoten leihen könnte, wenn man jetzt zum Beispiel in den Internet mit Peering, dass man dann sich das da wirklich über das Knoten von anderen Netzen Knoten leihen könnte, solange er ausfällig über sind die Knoten klauen. Das war quasi nicht mehr abstellbar. Scary. Die Anmerkung war, dass man das tatsächlich machen könnte, wie eben angemerkt mit dem Knoten klauen aus anderen Netzen und dann wäre das nicht mehr tot zu kriegen. Und liefe für immer, ja, könnte man machen. Wenn du Lust drauf hast, kann man da gerne darüber reden. Ich finde, ja, also die Tools sind auf jeden Fall da. Man könnte das auf jeden Fall machen. Man könnte das tatsächlich notwendig ist. Also zum einen die Ausfallsicherheit vom aktuellen Netz ist schon unglaublich hoch eigentlich, je nachdem, wie viel Knoten man es fährt. Man muss bedenken, dass der Worst Case, also wenn man wirklich einen Ausfall hat, ist ein Netzplatt. Das ist dann so schlecht, wie das, was wir momentan haben. Die Frage ist überhaupt, hast du erstmal genug robuste Netze, die betrieben werden von Leuten, die bei sowas mitmachen würden. Aber dann ist das eine interessante Spielerei. Die Frage war, was spricht dagegen, das über Hidden Services laufen zu lassen. Ich muss kurz überlegen, aber ich glaube, mir fällt nichts ein, was per se dagegen spricht, außer dass deine Latente sehr hoch sein wird. Das Problem ist ein bisschen, dass du, das Netz muss halt die ganze Zeit in Health Checking machen. Also der Lieder muss halt die ganze Zeit wissen, sind meine anderen Knoten noch da. Und die anderen Knoten schauen auch, habe ich mit dem Lieder in, habe ich schon zu lange nichts mehr von dem Lieder gehört und dann passiert irgendwas. Das ist das, was du da einstellen musst. Und diese momentan sowas wie eine Sekunde oder so. Und der Punkt ist, wenn du die zu sehr hoch drehen musst, weil zum Beispiel dein Tor Hidden Service, sagen wir, 10 Sekunden mal braucht, um zu antworten. Dann kommst du gefährlich nahe an den Punkt, wo das Netz nicht mehr schnell genug konvergieren kann, dass die Kleins nichts merken. Also du hast zumindest mal dann sowas wie einen 10 Sekunden Ausfall in dem Leute, wenn sie Nachrichten schreiben, dass die nicht sofort ankommen. Und wenn die Kleins hoch wird, dann fliegen die Leute raus, weil die Kleins denken, oh, ich kriege keine Antwort auf mein Ping mehr als ein Ping Timeout. Das ist das Einzige, was mir einfällt, was da dagegen spreche. Okay, noch weitere Folgen. Sieht da oben, ja? Das war so eine Bewendung gemacht. Das University ist etwas mit dem, was man da braucht. Ich bin noch so nicht schlimmer, als bei einem Fragmentier, was ich unterkomme. Das ist eine gute Anmerkung. Die Anmerkung war, ich habe gerade den Vergleich gemacht, dass das schlimmste was passieren kann, ein Netzplatt sei, und das war ein guter Anmerkungen. Das war ein guter Anmerkungen. Das war ein guter Anmerkungen. Ich habe gerade den Vergleich gemacht, dass das Schlimmste was passieren kann. Ein Netzplatt sei, wenn es nicht so gut ist, dann wird es nicht so gut. Das Schlimmste, was passieren kann, kann ja ein Netzplatt sein. Aber bei dem aktuellen IAC, können die Leute, die auf demselben Server sind, immerhin noch kommunizieren. Das stimmt. Muss man abschätzen, was jetzt schlimmer ist. Wir haben die Entscheidung gemacht, wir wollen ein konsistenten IAC-Verlauf haben. Bei uns ist es besser, wenn es einfriert, als wenn es noch verfügbar ist. Aber dann am Ende, Leute will durcheinander geredet haben noch weiterer Anmerkungen oder Fragen. Ich will noch mal auf die Frage zurückkommen. Würdet ihr das nutzen? Wer sieht da keinen Grund, das nicht zu benutzen? Cool. Wer hat was dagegen, ist zu kompliziert? Oder habe ich keinen Anwendungsfall für? Eins, zwei, okay. Darf ich fragen, ist es zu kompliziert? Oder einfach egal? Netzwerkmanagement, was meinst du damit genau? Okay. Also Nick registration haben wir. Wir haben Servicesanbindung. K-Lines sind ein bisschen schwierig. Weil du hast auf einmal mehrere Knoten über die Leute reinkommen können und müsstest dann halt quasi auf die ... Ja, weil momentan wird halt nicht hochkommuniziert, wenn du auf einer Bridge dich verbunden hast, sieht halt der Robust RC Server nur die IP von der Bridge, die das weiterleitet. Und die Bridge setzt zwar einen X forwarded vor und so, das heißt, man könnte das auswerten, aber die Bridge ist halt im Benutzerkontrolle. Ein bisschen, ja. Ist immer schwierig, oder? Aber wie machen das aktuelle IAC-Netze im besten Fall Bann, im Normalfall aussetzen, einfach schauen, dass es irgendwie Flat Protection Flags in den Channels gibt, schauen, dass Channel-Auner manuell die Leute kicken oder kick-Bann. Ab viel anders läuft es bei uns auch nicht. Aber das ist natürlich grundsätzlich ein Problem mit IAC, das stimmt. Okay. Cool. Wenn euch noch irgendwas einfällt, ich bin noch auf der Veranstaltung, ansonsten viel Spaß im Robust RC.