Conception de file d'attente de tâches de compression : traitement asynchrone Celery+Redis

Conclusion d'abord : la solution standard pour l'asynchronisation des tâches de compression est la file d'attente Celery + Redis. L'architecture centrale est Producer (FastAPI envoie les tâches) → Broker (Redis stocke temporairement) → Worker (Celery consomme et appelle le moteur de compression Rust) → Backend (Redis stocke les résultats). Pour la compression par lot de 10 000 fichiers, avec un partitionnement de 100 fichiers par lot et 12 Workers concurrents, l'ensemble peut être terminé en environ 40 minutes. Les points de conception clés sont le partitionnement des tâches, les files prioritaires, la reprise par backoff exponentiel et la file de lettres mortes comme filet de sécurité. Commençons par l'architecture de la file, avec le tableau des paramètres de configuration Celery et la solution complète.

Si vous n'êtes pas encore familier avec le déploiement global du service de compression, nous vous recommandons de lire d'abord le Guide complet de déploiement Docker du service de compression.

I. Pourquoi les tâches de compression nécessitent-elles une file asynchrone

La compression de fichiers est une tâche typique à la fois CPU-intensive et IO-intensive. La compression d'un PDF de 100 Mo peut prendre 5 à 15 secondes ; avec une interface synchrone, la connexion HTTP reste suspendue longtemps, et la capacité de concurrence sur une seule machine est très faible. La file asynchrone découple la « soumission » de l'« exécution » : le client soumet la tâche et obtient immédiatement un task_id, le Worker compresse en arrière-plan, et le résultat est retourné par callback ou par interrogation une fois terminé.

Mode de traitementCapacité de concurrenceLatence de réponseGestion des échecsÉchelle applicable
Traitement synchroneFaible (bloque la connexion HTTP)5–60 secondesPas de reprise, erreur directe<10 fichiers
Pool de threadsMoyenne (limitée par le nombre de threads)1–5 secondesImplémentation manuelle requise10–100 fichiers
File asynchrone CeleryÉlevée (scaling horizontal des Workers)<200msReprise automatique + file de lettres mortes100–100 000 fichiers
Kubernetes + fileTrès élevée (autoscaling HPA)<100msSystème de tolérance aux pannes complet>100 000 fichiers

SmartSlim Network Edition adopte l'architecture FastAPI + Celery + Redis + MinIO, avec 12 tâches concurrentes stables sur une seule machine. En déploiement Kubernetes, le HPA peut ajuster automatiquement entre 3 et 10 réplicas. Cette architecture prend déjà en charge les besoins de compression de plusieurs clients entreprises avec un volume quotidien de l'ordre de la dizaine de milliers de fichiers.

II. Architecture détaillée de la file d'attente de tâches Celery

La file d'attente de tâches Celery se compose de quatre rôles centraux : Producer (producteur), Broker (courtier de messages), Worker (processus de travail), Backend (stockage des résultats). Comprendre les responsabilités de ces quatre couches est essentiel pour configurer correctement la file de tâches de compression.

ComposantChoix techniqueResponsabilitéConfiguration clé
ProducerFastAPIReçoit les requêtes HTTP, construit les tâches, envoie au Brokertask.apply_async(queue=...)
BrokerRedis 7.xStocke temporairement les messages de tâches en attente, prend en charge les files prioritairesbroker_url, visibility_timeout
WorkerCelery 5.xConsomme les tâches, appelle le moteur de compression Rustconcurrency, prefork pool
BackendRedisStocke le statut des tâches et les résultats retournésresult_backend, result_expires
StockageMinIOStocke les fichiers originaux et compressésProtocole compatible S3, téléversement partitionné

1. Tableau des paramètres de configuration centraux de Celery

La configuration de Celery détermine directement le débit et la stabilité de la file. Le tableau ci-dessous présente la configuration recommandée pour les scénarios de compression, validée dans l'environnement de production de SmartSlim.

ParamètreValeur recommandéeDescription
broker_urlredis://:password@redis:6379/0Redis comme courtier de messages, DB isolée pour éviter les conflits
result_backendredis://:password@redis:6379/1Stockage des résultats sur DB isolée, séparée du Broker
task_serializerjsonSérialisation JSON, compatibilité multilangue
result_serializerjsonRésultats également en JSON
accept_content['json']Accepte uniquement JSON, durcissement de sécurité
timezoneAsia/ShanghaiFuseau horaire unifié
task_acks_lateTrueACK seulement après exécution, aucune tâche perdue en cas de crash
worker_prefetch_multiplier1Chaque Worker ne pré-fetch qu'1 tâche, évite la famine des tâches longues
task_time_limit600Timeout matériel 600 secondes par tâche
task_soft_time_limit540Timeout logiciel 540 secondes, déclenche SoftTimeLimitExceeded
task_reject_on_worker_lostTrueRejette la tâche si le Worker s'arrête anormalement, remet en file
result_expires86400Résultats automatiquement nettoyés après 24 heures

2. Conception des files prioritaires

