Ruby Multi-CPU-Threading

Hallo, wie ich in früheren Beiträgen erwähnt habe, führe ich Testläufe meiner Drupal-zu-Discourse-Migration durch, um alle Lösungen parat zu haben, bevor ich die alte Website endgültig abschalte, um die Produktionsdaten mit ihren ca. 2 Millionen Beiträgen zu migrieren. Was ich gelernt habe, ist, dass der Importprozess auf einem ziemlich schnellen VPS mit 3 vCPU-Kernen ewig dauert, etwa 48 Stunden. Und dann muss ich wahrscheinlich noch einige Bereinigungen mit rake-Tasks und/oder rails c durchführen, und für alles, was einen rake posts:rebake erfordert, dauert es weitere ca. 20 Stunden.

Ich verstehe die Grundlagen der Ruby-Toolchain nicht wirklich. Aber wird es die Zeit, die jeder dieser Prozesse zum Abschluss benötigt, erheblich verkürzen, wenn ich mehr CPU-Kerne für den Job einsetze? Können beispielsweise ein bundle-Befehl oder ein rake-Befehl ihre Arbeit auf die verfügbaren CPUs aufteilen, oder sind die zusätzlichen Kerne hauptsächlich nützlich, um mehrere Prozesse gleichzeitig auszuführen, wenn mehrere Benutzer die Website aufrufen?

1 „Gefällt mir“

Ich bin vom Thema abgekommen, aber als ich an einer Forenmigration mit der gleichen Anzahl von Beiträgen gearbeitet habe, habe ich das Importskript so modifiziert, dass nur 1/100 oder 1/1000 Themen und Beiträge importiert werden.

Es ist eine schnellere Methode, um zu sehen, ob Ihr Import zuverlässig ist und ob Änderungen oder Fehlerbehebungen erforderlich sind.

3 „Gefällt mir“

@Canapin Tatsächlich vielen Dank für die Erwähnung, ich würde wirklich gerne wissen, wie Sie das gemacht haben. Ich wollte dasselbe tun, habe die Idee aber verworfen, weil ich davon ausging, dass es bei einem teilweisen Import zu Inkonsistenzen in der Datenbank kommen würde. Also habe ich ein rudimentäres Drupal-Testforum erstellt, um darauf zu testen. Aber ich würde lieber eine Kopie der Produktionsdatenbank testen.

Ich mache mir hauptsächlich Sorgen um die endgültige Produktionsmigration. Ich muss das alte Forum offline nehmen oder es zumindest schreibgeschützt machen, und das wird bestenfalls mindestens 48 Stunden Ausfallzeit bedeuten, es sei denn, das Verdoppeln der CPU-Kerne halbiert die Zeit?

1 „Gefällt mir“

Die Aufgaben, deren Wiederherstellung lange dauert, sind tatsächlich Multithreading-Aufgaben. Ein Vorbehalt ist, dass doppelt so viele CPUs fast nie die doppelte Leistung bringen.

Ein weiterer Punkt ist, dass die Aufgaben für rake posts:rebake und die Hauptlast des Forums selbst, um den Inhalt wiederherzustellen und zu optimieren, normalerweise bei laufendem Forum stattfinden können. Dies könnte die Zeit reduzieren, die Sie benötigen, um das Forum entweder offline oder schreibgeschützt zu schalten, und eine etwas eingeschränkte Erfahrung anbieten zu können.

Meine Empfehlung wäre: Testen Sie zuerst. Führen Sie die Migration durch, sehen Sie, wie lange sie dauert und wie das Forum ohne alle Rebakes aussieht. Wenn es gut genug ist, timen Sie die Migration so, dass sie gegen die Zeit mit dem geringsten Traffic Ihres Forums endet, auf diese Weise verdienen Sie etwa 4-10 Stunden Migration, ohne dass sich viele Leute beschweren.

3 „Gefällt mir“

Ausgezeichnet, danke für die Bestätigung, ich habe auch über diese Option nachgedacht.

Leider habe ich das nicht aufgeschrieben und vergessen… Aber wenn du programmieren kannst, sollte das nicht sehr schwierig sein.
Ich habe vielleicht die Werte für BATCH_SIZE und offset unter anderem angepasst, um die Schleife zu ändern und Stapel von Beiträgen zu überspringen oder so etwas…

Ich kann es jetzt nicht noch einmal versuchen, weil ich gerade kein Forum zum Importieren habe, aber ich werde beim nächsten Mal eine kurze Anleitung erstellen, weil ich denke, dass sie sehr nützlich ist.

1 „Gefällt mir“

Ich möchte zwei Dinge erwähnen.

  • Ja, CPUs sind wichtig. Holen Sie sich also einfach einen größeren VPS und führen Sie mehrere Sidekiq-Instanzen für das erneute Backen und die Bildverarbeitung aus, das geht schneller.
  • Wenn Ihr Import vollständig abgeschlossen ist, ist es immer eine gute Idee, ein Backup/Restore durchzuführen. Dies verbessert die Leistung Ihrer Datenbank.

Beides zusammen: Holen Sie sich einen großen VPS für den Import und wenn Sie fertig sind, verschieben Sie ihn auf einen kleineren Produktions-VPS (mittels Backup und Restore).

Im Allgemeinen erfordert ein Import kein erneutes Backen von Beiträgen danach.

