Docker-Image-Update: Redis 6 und 25 % kleinere Image-Größe

Wir haben gerade ein brandneues Container-Image veröffentlicht, das bei Ihrem nächsten Befehl ./launcher rebuild app verwendet wird. Wie immer müssen Sie keine Konfiguration ändern, sofern Sie unserer offiziellen Standard-Installation für Discourse gefolgt sind. Dennoch gibt es neue Funktionen, die einigen Installationen helfen werden.

Redis 6

Wir setzen in vielen Bereichen von Discourse stark auf Redis – sei es für Caching, Sidekiq, MessageBus oder verteilte Sperren und Ratenbegrenzungen. Insgesamt war es eine absolut zuverlässige Wahl für uns.

Bei sehr spezifischen Arbeitslasten kann Redis jedoch zum Flaschenhals werden. Aufgrund der einzeln-threadigen Natur von Redis, kombiniert mit unserer Unfähigkeit, mehrere Instanzen zu nutzen (aufgrund unserer LUA-Skripte), war dies ein schwer zu umgehender Engpass.

Glücklicherweise unterstützt Redis 6 die Verwendung eines Thread-Pools für I/O-Operationen. Unsere Tests haben gezeigt, dass dies bei Discourse-Clustern, die durch Redis ausgebremst werden, sehr gut funktioniert.

Wenn Sie also auf einer Maschine mit vielen CPU-Kernen laufen und Ihre Metriken zeigen, dass Redis Schwierigkeiten hat, die Last zu bewältigen, können Sie nun über den params-Abschnitt in der app.yml-Konfiguration die Verwendung von Threads für Schreiboperationen aktivieren:

params:
  redis_io_threads: "4" # 1 deaktiviert es, n>1 verwendet n-1 zusätzliche Threads für I/O-Schreibvorgänge

Kleineres Image

Zu Beginn des Projekts haben wir uns dafür entschieden, ein großes Container-Image auszuliefern, um es nicht-technischen Nutzern zu erleichtern, Discourse auszuführen, und um alle erforderlichen Abhängigkeiten, Versionsverwaltungen, Updates usw. abzudecken.

Trotzdem haben wir vor kurzem die 1-Gigabyte-Grenze für das komprimierte Image überschritten, was etwas zu viel war.

Um die ständig wachsende Größe des Images einzudämmen, haben wir den Discourse-Quellcode innerhalb des Images von einer vollständigen Kopie des Quellcodes auf einen „shallow clone" umgestellt, der nur die neueste Version des Codes enthält.

Diese Änderung reduziert die Größe des komprimierten Images um 25 %, was weniger Serverplatz erfordert und Neuaufbauten bei Veröffentlichung eines neuen Images beschleunigt. Zudem sollte dies das Wachstum des Images im Laufe der Zeit begrenzen.

Wir haben dies in den Umgebungen tests-passed, beta und stable sowohl mit Neuaufbauten als auch mit Web-Updates getestet, und es unterbricht keine Standardpfade. Nutzer, die jedoch exotischere Git-Operationen in den app.yml-Hooks durchführen, müssen möglicherweise ihre Anpassungen anpassen.

42 „Gefällt mir“

Was passiert nach einem solchen Redis-Upgrade mit dem Browsererlebnis? Hat dies Auswirkungen auf zwischengespeicherte Assets? Werden diese als Folge des Upgrades geleert?

3 „Gefällt mir“

Nichts.

Assets werden auf der lokalen Festplatte oder im Objektspeicher gespeichert und im CDN zwischengespeichert. Redis hat keinen Einfluss darauf.

Die Redis-Daten bleiben während des Upgrades erhalten.

10 „Gefällt mir“

Was ist der Standardwert? 1?

5 „Gefällt mir“

Ja. Dies stammt aus der Redis-Konfigurationsdatei selbst, wobei 1 einen einzelnen Thread wie in der alten Version bedeutet.

8 „Gefällt mir“

Ich habe einen Fall, in dem ich Folgendes hinzugefügt habe:

after_redis:
  - replace:
      filename: "/etc/redis/redis.conf"
      from: /^databases.*/
      to: "databases 50"

Der Neuaufbau schlägt fehl, weil:

25:M 01 Dec 2020 20:21:08.830 # FATAL: Data file was created with a Redis server configured to handle
 more than 16 databases. Exiting

Gibt es einen anderen Hook, den ich nutzen kann, um die Anzahl der Datenbanken zu aktualisieren, bevor versucht wird, eine Migration durchzuführen oder was auch immer geschieht?