Les tâches de compression ont des priorités différentes : les requêtes de compression soumises en temps réel par les utilisateurs nécessitent une réponse rapide, tandis que les tâches d'archivage planifiées peuvent s'exécuter lentement. Les files prioritaires Redis permettent une planification différenciée — les tâches haute priorité sont consommées en premier par les Workers.

Nom de filePrioritéRègle de routageTâche type
compression_high9 (la plus élevée)Requête utilisateur en temps réelCompression immédiate d'un fichier unique
compression_normal5 (par défaut)Tâche par lotCompression par lot 100–500 fichiers
compression_low1 (la plus basse)Archivage planifiéArchivage complet nocturne
dlq_queue— (lettre morte)Tâches ayant échoué après repriseInvestigation manuelle ou traitement de compensation

III. Étude de cas : compression asynchrone de 10 000 fichiers

Scénario d'archivage de données d'entreprise : 10 000 documents historiques (mix PDF/Word/images, moyenne 8 Mo par fichier, total environ 80 Go) nécessitent une compression et un archivage unifiés. Exigence : terminer en moins d'1 heure, taux de compression ≥ 60 %.

Conception de la solution : Partitionnement en 100 sous-tâches de 100 fichiers chacune, envoi en lot via Celery group, 12 Workers consommant en parallèle. Chaque sous-tâche appelle en série le moteur de compression Rust pour compresser 100 fichiers.

Paramètres d'exécution et performances de débit :

IndicateurParamètreValeur mesuréeDescription
Nombre total de fichiers10 000Formats mixtes, moyenne 8 Mo/fichier
Granularité de partitionnement100 fichiers/lot100 sous-tâchesÉquilibre coût de gestion et coût de reprise
Concurrence Workers12Mode preforkMachine 12 cœurs CPU
Temps de compression par fichierMoyenne 3,2 secondesMoteur Rust niveau medium
Temps par lotEnviron 5,3 minutes100 fichiers en série
Temps totalEnviron 44 minutes100 lots/12 concurrents
Taux de compression67,3 %80 Go → 26,2 Go
Nombre d'échecs17Fichiers corrompus, en file de lettres mortes après reprise

Résultat : 10 000 fichiers compressés en 44 minutes, taux de compression 67,3 %, 17 fichiers corrompus automatiquement dirigés vers la file de lettres mortes pour traitement manuel. L'architecture globale est stable, pic d'utilisation CPU à 89 %, pic de mémoire à 4,2 Go, aucun OOM ni perte de tâche.

3. Stratégie de reprise et file de lettres mortes

Les échecs de tâches de compression se divisent en deux catégories : erreurs temporaires (timeout IO, mémoire insuffisante, concurrence excessive) et erreurs déterministes (fichier corrompu, format non pris en charge). Les erreurs temporaires ont de fortes chances de réussir après reprise, les erreurs déterministes sont inutiles à reprendre. Le tableau ci-dessous présente la stratégie de décision.

Type d'erreurException typeStratégieTentativesDestination finale
Temporaire-IOConnectionError, TimeoutErrorReprise par backoff exponentiel3Succès ou file de lettres mortes
Temporaire-ressourceMemoryError, OOMKilledBackoff étendu + dégradation2Succès ou file de lettres mortes
Déterministe-fichierFileCorrupted, ParseErrorPas de reprise, lettre morte directe0dlq_queue
Déterministe-formatUnsupportedFormatPas de reprise, lettre morte directe0dlq_queue
Déterministe-permissionPermissionDeniedPas de reprise, alerte0dlq_queue + alerte

La configuration de reprise utilise autoretry_for et retry_backoff de Celery, backoff initial 60 secondes, maximum 600 secondes, avec gigue aléatoire pour éviter l'effet d'avalanche. Les tâches de la file de lettres mortes sont scannées régulièrement par une tâche de surveillance indépendante, déclenchant des alertes WeChat Work/DingTalk pour informer les opérations.

Indicateur de surveillanceMéthode de collecteSeuil d'alerteAction
File d'attente en arrièreRedis LLEN>500Déclenche l'extension des Workers
Taux d'échec des tâchesCelery events>5%Analyse des journaux + pause d'envoi
Longueur de la file de lettres mortesRedis LLEN dlq>10Alerte WeChat Work
Workers en vieCelery inspect<10Redémarrage automatique des Workers
Temps moyen par tâcheSurveillance Flower>30 secondesVérification gros fichiers + dégradation
Utilisation CPUnode_exporter>95%Limitation de débit + extension

Pour les méthodes d'appel complètes de l'API de compression, consultez le Guide d'appel de l'API de compression : conception d'interface REST.

IV. Recommandations de configuration de file par scénario

Les différents scénarios métier ont des exigences différentes en matière de débit, de latence et de fiabilité. La configuration de la file doit être différenciée. Le tableau ci-dessous présente les configurations recommandées pour les scénarios courants.

