openlibraryenvironment/gokb

Erhöhung der Performance

Closed this issue · 12 comments

Für das Einspielen großer Pakete (bis zu 250.000, für Backlists vielleicht sogar 5.000.000 Records) muss die Performance der GOKb deutlich erhöht werden. Große produktive Pakete werden ab Januar 2021 eingespielt

Analyse

  • Ggf. Generierung sehr großer E-Book-KBART-Dateien mit Testdatengeneratoren
  • Bereitstellen mehrerer großer E-Book-KBART-Dateien per URL
  • Automatisierter Lauf mehrerer großer Testdaten-Pakete parallel. Test auf phaeton-qa
  • Ggf. Server- und Tomcateinstellungen optimieren und erneuter Testlauf
  • Zeiten und Logdaten notieren, wie es seitens der Performance aussieht (Dauer, klappt es überhaupt etc.)
  • Mögliche Optimierungen durchsspielen mit erneuten Tests (siehe unten)

Mögliche Flaschenhälse

  • Serverseitige Einstellungen
    • Für YGOR bzw. GOKb reservierter Tomcat-Speicher?
    • Zu geringe Timeout-Dauer?
    • Zu wenige Kerne für parallele Prozesse?
    • ...
  • Systeme (YGOR und GOKb)
    • Serielles Verarbeiten?
    • Nicht optimierte Schleifen?
    • Langsame Schnittstellen?
    • ...
  • Datenbankseitige Einstellungen
    • Clusterung sinnvoll?

Erweiterte Konzepte

  • YGOR besitzt noch die Funktion eines Teil-Updates ("Add Only"). Kann diese Funktion hilfreich sein? Dann müssten natürlich die Anbieter dazu gebracht werden, solche Teil-Updates als Datei anzubieten, also nur hinzugekommene oder weggefallene Titel nennen.
  • Wenn die Anbieter nur Änderungen als Datei ausgeben: Sollte ein entsprechendes Attribut dann in der Source nachgehalten werden (Teiludate: BOOLEAN) oder würde YGOR ggf. selbständig das Flag setzen und nur die korrekten, wenn YGOR eine gesetzte Spalte last_changed in der KBART-Datei findet?

Ich schließe mich von Nehmerseite aus an.

Die Versuche, die ich machen werde:

  • Parallelisierung (hinsichtlich zu verarbeitender TitleInstances oder TIPPs, muss noch evaluiert werden)
  • Verzicht auf das Verarbeiten gesamter GORM-Objekte, nur Einladen, wo es unbedingt notwendig ist, ansonsten nur die IDs laden

