Aggiornamento immagine Docker: Redis 6 e dimensione immagine ridotta del 25%

Abbiamo appena rilasciato una nuova immagine container che verrà utilizzata al prossimo ./launcher rebuild app. Come sempre, non è necessario modificare alcuna configurazione, a patto che abbiate seguito la nostra Installazione Standard Ufficiale di Discourse. Detto questo, sono state introdotte nuove funzionalità che aiuteranno alcune installazioni.

Redis 6

Facciamo un uso massiccio di Redis in molte parti di Discourse, sia per la cache, Sidekiq, MessageBus, che per i Distributed Locks e i Rate Limits. Nel complesso, è stato una scelta estremamente solida per noi.

Tuttavia, in alcuni carichi di lavoro molto specifici, Redis potrebbe diventare un collo di bottiglia. E a causa della natura single-thread di Redis, unita alla nostra incapacità di utilizzare più istanze a causa degli script LUA, questo rappresentava un collo di bottiglia difficile da aggirare.

Fortunatamente, Redis 6 introduce il supporto per l’uso di un thread pool per le operazioni di I/O e, durante i nostri test, ha funzionato molto bene con i cluster Discourse limitati da Redis.

Quindi, se state eseguendo su una macchina con molti core CPU e le metriche mostrano che Redis fatica a gestire il carico, ora potete attivare l’uso dei thread per le operazioni di scrittura tramite la sezione params di app.yml:

params:
  redis_io_threads: "4" # 1 disabilita la funzionalità, n>1 utilizza n-1 thread aggiuntivi per le scritture I/O

Immagine più piccola

Abbiamo scelto di distribuire un’immagine container di grandi dimensioni nelle prime fasi del progetto, per rendere più semplice a chi non è tecnico l’esecuzione di Discourse e per gestire tutte le dipendenze necessarie, il versionamento, gli aggiornamenti, ecc.

Detto questo, di recente l’immagine compressa ha superato 1 GB, e questo era un po’ eccessivo.

Quindi, per mitigare l’aumento costante delle dimensioni dell’immagine, abbiamo spostato il codice sorgente di Discourse all’interno dell’immagine: da una copia completa del codice sorgente a un “clone superficiale” (shallow clone) contenente solo la versione più recente del codice.

Questa modifica riduce le dimensioni dell’immagine compressa del 25%, il che si traduce in meno spazio server necessario e rebuild più rapidi quando viene rilasciata una nuova immagine. Dovrebbe anche controllare la crescita dell’immagine nel tempo.

L’abbiamo testato su tests-passed/beta/stable, sia con rebuild che con aggiornamenti web, e non rompe alcun percorso standard. Tuttavia, gli utenti che eseguono operazioni git più esotiche negli hook di app.yml potrebbero dover adattare le loro personalizzazioni.

42 Mi Piace

What happens if anything to the browser experience after such a redis upgrade? Any impact on cached assets? Does this get emptied as a result of the upgrade?

3 Mi Piace

Nothing.

Assets are saved into the local disk or object storage, and cached in the CDN. Redis doesn’t impact it.

The Redis data is kept during the upgrade.

10 Mi Piace

What is the default value? 1?

5 Mi Piace

Yes. It comes from Redis own config file, where 1 means a single thread like the old version.

8 Mi Piace

I’ve got an instance where I have added:

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

And it’s failing to rebuild because:

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

Is there some other hook that I can snag to update the databases count before it tries to migrate or whatever it does?

Hmm. And now after the apparently failed rebuild, I see this in docker logs:

chgrp: invalid group: ‘syslog’

2 Mi Piace

Why do you need more than 1 database?

3 Mi Piace

Multisite. Multiple instances using a single redis. I probably should have used a more generic redis container, but thought I’d stick with yours.

2 Mi Piace

:face_with_raised_eyebrow:

Don’t multisite uses a single database and the standard Redis keyname spaces? AFAIK Redis databases are a thin layer and we have commands that go across their boundaries, so you should not rely on that.

6 Mi Piace

Yeah multisite uses 1 database

3 Mi Piace

Oh. Then not multisite, just multiple instances running on one machine that each need a separate redis. I only upped the default 16 to 50 because I was too lazy to keep tight control over which redis databases were in use.

So I should run a separate redis container for each instance, I guess?

2 Mi Piace

Yes, otherwise you may run into stuff cross-talking.

5 Mi Piace

OH. Darn.

Thankfully, I learned this on a server that’s in use only for testing.

For the other sites, should I just give them a fresh redis and throw away what was scheduled? Do a backup/restore?

FWIW, I’ve not noticed any issues with crosstalk in the past year or so. :man_shrugging: And there is a way to set the DB. .

EDIT: Well, the good news is that I can enter the container, edit redis.conf and restart it and it starts working again.

If you’ve got a hint on how to move a site from DISCOURSE_REDIS_DB: 12 on one redis container to another redis container, I’d love to hear. Or maybe just don’t care about scheduled jobs?

3 Mi Piace

This. Discourse should reasonably survive a Redis flush. Some stuff is lost, but nothing critical.

7 Mi Piace

That’s what I’d though, as I don’t know any way that backups attempt to restore it (but there’s a lot I don’t know). It looks like I could do it like this: Copy all keys from one db to another in redis - Stack Overflow, and it appears to have worked in a test I just did, but it’ll be much easier to adjust my playbook to just create a new redis container and use it.

Thanks.

Now to figure out whether to run those redises on the database server or the web server. . .

3 Mi Piace

Then what is the db_id: 2 in the multisite config refer to?

2 Mi Piace

A deprecated setting:

5 Mi Piace

LOL. Yes, It is indeed confusing!

Thanks. I’m working on a ‘multisite config with lets encrypt and no external reverse proxy’ topic, and when I do that, I’ll clean up the other one as well.

4 Mi Piace

Just make sure to restart unicorn right after that, so it will recreate the scheduled tasks.
You will lose anything that is queued so you need to find a good moment to do this.

6 Mi Piace

Is this still working as it should be? Is there an easy one-liner to discover how large the compressed image is?

1 Mi Piace