ScénarioWorkersGranularitéFile prioritaireStratégie de reprise
Compression immédiate personnelle2Pas de partitionnementhighReprise rapide 3 fois
Archivage par lot entreprise12100 fichiers/lotnormal/lowBackoff exponentiel 3 fois
Traitement gouvernemental confidentiel450 fichiers/lothighReprise stricte + audit
Images plateforme e-commerce16200 fichiers/lotnormalReprise rapide 2 fois
Archivage planifié nocturne8500 fichiers/lotlowBackoff lent 5 fois
Transcodage vidéo en temps réel24Fichier uniquehighPas de reprise, alerte en cas d'échec

Un principe général : les scénarios en temps réel utilisent une file haute priorité + petit partitionnement + reprise rapide, les scénarios par lot utilisent une file normale + grand partitionnement + backoff exponentiel, les scénarios confidentiels utilisent un audit strict + petit partitionnement + reprise multi-niveaux. Pour la solution complète de compression par lot au niveau entreprise, consultez Solution de compression par lot entreprise : traitement de dizaines de milliers de fichiers en pratique.

V. Questions fréquentes (FAQ)

Q1 : Comment implémenter le traitement asynchrone des tâches de compression avec Celery ?

Construisez une file d'attente de tâches asynchrone avec Celery + Redis : FastAPI reçoit la requête et envoie la tâche au Broker Redis, le Worker Celery consomme la tâche depuis le Broker et appelle le moteur de compression Rust pour exécuter la compression, le résultat est écrit dans le Backend et le stockage MinIO. Un simple task.apply_async permet l'exécution asynchrone, et le statut est consulté via task.id. Avec 12 Workers concurrents sur une machine, 10 000 fichiers partitionnés en 100 lots peuvent être traités en 40 minutes.

Q2 : Comment relancer automatiquement les tâches de compression échouées ?

Configurez la reprise automatique avec le paramètre autoretry_for de Celery : max_retries=3, retry_backoff=True (backoff exponentiel, délai initial 60 secondes), retry_backoff_max=600 secondes, retry_jitter=True (gigue aléatoire pour éviter l'effet d'avalanche). Les tâches échouant après 3 tentatives sont automatiquement routées vers la file de lettres mortes dlq_queue, traitées manuellement ou par une tâche de compensation. Recommandation : reprendre les erreurs temporaires (timeout IO/mémoire insuffisante), envoyer directement en file de lettres mortes les erreurs déterministes (fichier corrompu/format non pris en charge).

Q3 : Comment partitionner la compression par lot de 10 000 fichiers ?

Partitionnez par 100 fichiers par lot, soit 100 sous-tâches. Utilisez Celery group ou chord pour l'envoi en lot, 12 Workers consomment en parallèle, chaque sous-tâche compresse 100 fichiers en série. Le temps moyen de compression par fichier est de 3 secondes, environ 5 minutes par lot, et 100 lots en parallèle permettent de terminer en environ 40 minutes. Une granularité trop fine (1 fichier par lot) augmente le coût de gestion, trop grande (1000 fichiers par lot) augmente le coût de reprise en cas d'échec — 100 est la valeur optimale empirique.

Q4 : Celery ou RQ : lequel est plus adapté à la file d'attente de tâches de compression ?

Celery est recommandé pour les tâches de compression. Celery prend en charge le partitionnement des tâches (group/chord), les files prioritaires, les tâches planifiées, les chaînes de tâches et les files de lettres mortes — un ensemble complet ; RQ est plus léger mais manque de partitionnement et de priorité. Les scénarios de compression nécessitent fréquemment le partitionnement par lot, la planification prioritaire et la reprise en cas d'échec, tous nativement pris en charge par Celery. En termes de performances, les deux reposent sur Redis avec un débit équivalent. SmartSlim Network Edition adopte l'architecture FastAPI + Celery + Redis + MinIO, avec 12 tâches concurrentes stables sur une machine.

Résumé

La solution standard pour l'asynchronisation des tâches de compression est la file d'attente Celery + Redis, dont le cœur réside dans le découplage des quatre couches Producer/Broker/Worker/Backend. Pour la compression par lot de dizaines de milliers de fichiers, avec un partitionnement de 100 fichiers, 12 Workers concurrents, l'ensemble peut être terminé en environ 40 minutes, avec un taux de compression de 60 % à 70 %. La stratégie de reprise doit distinguer les erreurs temporaires (reprise par backoff exponentiel) des erreurs déterministes (file de lettres mortes directe), complétée par 6 indicateurs de surveillance pour garantir la stabilité de la file.

Retenez trois points : premièrement, task_acks_late=True garantit qu'aucune tâche n'est perdue en cas de crash ; deuxièmement, worker_prefetch_multiplier=1 évite la famine des tâches longues ; troisièmement, la file de lettres mortes doit obligatoirement être associée à une surveillance et des alertes. Avec la bonne architecture de file et la bonne stratégie de partitionnement, le débit et la stabilité du service de compression feront un bond en avant.

Besoin de compresser des fichiers ? Essayez SmartSlim

Construit sur un moteur de compression Rust auto-développé, prenant en charge 10 catégories et plus de 40 formats, dont PDF, images, vidéo, Office et OFD, avec une compression locale qui garde vos données sur place.