So kombinieren Sie zwei Plattformen zu einer und beleidigen Benutzer nicht. Yandex.Kew Entwicklererfahrung



Im vergangenen Jahr ist TheQuestion zu Yandex gekommen. Zu dieser Zeit gab es bereits einen ähnlichen Dienst an Fragen und Antworten - Yandex.Znatoki. Die Kenner hatten ein großes Publikum und viele interessante Fragen, aber es gab nicht genügend Experten, die diese Fragen qualitativ hochwertig beantworten konnten. TheQuestion hatte im Gegenteil eine starke Expertengemeinschaft, aber es fehlten interessante Fragen. Der logische Schritt bestand darin, die beiden Dienste zu kombinieren, um das Beste aus jedem von ihnen herauszuholen. Aber wie geht das, wenn jeder Dienst seine eigene technologische Basis, seinen eigenen Inhalt und seine eigenen Benutzer hat?

Heute werde ich darüber sprechen, wie unser Team dieses Problem aus technologischer Sicht gelöst hat. Sie erfahren, welche Kombinationsmöglichkeiten wir in Betracht gezogen und welche am Ende gewählt haben. Ich erzähle Ihnen von der "Swap-API", der Datenbankmigration, dem Pooling von Profilen und dem Backend-Testen. Und doch - über die Nacht des Umzugs ohne das Recht, einen Fehler zu machen. Sie werden sehen, dass wir uns nicht langweilen mussten.

Die Aufgabe, zwei Dienste zu einem zusammenzuführen, ist nicht neu, macht dies jedoch nicht einfacher. Die Geschichte kennt viele erfolgreiche (und nicht so erfolgreiche) Beispiele für Integration, aber leider gibt es keine „Silberkugel“ und eine klare Anweisung „Mach das und alles wird klappen“. Alles hängt sehr stark von den Besonderheiten der zu kombinierenden Dienste und dem gewünschten Ergebnis ab.

In unserem Fall war das Ziel Folgendes: Der gesamte Inhalt, der jemals auf jeder der Websites geschrieben wurde, war in einem einheitlichen Dienst verfügbar, und seine Autoren konnten ihn verwalten.

Wie kombinieren Sie also die beiden Q & A-Services, die so ähnlich, aber im Wesentlichen so unterschiedlich zu sein scheinen? Das Übertragen von Inhalten und Benutzern von einem Dienst zu einem anderen ist dem Umzug von einer alten in eine neue Wohnung sehr ähnlich.

Nur in unserem Fall kann der Benutzer gleichzeitig in zwei Wohnungen leben (Kenner und TheQuestion), und Sie müssen ihn vorsichtig in die dritte transportieren. Sie müssen alle Möbel, Pflanzen, eine Katze und sogar Tapeten in eine neue Wohnung bringen (dh Fragen, Antworten, Kommentare, Likes) und ihn dann zum Umzug einladen.

Wie macht man das? Mehrere Optionen fallen sofort ein.

Option 1. Sehr schlecht.
Nehmen wir einfach einen der Dienste, übertragen den gesamten Inhalt auf einen anderen (obwohl dies nicht mehr einfach ist) und schließen den ursprünglichen Dienst.

Diese Option ist aus Sicht des Benutzers des ersten Dienstes sehr schlecht. Wir haben gerade sein altes Haus abgerissen und ihn gezwungen, in ein neues umzuziehen. Jeder wird diese Einstellung nicht mögen und anstatt sich zu bewegen, kann er einfach in den Sonnenuntergang gehen. Für uns ist der Hauptwert die Benutzergemeinschaft, daher hatten wir nicht vor, jemanden zu beleidigen. Und mutig zu anderen Optionen gewechselt.

Option 2. Schlecht
Lassen Sie uns keinen der Dienste ändern, sondern einen neuen, integrierten Dienst starten und regelmäßig Inhalte von den beiden anderen hinzufügen (z. B. einmal am Tag).

In diesem Fall scheinen wir den Benutzer nicht schlechter zu machen, aber wir machen es auch nicht besser. Seine alte Wohnung bleibt unverändert, aber es macht keinen Sinn, in eine neue zu ziehen. Alle Nachbarn wohnen auch in einem alten Haus, eine soeben gekaufte Blume wird erst nach einem Tag in eine neue Wohnung gebracht. Solch ein einheitlicher Dienst hat keine Chance, ein neues Zuhause zu werden.