Hmm. Und jetzt sehe ich nach dem scheinbar fehlgeschlagenen Neuaufbau Folgendes in den Docker-Logs:

chgrp: invalid group: ‘syslog’
2 „Gefällt mir“

Warum benötigen Sie mehr als eine Datenbank?

3 „Gefällt mir“

Multisite. Mehrere Instanzen nutzen einen einzigen Redis-Server. Ich hätte wahrscheinlich einen allgemeineren Redis-Container verwenden sollen, habe mich aber dafür entschieden, bei deinem zu bleiben.

2 „Gefällt mir“

:face_with_raised_eyebrow:

Verwendet Multisite eine einzige Datenbank und die Standard-Redis-Namensräume? Soweit ich weiß, sind Redis-Datenbanken nur eine dünne Schicht, und es gibt Befehle, die über ihre Grenzen hinweggehen. Daher solltest du dich nicht darauf verlassen.

6 „Gefällt mir“

Ja, Multisite verwendet eine Datenbank.

3 „Gefällt mir“

Ah. Also kein Multisite, sondern mehrere Instanzen auf einer Maschine, die jeweils eine eigene Redis-Instanz benötigen. Ich habe die Standardanzahl von 16 auf 50 erhöht, weil ich zu faul war, genau zu kontrollieren, welche Redis-Datenbanken gerade belegt waren.

Ich sollte also für jede Instanz einen separaten Redis-Container ausführen, nehme ich an?

2 „Gefällt mir“

Ja, andernfalls könnte es zu gegenseitigen Störungen kommen.

5 „Gefällt mir“

OH. Mist.

Zum Glück habe ich das auf einem Server gelernt, der nur zum Testen genutzt wird.

Soll ich den anderen Seiten einfach eine frische Redis-Instanz geben und das Geplante verwerfen? Ein Backup/Restore durchführen?

Übrigens habe ich in den letzten ein oder zwei Jahren keine Probleme mit Crosstalk bemerkt. :man_shrugging: Und es gibt eine Möglichkeit, die DB festzulegen.

EDIT: Die gute Nachricht ist, dass ich in den Container gehen, die redis.conf bearbeiten und ihn neu starten kann, und dann funktioniert es wieder.

Wenn du einen Tipp hast, wie man eine Seite von DISCOURSE_REDIS_DB: 12 in einem Redis-Container zu einem anderen Redis-Container verschiebt, würde ich das gerne hören. Oder sollte man sich vielleicht einfach nicht um geplante Jobs kümmern?

3 „Gefällt mir“

Genau. Discourse sollte einen Redis-Flush problemlos überstehen. Manche Dinge gehen verloren, aber nichts Kritisches.

7 „Gefällt mir“

Das dachte ich mir auch, da mir keine Methode bekannt ist, mit der Backups versuchen, dies wiederherzustellen (aber es gibt viel, das ich nicht weiß). Es sieht so aus, als könnte ich es so machen: https://stackoverflow.com/questions/23222616/copy-all-keys-from-one-db-to-another-in-redis, und es scheint in einem Test, den ich gerade durchgeführt habe, funktioniert zu haben. Es wird jedoch viel einfacher sein, mein Playbook so anzupassen, dass einfach ein neuer Redis-Container erstellt und verwendet wird.

Danke.

Jetzt muss ich noch herausfinden, ob ich diese Redis-Instanzen auf dem Datenbankserver oder dem Webserver ausführen soll…

3 „Gefällt mir“

Dann wofür steht die db_id: 2 in der Multisite-Konfiguration?

2 „Gefällt mir“

Eine veraltete Einstellung:

5 „Gefällt mir“

LOL. Ja, das ist wirklich verwirrend!

Danke. Ich arbeite an einem Thema über „Multisite-Konfiguration mit Let’s Encrypt und ohne externen Reverse-Proxy

4 „Gefällt mir“

Stelle einfach sicher, dass du Unicorn direkt danach neu startest, damit die geplanten Aufgaben neu erstellt werden.
Du wirst alle Warteschlangen verlieren, daher musst du einen geeigneten Zeitpunkt dafür wählen.

6 „Gefällt mir“

[quote=“Falco, Beitrag:1, Thema:171437”]
…wir haben kürzlich die 1 GB-Grenze für das komprimierte Image überschritten, und das war etwas zu viel.

Also … haben wir den Discourse-Quellcode aus dem Image heraus … in einen „shallow clone

1 „Gefällt mir“