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 traitement | Capacité de concurrence | Latence de réponse | Gestion des échecs | Échelle applicable |
|---|---|---|---|---|
| Traitement synchrone | Faible (bloque la connexion HTTP) | 5–60 secondes | Pas de reprise, erreur directe | <10 fichiers |
| Pool de threads | Moyenne (limitée par le nombre de threads) | 1–5 secondes | Implémentation manuelle requise | 10–100 fichiers |
| File asynchrone Celery | Élevée (scaling horizontal des Workers) | <200ms | Reprise automatique + file de lettres mortes | 100–100 000 fichiers |
| Kubernetes + file | Très élevée (autoscaling HPA) | <100ms | Systè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.
| Composant | Choix technique | Responsabilité | Configuration clé |
|---|---|---|---|
| Producer | FastAPI | Reçoit les requêtes HTTP, construit les tâches, envoie au Broker | task.apply_async(queue=...) |
| Broker | Redis 7.x | Stocke temporairement les messages de tâches en attente, prend en charge les files prioritaires | broker_url, visibility_timeout |
| Worker | Celery 5.x | Consomme les tâches, appelle le moteur de compression Rust | concurrency, prefork pool |
| Backend | Redis | Stocke le statut des tâches et les résultats retournés | result_backend, result_expires |
| Stockage | MinIO | Stocke les fichiers originaux et compressés | Protocole 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ètre | Valeur recommandée | Description |
|---|---|---|
| broker_url | redis://:password@redis:6379/0 | Redis comme courtier de messages, DB isolée pour éviter les conflits |
| result_backend | redis://:password@redis:6379/1 | Stockage des résultats sur DB isolée, séparée du Broker |
| task_serializer | json | Sérialisation JSON, compatibilité multilangue |
| result_serializer | json | Résultats également en JSON |
| accept_content | ['json'] | Accepte uniquement JSON, durcissement de sécurité |
| timezone | Asia/Shanghai | Fuseau horaire unifié |
| task_acks_late | True | ACK seulement après exécution, aucune tâche perdue en cas de crash |
| worker_prefetch_multiplier | 1 | Chaque Worker ne pré-fetch qu'1 tâche, évite la famine des tâches longues |
| task_time_limit | 600 | Timeout matériel 600 secondes par tâche |
| task_soft_time_limit | 540 | Timeout logiciel 540 secondes, déclenche SoftTimeLimitExceeded |
| task_reject_on_worker_lost | True | Rejette la tâche si le Worker s'arrête anormalement, remet en file |
| result_expires | 86400 | Ré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 file | Priorité | Règle de routage | Tâche type |
|---|---|---|---|
| compression_high | 9 (la plus élevée) | Requête utilisateur en temps réel | Compression immédiate d'un fichier unique |
| compression_normal | 5 (par défaut) | Tâche par lot | Compression par lot 100–500 fichiers |
| compression_low | 1 (la plus basse) | Archivage planifié | Archivage complet nocturne |
| dlq_queue | — (lettre morte) | Tâches ayant échoué après reprise | Investigation 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 :
| Indicateur | Paramètre | Valeur mesurée | Description |
|---|---|---|---|
| Nombre total de fichiers | 10 000 | — | Formats mixtes, moyenne 8 Mo/fichier |
| Granularité de partitionnement | 100 fichiers/lot | 100 sous-tâches | Équilibre coût de gestion et coût de reprise |
| Concurrence Workers | 12 | Mode prefork | Machine 12 cœurs CPU |
| Temps de compression par fichier | — | Moyenne 3,2 secondes | Moteur Rust niveau medium |
| Temps par lot | — | Environ 5,3 minutes | 100 fichiers en série |
| Temps total | — | Environ 44 minutes | 100 lots/12 concurrents |
| Taux de compression | — | 67,3 % | 80 Go → 26,2 Go |
| Nombre d'échecs | — | 17 | Fichiers 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'erreur | Exception type | Stratégie | Tentatives | Destination finale |
|---|---|---|---|---|
| Temporaire-IO | ConnectionError, TimeoutError | Reprise par backoff exponentiel | 3 | Succès ou file de lettres mortes |
| Temporaire-ressource | MemoryError, OOMKilled | Backoff étendu + dégradation | 2 | Succès ou file de lettres mortes |
| Déterministe-fichier | FileCorrupted, ParseError | Pas de reprise, lettre morte directe | 0 | dlq_queue |
| Déterministe-format | UnsupportedFormat | Pas de reprise, lettre morte directe | 0 | dlq_queue |
| Déterministe-permission | PermissionDenied | Pas de reprise, alerte | 0 | dlq_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 surveillance | Méthode de collecte | Seuil d'alerte | Action |
|---|---|---|---|
| File d'attente en arrière | Redis LLEN | >500 | Déclenche l'extension des Workers |
| Taux d'échec des tâches | Celery events | >5% | Analyse des journaux + pause d'envoi |
| Longueur de la file de lettres mortes | Redis LLEN dlq | >10 | Alerte WeChat Work |
| Workers en vie | Celery inspect | <10 | Redémarrage automatique des Workers |
| Temps moyen par tâche | Surveillance Flower | >30 secondes | Vérification gros fichiers + dégradation |
| Utilisation CPU | node_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énario | Workers | Granularité | File prioritaire | Stratégie de reprise |
|---|---|---|---|---|
| Compression immédiate personnelle | 2 | Pas de partitionnement | high | Reprise rapide 3 fois |
| Archivage par lot entreprise | 12 | 100 fichiers/lot | normal/low | Backoff exponentiel 3 fois |
| Traitement gouvernemental confidentiel | 4 | 50 fichiers/lot | high | Reprise stricte + audit |
| Images plateforme e-commerce | 16 | 200 fichiers/lot | normal | Reprise rapide 2 fois |
| Archivage planifié nocturne | 8 | 500 fichiers/lot | low | Backoff lent 5 fois |
| Transcodage vidéo en temps réel | 24 | Fichier unique | high | Pas 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.
Articles connexes
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.