Option 3. Gut, aber schwierig.
Lassen Sie uns keinen der Dienste schließen. Wir werden sofort Inhalte und Profile des integrierten Dienstes duplizieren und die Mitarbeiter werden sich im Laufe der Zeit bewegen.

Alle Nachbarn des Benutzers (und sogar die Katze) leben gleichzeitig im alten und im neuen Haus. Eine Blume, die Sie gerade gekauft haben, erscheint sofort in einer neuen Wohnung. Genau das, was benötigt wird! Diese Option ist aus Sicht des Benutzers am bequemsten. Deshalb haben wir es gewählt.

Bewegen Sie sich


Was wir letztendlich getan haben, kann in mehreren Sätzen beschrieben werden. Wir haben das gesamte TheQuestion-API-Backend basierend auf dem Connoisseurs-Backend vollständig wiederholt und so ein einziges Backend erhalten, das mit zwei (und sogar drei) Sites gleichzeitig arbeiten kann. Gleichzeitig blieb das TheQuestion-Frontend nahezu unverändert, was bedeutet, dass sich die Site aus Sicht der Benutzer praktisch nicht geändert hat. Dieses Projekt hat den internen Namen "Swap API" erhalten. Aber das Wichtigste zuerst.

Was wir am Eingang hatten: zwei völlig unabhängige Standorte. Kenner leben in den inneren Wolken von Yandex. Das Connoisseurs-Backend ist in Python geschrieben. TheQuestion befindet sich in den Clouds von Microsoft Azure. Das Backend von TheQuestion ist in Go geschrieben. Dienste haben ein völlig anderes Datenspeicherungsschema in den Datenbanken. Darüber hinaus verfügt TheQuestion über zwei mobile Anwendungen (für Android und iOS), die ebenfalls unterstützt werden mussten. Im Allgemeinen will der Feind einen solchen Zoo nicht vereinen.



Stufe 0. Fahren Sie in die Yandex-Wolke


Genau genommen ist dieser Schritt für die „Plugin-API“ nicht erforderlich, vereinfacht jedoch die nächsten Schritte erheblich. Zu diesem Zeitpunkt haben wir externe Lager und Einrichtungen vollständig aufgegeben. TheQuestion begann mit der Verwendung von Yandex-DNS-Servern. Die Rentme-Dienste wurden nach Yandex.Cloud verlegt. Die Datenbank wurde in Yandex Managed Databases übertragen. Während des Umzugs konnten wir auch mehrere Fehler in TheQuestion finden und beheben, z. B. nicht geschlossene Verbindungen zu Redis im Code 2015. Als Bonus erhielten wir zusätzliche Leistung für TheQuestion.

Stufe 1. Datenmigration


Unabhängig davon, welche Option Sie Services kombinieren möchten, müssten wir die Daten in jedem Fall kombinieren. Für eine einzelne Datenbank haben wir uns für PostgreSQL entschieden - dieses DBMS wurde bereits sowohl in Experts als auch in TheQuestion verwendet. Um das Projekt nicht zu komplizieren, wurde keine dritte Basis für den integrierten Dienst erstellt, sondern lediglich die Znatokov-Datenbank verwendet, um alle TheQuestion-Daten zu akzeptieren. Dies war die erste große technologische Herausforderung.

Jeder Eintrag in jeder Tabelle aus der TheQuestion-Datenbank musste konvertiert und in die Expertenbasis gestellt werden. Dann - korreliere jede Spalte von der einen zur anderen Basis. Viele Felder mussten nicht trivial von einem Format in ein anderes konvertiert werden. Eine separate große Unteraufgabe war die Konvertierung des Textspeicherformats (das tatsächliche Format des Frage- oder Antwortspeichers) von QML (TheQuestion) in Markdown (Experten).

