Mise à jour de l'image Docker : Redis 6 et taille d'image 25 % plus petite

Nous venons de publier une nouvelle image de conteneur qui sera utilisée lors de votre prochaine commande ./launcher rebuild app. Comme toujours, aucune modification de votre configuration n’est nécessaire si vous avez suivi notre installation standard officielle de Discourse. Cela dit, de nouvelles fonctionnalités devraient aider certaines installations.

Redis 6

Nous utilisons massivement Redis à de nombreux endroits dans Discourse, que ce soit pour le cache, Sidekiq, MessageBus, les verrous distribués ou la limitation du débit. Dans l’ensemble, cela a été un choix extrêmement fiable pour nous.

Cependant, dans certains cas de charge très spécifiques, Redis peut devenir un goulot d’étranglement. En raison de son architecture monothreadée, couplée à notre incapacité à utiliser plusieurs instances en raison de nos scripts LUA, il s’agissait d’un goulot d’étranglement difficile à contourner.

Heureusement, Redis 6 prend en charge l’utilisation d’un pool de threads pour les opérations d’E/S, et lors de nos tests, cela fonctionne très bien avec les clusters Discourse limités par Redis.

Ainsi, si vous exécutez sur une machine disposant de nombreux cœurs CPU et que vos métriques montrent que Redis peine à gérer la charge, vous pouvez désormais opter pour l’utilisation de threads pour les opérations d’écriture via la section des paramètres du fichier app.yml :

params:
  redis_io_threads: "4" # 1 désactive cette option, n>1 utilise n-1 threads supplémentaires pour les écritures E/S

Image plus légère

Nous avions opté pour publier une image de conteneur volumineuse au début du projet afin de faciliter l’exécution de Discourse pour les personnes non techniques et de gérer toutes les dépendances nécessaires, le versionnement, les mises à niveau, etc.

Cela dit, nous avons récemment dépassé 1 Go pour l’image compressée, ce qui était un peu trop.

Afin de mitiger la taille croissante de l’image, nous avons déplacé le code source de Discourse à l’intérieur de l’image : d’une copie complète du code source vers un « clone léger » ne contenant que la version la plus récente du code.

Cette modification réduit la taille de l’image compressée de 25 %, ce qui se traduit par un besoin moindre en espace serveur et des reconstructions plus rapides lorsqu’une nouvelle image est publiée. Cela devrait également limiter la croissance de l’image au fil du temps.

Nous l’avons testé sur les environnements tests-passés/beta/stable, avec des reconstructions et des mises à jour web, et cela ne rompt aucun chemin standard. Cependant, les utilisateurs effectuant des manipulations git plus exotiques via les hooks app.yml devront peut-être adapter leurs personnalisations.

42 « J'aime »

Que se passe-t-il, le cas échéant, avec l’expérience du navigateur après une telle mise à niveau de Redis ? Y a-t-il un impact sur les ressources mises en cache ? Ces dernières sont-elles vidées à la suite de la mise à niveau ?

3 « J'aime »

Rien.

Les ressources sont sauvegardées sur le disque local ou dans un stockage objet, et mises en cache via le CDN. Redis n’a aucun impact là-dessus.

Les données Redis sont conservées pendant la mise à niveau.

10 « J'aime »

Quelle est la valeur par défaut ? 1 ?

5 « J'aime »

Oui. Cela provient du fichier de configuration propre à Redis, où 1 signifie un seul thread, comme dans l’ancienne version.

8 « J'aime »

J’ai un cas où j’ai ajouté :

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

Et la reconstruction échoue avec le message suivant :

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

Existe-t-il un autre hook que je pourrais utiliser pour mettre à jour le nombre de bases de données avant qu’il ne tente une migration ou autre opération ?

Hmm. Et maintenant, après cette reconstruction apparemment échouée, je vois ceci dans les journaux Docker :

chgrp: invalid group: ‘syslog’
2 « J'aime »

Pourquoi avez-vous besoin de plus d’une base de données ?

3 « J'aime »

Multisite. Plusieurs instances utilisant un seul Redis. J’aurais probablement dû utiliser un conteneur Redis plus générique, mais j’ai pensé rester sur le vôtre.

2 « J'aime »

:face_with_raised_eyebrow:

N’utilise pas multisite une base de données unique et les espaces de noms Redis standards ? À ma connaissance, les bases de données Redis ne sont qu’une fine couche et nous avons des commandes qui traversent leurs frontières, donc vous ne devriez pas vous fier à cela.

6 « J'aime »

Oui, le multisite utilise une seule base de données.

3 « J'aime »

Ah. Donc pas de multisite, mais simplement plusieurs instances tournant sur une seule machine, chacune ayant besoin de son propre Redis. J’ai seulement augmenté la valeur par défaut de 16 à 50 parce que j’étais trop paresseux pour garder un contrôle strict sur quelles bases de données Redis étaient utilisées.

Donc, je devrais lancer un conteneur Redis séparé pour chaque instance, je suppose ?

2 « J'aime »

Oui, sinon vous risquez d’avoir des interférences entre les instances.

5 « J'aime »

Oh. Zut.

Heureusement, j’ai appris cela sur un serveur utilisé uniquement pour les tests.

Pour les autres sites, devrais-je simplement leur fournir une nouvelle instance Redis et jeter ce qui était planifié ? Ou faire une sauvegarde/restauration ?

Pour information, je n’ai remarqué aucun problème d’interférence au cours de la dernière année ou deux. :man_shrugging: Et il existe un moyen de définir la base de données.

EDIT : Eh bien, la bonne nouvelle est que je peux entrer dans le conteneur, modifier redis.conf, le redémarrer, et tout redevient opérationnel.

Si vous avez une astuce pour déplacer un site de DISCOURSE_REDIS_DB: 12 sur un conteneur Redis vers un autre conteneur Redis, j’aimerais beaucoup l’entendre. Ou peut-être ne vous souciez-vous tout simplement pas des tâches planifiées ?

3 « J'aime »

Exactement. Discourse devrait raisonnablement survivre à un effacement de Redis. Certaines choses sont perdues, mais rien de critique.

7 « J'aime »

C’est ce que je pensais, car je ne connais aucun moyen par lequel les sauvegardes tentent de le restaurer (mais il y a beaucoup de choses que j’ignore). On dirait que je pourrais le faire comme ceci : https://stackoverflow.com/questions/23222616/copy-all-keys-from-one-db-to-another-in-redis, et cela semble avoir fonctionné lors d’un test que je viens de réaliser. Cependant, il sera beaucoup plus simple d’ajuster mon playbook pour créer un nouveau conteneur Redis et l’utiliser.

Merci.

Maintenant, je dois déterminer s’il faut exécuter ces Redis sur le serveur de base de données ou sur le serveur web…

3 « J'aime »

Alors, à quoi fait référence db_id: 2 dans la configuration multisite ?

2 « J'aime »

Un paramètre obsolète :

5 « J'aime »

LOL. Oui, c’est en effet déroutant !

Merci. Je travaille sur un sujet concernant une « configuration multisite avec Let’s Encrypt et sans proxy inverse externe », et quand j’aurai terminé, je nettoierai l’autre sujet également.

4 « J'aime »

Assurez-vous simplement de redémarrer Unicorn juste après, afin qu’il recrée les tâches planifiées.
Vous perdrez tout ce qui est en file d’attente, vous devez donc trouver un bon moment pour le faire.

6 « J'aime »

Cela fonctionne-t-il toujours comme prévu ? Existe-t-il une commande simple en une ligne pour découvrir la taille de l’image compressée ?

1 « J'aime »