3 „Gefällt mir“

Vielen Dank Richard für die Antwort. Welche(n) davon?

  • UNICORN_WORKERS
  • UNICORN_SIDEKIQS
  • DISCOURSE_SIDEKIQ_WORKERS

Interessant, diese Empfehlung habe ich noch nicht gesehen. Reduziert das die Fragmentierung oder so etwas?

Ja, ich wollte ursprünglich einige [QUOTE]-Probleme und die Umwandlung von Textile zu Markdown mit regexp_replace() in der Postgres-Konsole beheben und dann alle Beiträge neu backen, da die rake posts:remap-Befehle einfach zu langsam waren. Aber dann habe ich festgestellt, dass die von Postgres verwendete Regex-Variante nicht mit PCRE kompatibel ist und es einfach zu viele unerwartete Anomalien gibt, als sich darauf zu verlassen. Daher werde ich versuchen, die Beiträge während des Importvorgangs durch Pandoc laufen zu lassen, was es mir ermöglichen sollte, die importierte Website in einem präsentablen Zustand hochzufahren und dann kleinere Dinge wie Emoji-Schlüsselwörter mit rake posts:remap zu beheben.

  • UNICORN_SIDEKIQS – Anzahl der Prozesse (Standard 1)
  • DISCOURSE_SIDEKIQ_WORKERS – Anzahl der Threads innerhalb eines Prozesses (Standard 5)

Es reduziert die Fragmentierung und behebt die Tatsache, dass die Postgres-Statistiken aufgrund des Imports verzerrt sein können.

2 „Gefällt mir“

:+1:

Diesen Rat habe ich auch noch nicht gesehen. Wenn dies “immer eine gute Idee” ist, sollte es vielleicht zu Pre-launch checklist after migrating from another platform hinzugefügt werden?

Ich glaube, es war Sam oder Jeff, der mir diesen Rat vor vielen Jahren gab. Ich kann ihn nicht mehr finden. Vielleicht sollten wir prüfen, ob es immer noch eine gute Idee und/oder die Mühe wert ist :wink:

1 „Gefällt mir“

Könnte mir zufällig jemand Tipps geben, wie ich ein Importskript am schnellsten erneut ausführen und die Daten neu importieren kann? Ich versuche, einige Textsubstitutionen im Importer-Skript zu ändern, und wenn ich es nicht richtig hinbekomme, muss ich die Discourse-Datenbank löschen und ./launcher rebuild import ausführen, was ziemlich lange dauert. Ich möchte Änderungen an meinem Importer-Skript vornehmen und es von vorne beginnen lassen (ich verwende derzeit eine kleine Skeleton-Mockup-Datenbank meiner Website, daher ist das Ausführen des Importers sehr schnell).

Hmmm. Ich teste einen weiteren Import meiner Produktionsforumdaten, diesmal auf einem ziemlich leistungsstarken VPS mit 8 virtuellen Kernen und 16 GB RAM. Ich habe Folgendes eingestellt:
UNICORN_SIDEKIQS=4
DISCOURSE_SIDEKIQ_WORKERS=20
UNICORN_WORKERS=16

Damit scheint er während der import_topics-Phase nicht alle Kerne auszunutzen:

Interessanterweise war das CPU-Diagramm während der user_import-Phase bei über 600 % (also ca. 6 von 8 Kernen zu 100 % ausgelastet).

Mir ist auch diese Umgebungsvariable aufgefallen: RUBY_GLOBAL_METHOD_CACHE_SIZE=131072. Wäre die zu klein?

Ich denke, dass während des Zustands der Benutzererstellung mehr Aktionen von Sidekiq asynchron verarbeitet werden.
Ein großer Teil des Imports wird leider nicht von der Parallelisierung profitieren. Sie sollten stattdessen die Single-Core-CPU-Geschwindigkeit optimieren.

Theoretisch könnten Sie verschiedene Teile des Topic-Imports parallel ausführen, aber dies würde eine erhebliche Umstrukturierung des Importers erfordern und sicherstellen, dass alles in der richtigen Reihenfolge verarbeitet wird. Es lohnt sich nicht für eine einmalige Aufgabe mit wenigen Iterationen.

2 „Gefällt mir“

Ich habe eine Kombination dieser beiden[1] Anleitungen[2] für den Import mit Zugriff auf einen anderen Docker-Container, auf dem eine Kopie der Quelldatenbank des Quellforums in MySQL läuft, befolgt. Aber mir ist eingefallen, dass ich anstatt einen separaten import-Container zu erstellen, einfach einen einzelnen app-Container verwenden und die mysql-dep.tempate hinzufügen kann:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

Dies ermöglicht es mir, eine funktionierende Discourse-Instanz zu haben, während das Import-Skript läuft. Gibt es Nachteile, das Forum sofort nach dem Import aller Benutzer und Kategorien für die Öffentlichkeit zugänglich zu machen und die Benutzer einfach mit einem Banner darüber zu informieren, dass es ein paar Tage dauern wird, bis es vollständig gefüllt ist? Ich denke, dass ich es zumindest nach dem Import aller Themen und Beiträge öffnen könnte, aber bevor die privaten Nachrichten importiert werden, da der Import der privaten Nachrichten allein gut 24 Stunden dauern wird.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.