Wir haben einen regelmäßigen (mehrmals täglichen) Prozess zum Übertragen neuer Daten von einer Datenbank in eine andere eingerichtet, aber gleichzeitig sichergestellt, dass die Daten von TheQuestion bis zum Abschluss der nächsten Stufe nirgendwo angezeigt wurden. Denn "mehrmals am Tag" wird keineswegs "sofort" versprochen, und die Daten könnten sich in einem inkonsistenten Zustand mit denselben Daten in TheQuestion befinden, was die Benutzer irreführen würde. Warum haben wir mit der Datenmigration begonnen, wenn das Backend noch nicht fertig war?

Erstens haben wir auf diese Weise den Prozess stabilisiert. Zweitens haben sie die Menge neuer Daten reduziert, die in Zukunft übertragen werden müssen, und dies ist wichtig, da alle importierten Inhalte durch das Markup für Qualität, unangemessenen Inhalt, Spam und Betrug gesteuert werden mussten.



Stufe 2. "API austauschen"


Also haben wir das erste der Probleme gelöst - wir haben gelernt, Inhalte aus der TheQuestion-Datenbank zu übernehmen und sie sogar anzuzeigen, wenn Sie dies wünschen. Jetzt war es notwendig, diesen Inhalt sofort und nicht mehrmals am Tag in die integrierte Datenbank zu bringen.

Dazu musste das gesamte TheQuestion-Backend mit der erforderlichen Logik neu geschrieben werden. Der Name des Projekts, "Swap API", spiegelt genau genommen das Wesentliche nicht vollständig wider. Es wäre richtiger, es "Swap-Backend" zu nennen. Tatsache ist, dass neben der direkten Implementierung aller für das Funktionieren des TheQuestion-Frontends erforderlichen „Stifte“ weitere Möglichkeiten realisiert werden mussten. Wir standen vor mehreren großen Aufgaben.

GenehmigungYandex verfügt über ein zentrales Benutzerautorisierungssystem - Yandex.Passport. Und Kenner haben natürlich den Pass benutzt. Um sich anzumelden, müssen Sie ein Konto bei Yandex haben. Das war das Problem. Nicht alle TheQuestion-Benutzer haben sich über Yandex auf der Website angemeldet (obwohl es eine solche Möglichkeit gab). Viele Benutzer hatten überhaupt kein Yandex-Login und gingen über soziale Netzwerke (VKontakte, Facebook ...). Natürlich mussten wir diese Funktionalität beim Umzug beibehalten. Aus diesem Grund haben wir die Berechtigung "Nicht-Pass" implementiert.

Seitensuche.TheQuestion hat eine Suche nach Fragen, Antworten, Benutzern und Themen implementiert. Für die Suche wurde eine Sphinx-Lösung eines Drittanbieters verwendet. Wenn es sich um einen einzelnen Dienst handelt, sollte die Suche natürlich dieselbe sein, dh, sie kann nicht auf zwei Systemen gleichzeitig funktionieren. Daher wurde Sphinx zugunsten einer internen Suchmaschine aufgegeben, die die erforderliche Funktionalität und Indizierung aller TheQuestion-Inhalte unterstützt.

Versand von Seiten in Zen und Turbo . Zum Zeitpunkt des Beitritts verwendete TheQuestion bereits Yandex-Technologien. Turbo-Seiten wurden unterstützt, interessante Inhalte fielen in den Zen-Feed. All dies musste auch in der "Ersatz-API" unterstützt werden.

Benachrichtigungen im Dienst und in den Anwendungen, Mailinglisten.Alles, was mit der Benachrichtigung von Benutzern zu tun hat: Abonnements, Newsletter mit interessanten Inhalten, Push-over-Likes und Kommentare, vieles mehr. All dies musste sorgfältig übertragen und nicht vergessen werden.

Site Administration System . Dieser Absatz bezieht sich auf alles, was mit der internen Verwaltung des Dienstes zusammenhängt: Moderation, Analyse usw.

