Aber fangen wir von vorne an.
2010 arbeitete ich bei Google Wave, wo wir versuchten, gemeinsam bearbeitbare Bereiche zu erstellen, um E-Mails, Google Docks, Foren, Instant Messaging und viele andere Single-Tasking-Anwendungen zu ersetzen. Unter meinen Werkzeugen gefällt mir besonders die Allzweckumgebung, nirgendwo anders als in Wave wurde die Funktionalität zu diesem Zeitpunkt nicht formuliert. Im Gegensatz zu den meisten anderen Tools erfordert die Allzweckumgebung keinen eigenen Workflow, sodass Sie damit Urlaub planen, Wikis erstellen, Brettspiele mit Freunden spielen, Arbeitstreffen planen und vieles mehr können.
Intern arbeitet die Wave-Co-Bearbeitung über eine Operational Transform (OT) hinaus und wurde zu dieser Zeit tagelang verwendet: Unser Algorithmus basierte auf einem Jupiter-Vortrag von 1995. Für jedes Dokument führt der Algorithmus eine separate chronologische Liste der Änderungen, "Typ H an Position 0", "Typ i an Position 1" usw. In den meisten Fällen ändern Benutzer die neueste Version des Dokuments, und das Protokoll sieht aus wie eine Folge von Änderungen. Beim Co-Authoring müssen wir jedoch gleichzeitig Änderungen vornehmen.
In diesem Fall wird die erste Bearbeitung, die auf den Server gelangt, wie gewohnt aufgezeichnet, und die nächste, wenn sie sich als veraltet herausstellt, wird mit dem Ereignisprotokoll verglichen, um die ursprünglichen Ziele des Benutzers zu ermitteln. (Meistens kommt es darauf an, die Zeichenpositionen zu aktualisieren.) Dann fügt der Algorithmus, angeblich "dies ist das vom Benutzer gewünschte Ergebnis", eine neue Operation hinzu, wie z. B. Git-Rebase in Echtzeit.
Mit der Schließung von Google Wave habe ich das OT-Modell auf ShareJS portiert . Zu dieser Zeit fühlte sich Node neu und seltsam an, und wenn ich mich richtig erinnere, habe ich ShareJS gestartet, noch bevor npm veröffentlicht wurde. Ein einfacher Mitherausgeber benötigte nur tausend Codezeilen, und in der Demo habe ich das Dokument im Browser und in der Anwendung mitbearbeitet.
OT ist im Kern eine verschönerte for () - Schleifemit mehreren Hilfefunktionen zum Aktualisieren des Zeichenversatzes. In der Praxis ist OT einfach, leicht zu verstehen, schnell in Betrieb zu nehmen und funktioniert hervorragend. (10-100.000 Operationen pro Sekunde in nicht optimiertem Javascript, 1-20 Millionen in optimiertem C ). Das Ereignisprotokoll kann mehr Speicher als üblich belegen, kann jedoch bei Bedarf gekürzt werden, obwohl es nicht funktioniert, um besonders alte Änderungen zu kombinieren. Für die globale Zuweisung von Vorgängen ist ein zentraler Server erforderlich, aber die meisten Systeme verfügen bereits über einen solchen Server oder eine solche Datenbank, nicht wahr?
Zentralisierte Server
Ein wesentliches OT-Problem ist die Abhängigkeit von einem zentralen Server. Haben Sie sich jemals gefragt, warum Sie beim Zulassen des Zugriffs auf ein Google Text & Tabellen-Dokument über soziale Netzwerke mit der seltsamen Meldung "Dieses Dokument ist überladen und seine Bearbeitung ist deaktiviert" konfrontiert wurden? Der Grund (meiner Meinung nach) ist folgender: Wenn Sie ein Dokument öffnen, wird ein bestimmter Server ausgewählt, um alle Änderungen zu verarbeiten, und wenn sich eine Menge Benutzer auf das Dokument stürzt, muss das System sehr bemüht sein, den Server nicht zu überlasten.
Es gibt verschiedene Möglichkeiten, um dieses Problem zu umgehen: Zusätzlich zum Sharding von Unterdokumenten (wie in Google Docks) können Sie Änderungen über eine Wiederholungsschleife unter Umgehung von Datenbanktransaktionen vornehmen, sodass das Serialisierungsproblem von derselben Datenbank übernommen wird (so funktioniert Firepad)und ShareDB ).
OT ist jedoch nicht perfekt. Wir wollten E-Mail durch Wave ersetzen, aber Mail unterstützt das Zusammenführen, eine Buchstabenkette kann sich über viele Unternehmen erstrecken und alles funktioniert irgendwie erfolgreich. Im Gegensatz zu Facebook-Nachrichten können E-Mails außerdem an Unternehmen gesendet werden, die in der Spalte „Kopieren“ aufgeführt sind. Wenn Wave E-Mails ersetzen soll, muss es auch die Funktion zum Senden von Nachrichten ohne Zugriff auf das externe Netzwerk haben, z. B. wenn ich am nächsten Tisch einen Brief an meinen Kollegen sende. Aber wie können Sie all dies zusätzlich zu OT implementieren? Wir haben es irgendwie geschafft, einen solchen Prozess einzurichten, aber er stellte sich als zu komplex und voller Fehler heraus: Wir haben ein Diagramm erstellt, in dem jedes Wave-Protokoll einen Baum von Wave-Servern eingerichtet hat, um Vorgänge in beide Richtungen zu übertragen, aber nie vollständig funktioniert hat. Vor etwas weniger als zehn Jahren hielt ich auf dem Wave Protocol Summit einen Vortrag über das Erstellen und Konfigurieren eines solchen Netzwerks. Trotz aller Vorbereitungen und aller vorläufigen Überprüfungen schlug die strikte Einhaltung jedes Schritts in der Präsentation selbst fehl, und das Netzwerk funktionierte nie. Ich weiß immer noch nicht, warum das passiert ist, aber was auch immer die Fehler waren, sie wurden in der öffentlichen Version kaum jemals behoben, es war alles zu schwierig.
Start CRTD
Wie ich bereits erwähnte, wurde der Hauptwellenalgorithmus vor ziemlich langer Zeit, 1995, entwickelt, und ich erinnere mich nicht einmal daran, dass ich zu dieser Zeit das Internet zu Hause hatte. Seitdem haben Forscher unermüdlich daran gearbeitet, die Leistung von OT zu verbessern, und verwenden in der vielversprechendsten Richtung CRTD (Conflict-Free Replicated Datentypen). Dieser Ansatz unterscheidet sich etwas von den üblichen und ermöglicht es Ihnen, Dateien in Echtzeit zu bearbeiten, ohne dass ein zentraler Server erforderlich ist. Martins Präsentation beschreibt ihre Arbeit besser als ich sie beschreiben könnte, also werde ich die Details überspringen.
Die Leute haben jahrelang nach meiner Meinung zu CRTD gefragt, und meine Antwort klingt immer so:
Sie sind ordentlich und ich bin froh, dass die Leute daran arbeiten:
- . . , 100 Delta-CRTD . (: B4.)
- - CRTD , , 100 automerge master 83 . , , , , . ( automerge 1.1 .)
- Seit Jahren fehlt die in OT vorhandene Funktionalität in CRDT. Beispielsweise hat noch niemand eine CRDT mit Unterstützung für / object move / (Übertragung von etwas von einem Teil des JSON-Baums zu einem anderen) erstellt. Solche Verfahren sind für Anwendungen wie Workflowy erforderlich, und OT leistet damit hervorragende Arbeit .
- CRDTs sind an und für sich komplex und schwer zu überlegen.
- Sie haben höchstwahrscheinlich bereits einen zentralen Server / eine zentrale Datenbank.
Trotz all meiner Kritik ignorierte ich die CRDT, ignorierte dabei jedoch die einschlägige Literatur und zu meiner Überraschung vermisste ich die leise und nicht wahrnehmbare Verbesserung der CRDT. In seiner Präsentation (die Ihre Aufmerksamkeit mehr als wert ist) spricht Martin die wichtigsten Punkte an:
- : CRDT (Automerge / RGA Y.js / YATA) [log(n)] . ( .)
- : - , 54- . automerge , Y.js, Y.js 100 160 3 . .
- : , .
- : , CRDT OT. , automerge .
Die Gründe für die Geschwindigkeit haben mich nicht überzeugt. Um die Idee zu testen, habe ich CRDT in Rust mithilfe eines B-Baums mithilfe von Ideen von automerge unabhängig implementiert und getestet . Es fehlte an Funktionalität (Löschen von Zeichen, Konflikte), aber es konnte 6 Millionen Änderungen pro Sekunde verarbeiten . (Jede Iteration hat 2.000 Änderungen an einem leeren Dokument durch zwei abwechselnde Benutzer vorgenommen, was insgesamt 330 Mikrosekunden oder 6,06 Millionen Änderungen pro Sekunde dauerte.) CRDTs haben sich also wirklich verbessert, und der Geschwindigkeitsunterschied zwischen ihnen und OT ist jetzt noch geringer als zwischen Rust und Javascript.
Alle diese Korrekturen befinden sich schon lange im Abschnitt "In Kürze verfügbar" der Automerge-Leistungsbranche, aber schließlich ist Automerge nicht die einzige CRDT. Y.js erweist sich als würdig und umgeht in seinen Tests leicht die aktuelle Version von automerge. Es fehlt die Funktionalität, die mich interessiert, aber im Allgemeinen ist es sicherlich einfacher, die vorhandene Implementierung zu reparieren, als einen neuen Algorithmus zu erstellen.
Die Zukunft erfinden
Ich bin sehr besorgt über Fortschritte. Was wäre es seltsam, in hundert Jahren nicht mehr benutzt zu werden? Natürlich werden wir in Echtzeit bearbeiten, aber ich bin mir nicht mehr sicher, ob es durch OT implementiert wird und welche Arbeit ich in dieser Hinsicht geleistet habe, was mich nur traurig machen kann.
JSON und REST sind heutzutage allgegenwärtig. Nehmen wir an, in 15 Jahren wird auch die Echtzeit-Co-Bearbeitung allgegenwärtig sein. Was wäre das JSON-Gegenstück in Bezug auf Co-Authoring für eine einfache Übertragung auf Ihr Projekt? In dieser glorreichen Zukunft werden wir eine qualitativ hochwertige Implementierung von CRDT benötigen, da OT für einige Anwendungen einfach nicht funktioniert, es nicht funktioniert, eine Echtzeitversion von GIt oder eine einfache Variante von Google Wave zu erstellen. Aber wenn wir bereits eine gute CRDT-Implementierung haben, brauchen wir auch eine OT-Implementierung? Ich denke nicht, denn es wird nicht schwierig sein, alle Funktionen von OT auf CRDT zu übertragen (einschließlich übrigens Schnittoperationen), während das Gegenteil nicht der Fall ist. Kluge Leute stimmen mir nicht zu, aber meiner Meinung nach haben wir eine gute, schnelle CRDT für jede Sprache.Die Notwendigkeit für OT wird vollständig verschwinden.
Einer der Vorteile von OT besteht darin, dass es - wie die meisten modernen Anwendungen - problemlos in zentralisierten Systemen implementiert werden kann, verteilte Algorithmen jedoch ebenso gut implementiert sind. (Schauen Sie sich zum Beispiel Github an.) Meiner Meinung nach ist eine qualitativ hochwertige CRDT auf wasm schneller als eine OT-Implementierung in JS. Wenn Sie sich nur mit zentralisierten Systemen befassen, denken Sie daran: OT-Einschränkungen führten dazu, dass Google Skalierungsprobleme in Google Text & Tabellen hatte.
Daher scheint es mir jetzt an der Zeit zu sein, auf eine kleine und schnelle CRDT umzusteigen. Zum größten Teil ist die akademische Arbeit bereits erledigt, die Frage bleibt für erfolgreiche Implementierungen.
Was weiter
Ich beschäftige mich immer weniger mit der Welt der zentralisierten Anwendungen. Anwendungen interagieren mit meinen Daten auf meinen Geräten, und es wäre höchste Zeit, dass diese Anwendungen entsprechend auf solche Verbindungen reagieren. Ich möchte, dass mein Laptop und mein Telefon Daten über WLAN untereinander übertragen können und nicht durch Hochladen meiner Daten auf Server in einem anderen Land. Vor allem, wenn diese Server von den um meine Aufmerksamkeit konkurrierenden Anzeigenriesen finanziert werden .
Wenn ich ein Dokument in Google Text & Tabellen bearbeite, bittet mein Computer Google um Erlaubnis zum Bearbeiten der Datei (denn wenn der Server aus irgendeinem Grund Nein sagt, verliere ich alle meine Änderungen). Zum Vergleich, wenn
git pushich in Github bin, benachrichtige ich nurGithub über Änderungen in meinem Code. Mein Repository gehört immer noch mir, ebenso wie alle Daten und Hardware, auf denen es sich befindet, und so sollten meine Anwendungen funktionieren. Dank Leuten wie Martin wissen wir jetzt, wie man gute CRDTs macht. Bevor jedoch Local-First-Anwendungen als Grundlage akzeptiert werden, müssen mehr Codezeilen geschrieben werden.
Alles in allem ist es Zeit, sich von der operativen Transformation zu verabschieden. Wir hatten eine großartige Zeit zusammen, von allem, was ich geschrieben habe, war der operative Transformationscode einer der schwierigsten und interessantesten. Du bist schlau und erstaunlich, OT, aber CRDT kann etwas tun, was du niemals kannst. Und ich brauche CRDT. Ich denke, mit ein paar guten Implementierungen können wir etwas ganz Besonderes erreichen.
Ich trauere um all die Arbeit, die ich im Laufe der Jahre in OT gesteckt habe, aber OT passt nicht mehr in meine Zukunftsvision. Mit CRDT können wir Wave einfacher und schneller neu erstellen und Apps erstellen, die Benutzer eher wie digitale Bürger als wie digitale Bauern behandeln. Und das ist wichtig.
Es ist Zeit zu schaffen.