Abstrakte Wikipedia/Erste Auswertungsmaschine
Abstrakte Wikipedia |
---|
(Diskussion) |
Allgemein |
Entwicklungsplan |
|
Anmerkungen, Entwürfe, Diskussionen |
|
Beispiele und Modelle |
Datenwerkzeuge |
Historisch |
- Wo und wie sollte unsere erste Auswertungsmaschine eingesetzt werden und wie sollte sie aufgebaut sein?
Letztendlich zielt Wikifunctions darauf ab, ein gesundes Ökosystem interoperabler Auswertungsmaschinen zu haben. Wir werden eine wohldefinierte Beschreibung dessen liefern, was eine Auswertungsmaschine tun MUSS und SOLLTE, und wir hoffen, dass es in vielen verschiedenen Kontexten laufende Auswertungsmaschinen geben wird — von kleinen eingebetteten Auswertungsmaschinen, die in nativen Apps laufen und bestimmte Funktionen nutzen wollen, über Auswertungsmaschinen, die als mobile Apps oder lokale Server laufen, bis hin zu leistungsstarken Auswertungsmaschinen, die in der Cloud oder in einem verteilten Peer-to-Peer-Netzwerk laufen. Die Wikimedia Foundation wird eine oder mehrere Auswertungsmaschinen betreiben müssen, um die Funktionalitäten bereitzustellen, auf die die Wikimedia-Projekte angewiesen sein werden. Über diese und viele andere werden wir zu einem anderen Zeitpunkt nachdenken.
Für den Moment müssen wir herausfinden, wo unsere allererste Auswertungsmaschine angesiedelt werden soll. Während es großartig wäre, irgendwann alle diese Funktionen zu implementieren, müssen wir unsere Ressourcen realistisch einschätzen und sollten uns zunächst auf nur eine dieser Funktionen konzentrieren. Es scheinen drei Hauptmöglichkeiten für die erste Implementierung in Frage zu kommen:
- eingebettet in die WikiLambda-Erweiterung,
- ein eigenständiger Dienst,
- wir werten alles im Browser des Lesers aus.
Wir müssen dies entscheiden, bevor wir mit der Arbeit an Phase δ beginnen können, in der wir diese Auswertungsmaschine implementieren werden. Hier diskutieren wir Vor- und Nachteile der drei Hauptansätze und erörtern auch mögliche Optionen innerhalb der Ansätze.
Hauptoptionen
WikiLambda-Erweiterung
Die WikiLambda-Erweiterung selbst stellt nicht nur die Wiki-Erweiterung zur Verfügung, um die ZObjekte im Wiki zu bearbeiten und zu pflegen, sondern bettet auch eine Auswertungsmaschine ein. Die Erweiterung macht die Auswertungsmaschine über eine API sowohl der Welt als auch ihren internen Verwendungen zugänglich.
Pros:
- Das Bereitstellen der WikiLambda-Erweiterung ist einfach, da wir keinen sekundären Stack für die Auswertungsmaschine bereitstellen müssen (selbst wenn wir diesen Weg jetzt nicht gehen, wäre es sinnvoll, eine eingebettete Auswertungsmaschine in der Erweiterung zu haben, um ein einfaches Bereitstellen zu ermöglichen, was auch dazu beiträgt, dass Leute leichter zur Codebasis beitragen).
Wir haben bereits mit der Erstellung von Objekten mit bestimmten Fähigkeiten im PHP-Code begonnen und können darauf weiter aufbauen. - Es ist der mit Abstand schnellste und einfachste Weg, um auf alle anderen ZObjekte zuzugreifen, die man zur Auswertung eines bestimmten Aufrufs benötigen würde.
- Da wir möchten, dass die Erweiterung auf im Wiki vorhandene Funktionen zurückgreift, um einige ihrer Ergebnisse zur Verfügung zu stellen, ist es bei weitem die bequemste Lösung mit dem geringsten Overhead, sie sofort zur Hand zu haben.
- Kann alles wiederverwenden, was bereits in MediaWiki vorhanden ist, um eine API bereitzustellen, z. B. Authentifizierung, Token usw.
Kontras:
- Unter dem Gesichtspunkt der Sicherheit ist dies ein hohes Risiko, da dies im Einsatz auf dem Hauptcluster laufen würde. Sollte es jemandem gelingen, aus dem eingebetteten System auszubrechen, hätte er direkten Zugriff auf die Produktionsdatenbanken, da das Wiki Zugriff auf die entsprechenden Zugangsdaten hat.
- Aus der Sicht der Sicherheit kann es auch ein Angriffsvektor für eine absichtliche oder sogar unabsichtliche DOS-Attacke sein, da aufwendige Auswertungen ausgeführt werden und Produktionsinstanzen von MediaWiki blockieren.
- Es ist schwierig, die Auswertung innerhalb der Erweiterung in eine Sandbox zu packen, da alles im gleichen PHP-Code liegt.
- Es müssen Überwachungs-, Zeit- und Speicherbeschränkungen innerhalb von MediaWiki implementiert werden.
Eigenständiger Dienst
Wir entwickeln einen eigenständigen Dienst, der über REST aufgerufen werden kann, um Funktionsaufrufe auszuwerten. Der Dienst wird sowohl von externen als auch von internen Clients genutzt.
Pros:
- Kann alles von Grund auf neu entwickeln. Keine Einschränkungen durch MediaWiki, der Dienst kann so schlank sein, wie es der Stack, auf dem wir aufbauen, erlaubt.
- Der Dienst kann als Ganzes in eine Sandbox gestellt, überwacht und mit einem Zeit- und Speicherbudget versehen werden.
- Kann einen ganzheitlichen und einheitlichen Ansatz für das Caching innerhalb der Auswertungsmaschine aufbauen.
- Kann leicht skaliert werden, indem mehr Dienste in mehr Boxen ausgeführt werden. Erlaubt sogar eine Architektur, in der ein einzelner Serveraufruf entscheiden kann, andere Server aufzurufen und so Teile des Aufrufs zu parallelisieren, was in den anderen beiden hier besprochenen Ansätzen nur schwer zu implementieren ist.
Kontras:
- Muss alles von Grund auf neu entwickeln. Viel Potenzial für Verschwendung hinsichtlich Implementierungssprache, Stack und Bereitstellungsansatz.
- Bedeutet auch viel mehr Möglichkeiten, neue Fehler einzuführen.
- Es muss herausgefunden werden, wie ein neuer produktionsfähiger Dienst in Betrieb genommen werden kann (kann aber bis dahin auf WMFCloud oder einer anderen Infrastruktur laufen).
- Man muss viel aus der DB lesen, daher ist es wichtig, das schnell zu können. Es handelt sich jedoch um einen Nur-Lese-Zugriff.
- Verursacht Kosten für jeden, der die Erweiterung einsetzt und daran arbeiten möchte, da er den Dienst ebenfalls einrichten muss.
Browser
Die Funktionsauswertungen müssen nicht zwingend auf der Wikimedia-Infrastruktur laufen, sondern können alle in den Browsern der Benutzer laufen.
Pros:
- Einfach zu implementieren.
- Kaum nachteilige Auswirkungen auf die Infrastruktur.
- Es ist nicht notwendig, die Ressourcen für die Leser einzuschränken, da es sich um deren eigene Ressourcen handelt.
Kontras:
- Sehr vorsichtig sein, um keine Angriffe auf Leser zuzulassen.
- Wird wahrscheinlich zu einer schleppenden Wiedergabe bei vielen Clients führen, was dazu führt, dass dies nur Benutzern mit besserer Ausstattung zugänglich ist, was unseren Zielen zuwiderläuft.
- Die Auswertungsmaschine muss unter Umständen viel aus der DB lesen, mit langen Round-Trip-Zeiten, da der Browser auf das Wiki zugreifen muss.
- Es gibt keine Möglichkeit, den Code serverseitig aufzurufen (es sei denn, wir entwickeln ihn parallel auf, sagen wir, Node, so dass er im Browser und im Backend laufen kann, aber das bedeutet im Grunde die Entwicklung und Pflege von zwei Lösungen, auch wenn sie sich einen Teil des Codes teilen).
- Die Möglichkeiten für das Caching sind stark eingeschränkt, vor allem in Bezug auf die Benutzer, bei denen große Vorteile zu erwarten sind.
- Nicht suchmaschinenfreundlich.
- Kann nicht weiter verarbeitet werden (wie
{{Str left|{{#lambda:xxx}}|123}}
).
Architektur für den eigenständigen Dienst
Wir neigen derzeit dazu, die erste Auswertungsmaschine als eigenständigen Dienst zu entwickeln. Die Bereitstellung als Teil von MediaWiki wird als mit zu vielen potenziellen Sicherheits- und Leistungsrisiken behaftet angesehen, ebenso wie die Ausführung im Browser. Wir hoffen, die Entscheidung über den Browser zu einem späteren Zeitpunkt zu revidieren.
Idealerweise kann die Auswertungsmaschine viele Male hochgefahren und als zustandsloser Dienst orchestriert werden. Der Dienst ist 'read-only', modulo Caching und Monitoring.
Die Auswertungsmaschine stellt eine API über HTTP bereit, die ein ZObjekt als Eingabe erhält und ein ZObjekt als Ausgabe zurückgibt. Das zurückgegebene ZObjekt ist das Ergebnis der Auswertung des eingehenden ZObjekts, bis ein Fixpunkt erreicht ist. Dies ist vor allem für Funktionsaufrufe interessant.
Der Dienst wird von der Zwischenspeicherung drastisch profitieren. Es gibt (mindestens) drei Ebenen des Caching bezüglich der Auswertungsmaschine:
- HTTP-Cache: Zwischenspeicherung des gesamten API-Aufrufs an die Auswertungsmaschine auf der Ebene der HTTP-Aufrufe. Wenn der gleiche Aufruf erfolgt, wird das gleiche Ergebnis zurückgegeben.
- Zwischenergebnis-Cache: Wenn die Auswertungsmaschine einen Funktionsaufruf auswertet, sollte sie prüfen, ob sie den angegebenen Funktionsaufruf in ihrem Cache hat, und stattdessen dieses Ergebnis zurückgeben. Dies hätte den Vorteil, dass alle parallel laufenden Auswertungsmaschinen den gleichen Cache nutzen könnten.
- Inhaltscache: Referenzen werden im Wiki nachgeschlagen. Dies könnte auch aus dem Wiki gepusht werden, insbesondere wenn wir einen gemeinsamen Cache haben. Dieser kann Teil des Zwischenergebnis-Caches sein.
Schließlich müssen wir REST-Aufrufe für andere Wikimedia- und externe Dienste (z.B. Wikidata, Wetterbericht, etc.) sowie das Ändern von Dingen wie der aktuellen Zeit oder von Zufallswerten ermöglichen.
Was ist mit Wettlaufbedingungen, wenn Funktionen bearbeitet werden, während eine Funktion ausgeführt wird?
Würden Auswertungsmaschinen homogen oder vielfältig sein? D.h. könnte es eine Auswertungsmaschine geben, die eine TPU verwenden kann, und andere, die das nicht tun, und wie leiten wir die Abfragen weiter? Eine einfache Idee: Müssen alle Auswertungsmaschinen alle Programmiersprachen verstehen, oder können wir sie leichter machen, indem wir dedizierte Auswertungsmaschinen haben, von denen einige Python, andere JavaScript usw. ausführen können?
Einige zu berücksichtigende Technologien:
Entwurf für Schritte zur ersten Auswertungsmaschine
Die Reihenfolge der folgenden Schritte ist nicht unbedingt wie angegeben. Built-Ins kommen zuerst, aber die meisten anderen sind eher unabhängig voneinander.
Built-ins
Siehe phabricator:T260321.
- Sehr kleine API — vielleicht sogar nur mit einer einzigen Auswertungsmethode beginnen und das war's.
- Kein Caching.
- Implementiert einige (oder alle) der ersten Gruppe von Built-Ins, wie durch phabricator:T261474 beschrieben.
- Alles, was kein Funktionsaufruf ist, wird so zurückgegeben, wie es ist (eventuell kanonisiert).
Beispiel:"Test"
wird zu"Test"
ausgewertet. - Alles, was ein Funktionsaufruf ist, wird bis zum Fixpunkt ausgewertet.
Beispiel:if(true, "Yes", "No")
wird zu"Yes"
ausgewertet. - Wenn die Argumente Funktionsaufrufe sind, werden sie auch ausgewertet, bis zum Fixpunkt.
Beispiel:head(tail(["1", "2", "3"]))
wird zu"2"
ausgewertet.
Beachte, dass dies alles bereits voraussetzt, dass Verweise auf das Wiki aufgelöst werden.
Die Funktion head
ist eine Funktion im Wiki und muss nachgeschlagen werden, ihre Implementierungen müssen gesammelt werden (wir haben im Moment nur eingebaute Implementierungen), eine Implementierung muss ausgewählt und ausgewertet werden.
Die erste Version der Auswahl einer Implementierung ist die Auswahl irgendeiner. Dies muss später noch verfeinert werden.
Sandboxing und Überwachung
Implementierung aller notwendigen Schritte zum Sandboxing und zur Überwachung der Auswertungsmaschinen (Phabricator:T261470).
Vieles davon sollte über Kubernetes verfügbar sein. Aber wir würden wahrscheinlich auch gerne Statistiken führen, wie "wie oft wurde eine Funktion aufgerufen?", "wie oft hatten wir Cache-Fehlschläge" usw.
Zwischencaching
Caching von Zwischenergebnissen einführen.
Vor der Auswertung eines Funktionsaufrufs prüfen, ob dieser im Cache ist und stattdessen diesen wiedergeben.
Es ermöglichen, dass der Cache zurückgesetzt wird.
Editieren leert den Cache
Das Editieren eines bestehenden ZObjekts leert den ganzen Cache. Wir werden dieses Verhalten langsam verbessern. (Idealerweise werden bei einer Bearbeitung nur die Caches geleert, die geleert werden müssen, aber das wird schnell komplex. Dazu kommen wir später.)
Erfordert Zwischencaching.
Zusammensetzen von Implementierungen
Zusammengesetzte Implementierungen ermöglichen (Phabricator:T261468).
JavaScript-Implementierung
JavaScript-Implementierungen ermöglichen.
Wikidata
In der Lage, Wikidata aufzurufen.
Commons
In der Lage, Dateien in Commons aufzurufen.
Andere Wikimedia
In der Lage, andere Wikimedia-Eigenschaften aufzurufen.
Web aufrufen
In der Lage, das Web allgemein aufzurufen.
Nichtfunktionale Funktionen
Insbesondere "aktuelle Zeit" und "zufällig".