Einheitliches Benutzerbewertungssystem.Diese Aufgabe war eher nicht technisch, sondern logisch. Formal ist es nicht erforderlich, ein einheitliches Bewertungssystem für eine „Swap-API“ zu entwickeln, aber dieses System wird weiterhin für den zukünftigen integrierten Service benötigt. Auf beiden Websites wurden Benutzer nach Quantität und Qualität der erstellten Inhalte bewertet. Die Details der Bewertung wurden nicht bekannt gegeben, aber je öfter und besser Sie die Fragen beantworten, desto höher ist Ihre Bewertung. Die Bewertungsgrundsätze waren für beide Dienste gleich, aber die Formel selbst und die Faktoren waren sehr unterschiedlich. Es war nicht nur notwendig, die Benutzer von Znatokov und TheQuestion korrekt und ehrlich miteinander zu vergleichen, sondern auch zu lernen, eine einzige Bewertung für diejenigen Experten zu berücksichtigen, die gleichzeitig über zwei Dienste geschrieben haben.

Und schreiben Sie alle APIs neu.Ob es Ihnen gefiel oder nicht, diese Aufgabe war die wichtigste und schwierigste. Viele Prozesse in den Diensten waren ähnlich, deshalb haben wir sie den Kennern abgenommen und nicht von Grund auf neu geschrieben. Es gab aber auch viele neue Dinge, zum Beispiel gerade Linien von Benutzern oder Entwürfe von Antworten. Infolgedessen haben wir mehr als 100 "Stifte" in der "Swap-API" neu geschrieben und mehr als 50 REST-Ressourcen implementiert.

Nachdem wir alle oben beschriebenen Funktionen implementiert hatten, war es möglich, mit dem Umzug zu beginnen. Aber bevor wir einen Trick gemacht haben.

Es ist klar, dass die „Swap-API“ vor dem Wechsel und der Einführung in der Produktion sehr gut getestet werden musste. Zunächst musste es funktionsfähig getestet werden, dh die Leistung der gesamten Site auf der neuen API direkt überprüft werden. Zweitens ist es stressig. Wir wollten 100% sicher sein, dass unser Design nicht unter Last „liegt“. Natürlich haben wir regelmäßig „Lastfeuerungen“ durchgeführt, was gezeigt hat, dass wir ein gutes Leistungsangebot haben. In Bezug auf die Serviceleistung ist es jedoch immer besser, auf Nummer sicher zu gehen. Alle, selbst die besten synthetischen Belastungstests unterscheiden sich irgendwie von der Produktionslast. Aus diesem Grund haben wir uns vor dem Wechsel der API entschlossen, die Produktionslast auf unserem Stand zu füllen.

Zu diesem Zweck haben wir im TheQuestion-Frontend die Duplizierung aller GET-Anforderungen (dh Datenanforderungen, keine Änderungen) gleichzeitig in zwei APIs implementiert: die "alte API" TheQuestion, die zu diesem Zeitpunkt die Haupt-API war, und die sekundäre "Swap-API". Gleichzeitig wartete das Frontend nicht auf eine geringfügige API-Antwort und verarbeitete keine Fehler, aber wir konnten das Backend an echten Benutzern testen.



Stufe 3. Und dann erinnerten wir uns an Anwendungen


Nein, natürlich haben wir uns die ganze Zeit an sie erinnert, aber wir hatten ein Problem. Diejenigen, die mit mobilen Anwendungen gearbeitet haben, wissen, dass der Aufwand mit ihnen viel größer ist als mit der Website. Dies ist vor allem auf die Verbreitung neuer Versionen zurückzuführen.

Erstens müssen Sie mit externen Diensten des App Store und von Google Play zusammenarbeiten und warten, bis die neuen Versionen die Überprüfung bestanden haben (und manchmal kann die Überprüfung eine beträchtliche Zeit in Anspruch nehmen). Zweitens bedeutet dies nicht, dass Benutzer ein Update vornehmen, selbst wenn Ihre Anwendung den Test bereits bestanden hat und im Store angezeigt wurde.

Im Fall des Frontends der Site steuern die Entwickler selbst, wann eine neue Version veröffentlicht wird, und sie wissen mit Sicherheit, dass danach alle Benutzer eine aktualisierte Version der Site erhalten. Bei Anträgen gibt es keine solche Garantie. Um eine solche Garantie zu erhalten, verwenden sie häufig eine „erzwungene Aktualisierung“ der Anwendung. Nur wenige Leute lieben diese Methode, und natürlich müssen Sie, wenn möglich, immer die Abwärtskompatibilität zwischen der Anwendung und dem Backend aufrechterhalten. Daher haben wir den Weg eingeschlagen, Änderungen genau auf der Backend-Seite mit minimalen Änderungen am Frontend in Anwendungen vorzunehmen. Aber wie so oft ist der Plan mit einer harten Realität konfrontiert.

