Projet

Général

Profil

Development #23045

parallélisation du migrate_schema

Ajouté par Thomas Noël il y a environ 6 ans. Mis à jour il y a plus d'un an.

Statut:
En cours
Priorité:
Bas
Assigné à:
-
Catégorie:
-
Version cible:
-
Début:
09 avril 2018
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Permettre que les migrations se passent en parallèle, avec un nombre de process paramétrable.


Fichiers

Historique

#1

Mis à jour par Thomas Noël il y a environ 6 ans

Idées en vrac :
  • soit des options de migrate_schema, soit une nouvelle commande dédiée pour ne pas tout mélanger
  • permettre de passer un nombre de processus max en ligne de commande, ou dans les settings, sinon par défaut nombre de coeurs
  • utilisation de https://docs.python.org/2/library/multiprocessing.html (imap_unordered)
  • si possible permettre le démarrage «dès que possible» des workers uwsgi :
    • préparer la migration en posant un "on-maintenance.lock" sur tous tenants
    • avoir un retour 503 dans hobo.multitenant.middleware.TenantMiddleware sur un tenant tant que ce lock existe, cela "ferme" le tenant
    • quand la migration d'un tenant est terminée, libérer le lock (ie supprimer le fichier), le middleware fait alors son boulot normal, le tenant est ouvert
    • ça demande que cette commande manage de migration rende la main aussitôt que les locks sont posés, et travaille en tâche de fond, laissant le lancement de uwsgi se faire, qui attendra la libération des tenants un par un
    • étudier au passage comment NE PAS lancer les cron sur les tenants lockés (voire, autre sujet, quand le serveur uwsgi n'est pas lancé)
#2

Mis à jour par Benjamin Dauvergne il y a environ 6 ans

Thomas Noël a écrit :

  • étudier au passage comment NE PAS lancer les cron sur les tenants lockés (voire, autre sujet, quand le serveur uwsgi n'est pas lancé)

Je me dis qu'on pourrait utiliser des locks explicites postgres plutôt que de passer par le FS (et ça résoud le problème quand on a plusieurs front en plus): https://www.postgresql.org/docs/9.4/static/explicit-locking.html

#3

Mis à jour par Benjamin Dauvergne il y a environ 6 ans

Thomas Noël a écrit :

  • ça demande que cette commande manage de migration rende la main aussitôt que les locks sont posés, et travaille en tâche de fond, laissant le lancement de uwsgi se faire, qui attendra la libération des tenants un par un
  • étudier au passage comment NE PAS lancer les cron sur les tenants lockés (voire, autre sujet, quand le serveur uwsgi n'est pas lancé)
En fait on aurait rien besoin de locker si on s'astreignait à une certain discipline car il y a deux types de migrations :
  • ajout de tables ou de colonnes
  • suppressions de tables ou de colonnes
Si on ordonnait systématiquement les migrations d'ajout avant les suppression on pourrait avoir le processus suivant:
  • appliquer les ajouts
  • relancer les serveurs et les crons sur le nouveau code
  • appliquer les suppressions

Dans cet ordre là il n'est pas nécessaire de locker tout peut se faire en parallèle, il peut y avoir un peu de contention entre les migrations et le code de l'application (cron ou uwsg) mais nos migrations étant généralement assez courtes je ne crois pas qu'on ait des contentions importantes.

À voir comment on pourrait automatiser ce fonctionnement.

#4

Mis à jour par Thomas Noël il y a environ 6 ans

Benjamin Dauvergne a écrit :

En fait on aurait rien besoin de locker si on s'astreignait à une certain discipline car il y a deux types de migrations :
  • ajout de tables ou de colonnes
  • suppressions de tables ou de colonnes

Je pense qu'il y a aussi les renommages (sans doute à gérer en premier) et sans doute d'autres choses encore. Mais je n'arrive pas à voir comment on peut séparer les choses dans Django sauf à mettre les doigts dans le code de migration. Ou bien je rate qqchose ?

#5

Mis à jour par Frédéric Péters il y a plus de 5 ans

C'est peut-être nouveau de django-tenant-schemas mais je vois maintenant tenant_schemas/migration_executors/parallel.py et dans ce fichier :

    def run_tenant_migrations(self, tenants):
        if tenants:
            processes = getattr(settings, 'TENANT_PARALLEL_MIGRATION_MAX_PROCESSES', 2)
            chunks = getattr(settings, 'TENANT_PARALLEL_MIGRATION_CHUNKS', 2)
#7

Mis à jour par Frédéric Péters il y a plus de 5 ans

2017. Et du coup chez nous ça a fait partie de #18178.

#8

Mis à jour par Thomas Noël il y a plus de 5 ans

Un patch qui ajoute l'option executor, extraite de django-tenant-schemas. Au passage ça fait nettoyer des trucs pour du Django < 1.8.

La parallelisation se fait alors via « migrate_schemas --executor=parallel » sachant que par défaut j'ai posé une limite à 4 workers * 2 chunks (cf variables TENANT_PARALLEL_MIGRATION_* dans debian_config_common.py, par défaut c'est 2*2)

#9

Mis à jour par Benjamin Dauvergne il y a environ 5 ans

  • Assigné à mis à Thomas Noël
#10

Mis à jour par Benjamin Dauvergne il y a environ 5 ans

  • Statut changé de Solution proposée à Solution validée

À rebaser, repousser pour test mais ça m'a l'air ok; vérifier au passage que les tests multitenant prennent bien en compte le paramétrage pour le parallélisme.

#11

Mis à jour par Thomas Noël il y a environ 4 ans

  • Statut changé de Solution validée à En cours
  • Priorité changé de Normal à Bas

Ce patch serait à revoir (rebaser, au moins) et notamment voir s'il est toujours efficace au regard des optimisations dans django >= 1.11.

#12

Mis à jour par Thomas Noël il y a plus d'un an

  • Tags mis à accessible
  • Assigné à Thomas Noël supprimé

Thomas Noël a écrit :

Ce patch serait à revoir (rebaser, au moins) et notamment voir s'il est toujours efficace au regard des optimisations dans django >= 1.11.

Aujourd'hui le nombre de tenant a explosé et un retour sur ce ticket serait bienvenu. Le patch doit être plus facile encore aujourd'hui avec les nettoyages qui ont eu lieu depuis.

#13

Mis à jour par Thomas Noël il y a plus d'un an

  • Tags accessible supprimé

J'ai regardé quand même et après #29522 je pense qu'on ne peut plus profiter de l'executor aussi facilement... je retire le tag "accessible".

Formats disponibles : Atom PDF