Insbesondere der OAI-PMH-Endpunkt hat hohen Verbesserungsbedarf. Dieser Aufruf (https://phaeton.hbz-nrw.de/gokb/oai/packages?verb=ListRecords&metadataPrefix=gokb&resumptionToken=2020-11-02T11:34:28Z||207|gokb) lädt bei Speicherlast 30 Minuten (!) und mehr. TOP zeigt Vollast zweier Prozessorkerne und 25 % Speicherlast.
EDIT: die gerade eben besprochene Abfrage hat bis zur Antwort seitens phaeton 40 Minuten genau gebraucht.

Am wirksamsten läßt sich die Verarbeitungsdauer verkürzen, indem die Datenmenge auf die Bestandteile reduziert wird, die tatsächlich noch nicht in der DB vorhanden sind. Ansonsten sollte man sich vor Augen halten, dass eine Viertelmillion Datensätze eine große Anzahl sind, die nicht einfach nur in die GOKb "eingespielt" werden, sondern als komplexe Datenstrukturen angelegt und validiert werden. Selbst, wenn sich die Performance verdoppeln läßt, scheint es mir nur eine Frage der Zeit zu sein, bis ein Paket kommt, was zwei Millionen Datensätze enthält.

Am wirksamsten läßt sich die Verarbeitungsdauer verkürzen, indem die Datenmenge auf die Bestandteile reduziert wird, die tatsächlich noch nicht in der DB vorhanden sind.

Genau, das wird bei Updates auf jeden Fall angestrebt. Bei der Ersteinspielung eines Titels gibt es hier wohl wenig Einsparpotential, oder @VolkerHBZ ?

Insbesondere der OAI-PMH-Endpunkt hat hohen Verbesserungsbedarf. Dieser Aufruf (https://phaeton.hbz-nrw.de/gokb/oai/packages?verb=ListRecords&metadataPrefix=gokb&resumptionToken=2020-11-02T11:34:28Z||207|gokb) lädt bei Speicherlast 30 Minuten (!) und mehr. TOP zeigt Vollast zweier Prozessorkerne und 25 % Speicherlast.
EDIT: die gerade eben besprochene Abfrage hat bis zur Antwort seitens phaeton 40 Minuten genau gebraucht.

Ich denke die beste Lösung hierfür wäre der Umstieg auf den mittleweile verfügbaren TIPP-Endpunkt (in 8.13.0 leider noch verbuggt). Ich habe den in den letzten Tagen noch etwas ausgebaut und beim Deploy der nächsten Minor Version (8.13.1) wird hierüber z.B. auch die selektive Abfrage von Inhalten einzelner Pakete (per Parameter pkg=<id/uuid>) möglich sein.

Die Verarbeitung eines 10.000-Zeilen Pakets (Springer eBooks) dauert Ygor-seitig etwa 3 Minuten (auf meiner lokalen Instanz), inkl. Absenden an die GOKb.

Die Annahme der gesendeten Daten durch die GOKb (ebenfalls meine lokale Instanz) dauert (wenn der Speicher nicht zu klein gewählt ist) etwa 100 Minuten.

@hornmo Gibt es Möglichkeiten, den crossReferencePackage-Prozess zu beschleunigen? (Abgesehen von Hardware-Upgrades.)

Zu den Analyse-Punkten aus der Issue-Beschreibung:

Ggf. Generierung sehr großer E-Book-KBART-Dateien mit Testdatengeneratoren

@VolkerHBZ und ich haben je einen Testdaten-Generator gebaut. Volker's Version erstellt reine Dummy-Daten, meine Version erweitert eine bestehende KBart-Datei. So haben wir insgesamt viel Varianz in den Daten. Datensätze in der Größenordnung mehrerer Millionen Records sind so im Handumdrehen erstellt. Beide Generatoren erzeugen Daten, die von Ygor vollständig eingelesen werden können.

Bereitstellen mehrerer großer E-Book-KBART-Dateien per URL

Das können wir jederzeit tun, sollten hierzu aber vielleicht URLs wählen, die im Firmennetz liegen?!

Automatisierter Lauf mehrerer großer Testdaten-Pakete parallel. Test auf phaeton-qa
Ggf. Server- und Tomcateinstellungen optimieren und erneuter Testlauf
Zeiten und Logdaten notieren, wie es seitens der Performance aussieht (Dauer, klappt es überhaupt etc.)
Mögliche Optimierungen durchsspielen mit erneuten Tests (siehe unten)

Das ist Stand Jetzt aus meiner Sicht (noch?) nicht sinnvoll, da die GOKb crossReference-Jobs (noch?) seriell abarbeitet. Ob die Parallelisierung der Einspielung von Paketen innerhalb einer GOKb-Instanz einen Performance-Gewinn erzeugen würde, kann ich auch nicht beurteilen. Das können @VolkerHBZ und @hornmo besser beurteilen.

Meine Tests zeigen, dass es keine offensichtlichen Hotspots gibt, an denen sich leicht viel Performance holen läßt. Um 500 Titel von Ygor zu übernehmen, braucht meine lokale Instanz 6 min. Allerdings stimme ich Philipp zu: eine parallele Verarbeitung, insbesondere der Tipps während des xRef-Jobs könnte die Performance deutlich steigern, da TIPPs ja unveränderlich sind und daher parallel geschrieben werden können. Bei dieser Gelegenheit wäre ein Auslagern der Funktionalität von crossReferenceXXX aus dem Integration Controller in einen Service sinnvoll, denke ich.
@hornmo ?

Meine Tests zeigen, dass es keine offensichtlichen Hotspots gibt, an denen sich leicht viel Performance holen läßt.

Auch nicht bedingt, z. B. dass Validierungen wegfallen können, wenn es sich z. B. um eBooks handelt?

Allerdings stimme ich Philipp zu: eine parallele Verarbeitung, insbesondere der Tipps während des xRef-Jobs könnte die Performance deutlich steigern, da TIPPs ja unveränderlich sind und daher parallel geschrieben werden können. Bei dieser Gelegenheit wäre ein Auslagern der Funktionalität von crossReferenceXXX aus dem Integration Controller in einen Service sinnvoll, denke ich.

+1 --> testen?!

Validierungen zu überspringen scheint mir nicht sinnvoll (https://github.com/openlibraryenvironment/gokb/wiki/tipp_dto), da sie - besonders bei Massendaten, die keiner weiteren Kontrolle unterliegen - wirksam verhindern, dass Müll in der Datenbank landet.

Validierungen zu überspringen scheint mir nicht sinnvoll (https://github.com/openlibraryenvironment/gokb/wiki/tipp_dto), da sie - besonders bei Massendaten, die keiner weiteren Kontrolle unterliegen - wirksam verhindern, dass Müll in der Datenbank landet.

Natürlich nicht einfach "überspringen". Die Frage ist, ob durch Fallunterscheidung auf unnötige Checks verzichtet werden kann.

es sind ohnehin nicht die Validierungen, die die Zeit verbraten, sondern die Datenbankzugriffe. Da werden pro Datensatz Zeilen in Combo, TitleInstance, Book/JournalInstance, TIPL, TIPP, KBComponent und sicher auch noch mehr geschrieben. Im Profiler sieht man dann dass und jedes mal, wenn ein flush:true kommt, dauert das ein paar Millisekündchen. Allerdings funktioniert ohne die flushs das Multithreading nicht.
Anbei ein Screenshot, wie lange ein 1000er Import auf PhaetonQA gedauert hat. Währenddessen hat der tomcat-Prozess 100%-160% Prozessorauslastung verursacht.
grafik