Einige Änderungen waren auf der Front-End-Seite viel einfacher durchzuführen als auf der Back-End-Seite. Bei der Entwicklung einer „Plug-in-API“ wurde das Front-End daher geringfügig geändert. Insbesondere in der alten TheQuestion-Datenbank wurden numerische 64-Bit-IDs verwendet. Die Connoisseurs-Datenbank und dementsprechend die kombinierte Datenbank und die neue API für TheQuestion verwendeten String-128-Bit-IDs. Im Allgemeinen ist dieser Unterschied für ein in Node.js geschriebenes Frontend nicht signifikant. Bei stark typisierten Anwendungen erwies sich dies jedoch als fatal. Wir haben die Abwärtskompatibilität verloren und ältere Anwendungen konnten nicht mit der "Plugin-API" arbeiten.

Irgendwann gab es sogar ein Projekt namens "Plugin-API für Plugin-API", dessen Kern darin bestand, eine kleine Ebene zwischen dem neuen Backend und Anwendungen zu schreiben, die alle Daten in das alte Format konvertieren würden. Wir haben diese Idee jedoch schnell aufgegeben. Diese Schicht würde sich als sehr starre „Krücke“ herausstellen, was uns in Zukunft definitiv viele Probleme bringen würde. Beispielsweise können Sie 128-Bit-IDs nicht einfach in 64-Bit-IDs umwandeln. Ich müsste mit Informationsverlust und folglich möglichen Kollisionen nach ID übersetzen oder eine Zwischentabelle mit der Entsprechung alter und neuer IDs (für alle Elemente der Datenbank) führen. Sowohl das als auch eine andere - nicht die beste architektonische Lösung.

Neben der ID gab es eine Reihe weiterer Änderungen, die auch auf der Front-End- und Anwendungsseite viel einfacher zu unterstützen waren. Aus diesem Grund haben wir beschlossen, Änderungen in Anwendungen zu implementieren und das erzwungene Update weiterhin zu verwenden. In kurzer Zeit haben wir neue Versionen von Anwendungen entwickelt, die mit der „Swap-API“ kompatibel sind, da es im Front-End nicht so viele Änderungen gab und diese nicht sehr schwerwiegend waren. Wird an den App Store und an Google Play gesendet, erfolgreich moderiert und beginnt zu warten.

Stufe X. Lass uns gehen!


Der gesamte Code ist also geschrieben. Der Stand mit der "Ersatz-API" wird getestet und gebrannt. Neue Versionen der Anwendung wurden in Geschäften getestet und können veröffentlicht werden. Jetzt musste alles in die Produktion eingeführt werden.

Aufgrund der Tatsache, dass das Kopieren neuer Daten aus der alten Datenbank in die neue asynchron erfolgt und einige Zeit in Anspruch nimmt, können Sie das Backend (und die darunter liegende Datenbank) auf einer Arbeitswebsite nicht wechseln. Dies kann zum Verlust oder zur Inkonsistenz von Benutzerdaten führen. Aus diesem Grund haben wir ein Datum ausgewählt, die Benutzer gewarnt und eine Platte mit dem Titel „Technische Arbeiten in Arbeit“ vorbereitet.

Und dann kam die Stunde oder besser gesagt die Nacht X. Der Roll-out-Plan sah folgendermaßen aus:

  1. Auf der Website TheQuestion hängen wir einen Stub "Work is in progress" auf.
  2. Wir übertragen Anwendungen in den Readonly-Modus. Benutzer können Inhalte aus der alten Datenbank lesen, aber keine neue erstellen.
  3. TheQuestion Readonly. : . , , .
  4. . , .
  5. .
  6. , , API.
  7. API . — , API .
  8. , , .
  9. « », API.
  10. .

Nun, das sieht nicht so beängstigend aus. In Wirklichkeit lief alles ganz reibungslos. Von den Überraschungen, die wir erlebten, war es vielleicht nur zu lang, die Anwendung im App Store zu veröffentlichen (die Anwendung wurde im Voraus geprüft, es ging nur darum, im Store zu erscheinen). Am Ende dauerte es mehrere Stunden, weshalb sich die gesamte Operation etwas verzögerte.

Darüber hinaus gab es beim Wechsel ein Schlüsselmerkmal, das alles um ein Vielfaches komplizierte und die Verantwortung erhöhte. Tatsache ist, dass der Schaltvorgang nicht rückgängig gemacht werden konnte.

Obwohl der Prozess des Kopierens und Konvertierens von Daten aus der alten TheQuestion-Datenbank in die neue, integrierte Datenbank für uns eingerichtet und debuggt wurde, gab es keinen umgekehrten Kopierprozess (von der neuen Datenbank in die alte). Dies bedeutet, dass alle neu erstellten Fragen, Antworten, Kommentare und Likes nicht mehr einfach in die alte TheQuestion-Datenbank gelangen können, sobald wir die Site über die „Swap-API“ öffnen und den Benutzerverkehr starten. Wenn beispielsweise nach dem Öffnen etwas schief geht und eine einzelne Datenbank die Last nicht bewältigen kann, kann nicht alles schnell zurückgesetzt werden.

Tatsächlich übertreibe ich natürlich. In jedem Fall würden wir keine Benutzerdaten verlieren. Wir hatten einen Plan B und eine Möglichkeit, Daten manuell aus einer neuen Datenbank in eine alte zu sichern. Aber es würde noch einige Zeit dauern, und der Rollback wäre für Benutzer nicht ganz schmerzlos verlaufen.

Glücklicherweise funktionierte Plan A und nichts musste zurückgesetzt werden.



Letzte Stufe


Also wurde das Backend geändert, die Datenbank wurde kombiniert, die mobilen Anwendungen wurden nicht vergessen. Für Benutzer hat sich nichts geändert, da die Yandex.Ku-Site, die Daten von beiden Sites kombinieren sollte, zu diesem Zeitpunkt noch nicht gestartet wurde. Und für den Start mussten wir noch ein Problem lösen.

Ganz am Anfang schrieb ich, dass wir nicht nur Fragen und Antworten von zwei Diensten in einem neuen, sondern auch von Benutzern kombinieren müssen. Benutzer sollten in der Lage sein, ihre Inhalte nicht nur auf Kew zu sehen, sondern auch auf Kew zu verwalten. Technisch gesehen ist es nicht schwierig, Daten zu kombinieren und Verwaltungsrechte zu übertragen. Es ist viel schwieriger sicherzustellen, dass die Rechte auf denjenigen übertragen werden, auf den sie übertragen werden sollen.

Beim Umzug von Znatokov nach Kew ist alles einfach: In beiden Fällen wird dasselbe Yandex-Konto verwendet. TheQuestion hat jedoch ein eigenes Konto, das bei Kew nicht autorisiert werden kann. Zum Glück haben wir vorher darüber nachgedacht. Lange vor den oben beschriebenen Aktionen haben wir TheQuestion-Benutzern ermöglicht, ihre Yandex-Profile zu verknüpfen. Zum Zeitpunkt der physischen Konsolidierung der Dienste hatten dies mehr als 90% der aktiven Benutzer getan. Dadurch konnten wir problemlos mit der Migration von Inhalten und Benutzern beginnen.

Gesamt


Als wir umgezogen sind, wollten wir jeden Benutzer retten, deshalb haben wir uns bewusst für die zeitaufwändigste und riskanteste Option entschieden, Plattformen zu kombinieren. Wir haben eine einheitliche technologische Basis geschaffen und gelernt, wie Inhalte und Profile sofort transportiert werden können. Anstelle einer unerwarteten Schließung und eines erzwungenen Umzugs behielten sie die Funktionalität der alten Dienste bei, starteten einen neuen und erläuterten dessen Vorteile.



Wir haben Yandex.Kew letztes Jahr gestartet . Jetzt sind mehr als 80% der aktiven Autoren von TheQuestion und Znatokov freiwillig in ein neues Zuhause gezogen.

All Articles