Retour au blog

Stabilité de la collecte de données à grande échelle : les problèmes révélés par le passage à l’échelle

Une collecte peut être stable sur dix cibles puis perdre en fiabilité sur des milliers. Classification des échecs et déduplication, limitation de débit et concurrence, reprise, défaillances de sortie réseau, contrôles de cohérence et quelques métriques clés deviennent critiques à grande échelle.

Un script de collecte peut fonctionner sans problème sur dix cibles puis voir son taux de réussite chuter lorsqu’il passe à des milliers. On ajoute des tentatives, on change de proxy, on ajuste la concurrence, mais les mêmes problèmes reviennent. En allant plus loin, le blocage vient souvent non pas de la logique d’analyse, mais de plusieurs couches d’ingénierie qui n’ont pas été mises en place. À petite échelle, ces problèmes peuvent rester invisibles.

Classer les échecs avant de relancer

Les échecs sont inévitables dans la collecte de données. L’essentiel est de les classer : une instabilité réseau ou une réinitialisation de connexion peut être retentée immédiatement ; une limitation temporaire doit être suivie d’un backoff avant une nouvelle tentative ; si un changement de structure de page produit un résultat d’analyse vide, même dix mille tentatives ne serviront à rien, il faut enregistrer le cas et déclencher une alerte ; si la cible n’existe pas, il suffit de marquer la tâche comme terminée ; si un environnement ou une sortie réseau ne démarre pas, on en change puis on réessaie.

Tout relancer indistinctement est l’une des erreurs les plus faciles à commettre. Cela masque dans des boucles des problèmes qui nécessitent une intervention humaine tout en gaspillant quotas et capacité de sortie. Le backoff est également indispensable : l’intervalle entre les tentatives doit augmenter, sinon tout un lot de tâches reviendra dans la même fenêtre de temps et aggravera encore la limitation.

Les nouvelles tentatives amènent directement à la déduplication. Une tâche peut être exécutée plusieurs fois à cause des retries ; chaque tâche doit donc disposer d’un identifiant unique et stable, par exemple la valeur obtenue après normalisation de l’URL, et les écritures en base doivent être idempotentes selon cet identifiant. Sinon, davantage de tentatives signifie simplement davantage de données sales.

Limitation de débit et concurrence sont deux sujets distincts

Augmenter la concurrence ne garantit pas une hausse du débit. Trois contraintes agissent en même temps : ce que le site cible peut supporter avant que la limitation réduise le débit global, la mémoire et le CPU de la machine locale, et la capacité d’un même environnement ou d’une même session à exécuter plusieurs tâches simultanément.

Une approche plus stable consiste à commencer avec une faible concurrence puis à augmenter progressivement la charge, en observant ensemble le taux de réussite et le temps de réponse afin d’identifier le point où les performances se dégradent nettement. La limitation de débit est un autre mécanisme : elle règle le rythme d’accès à une même cible et ne se confond pas avec la concurrence globale. Si un lot répartit ses requêtes sur plusieurs sites, chaque site doit avoir son propre rythme.

La reprise repose sur la persistance de l’état

Pour une tâche qui dure plusieurs heures, une interruption est normale ; repartir de zéro coûte souvent trop cher. Il faut donc persister l’état : en attente, en cours, terminé, ainsi que le nombre de tentatives, la prochaine heure d’exécution autorisée et le type d’erreur. Au démarrage du processus, la file doit être relue depuis le stockage au lieu d’être reconstruite en mémoire.

Garder la file uniquement en mémoire est une implémentation très courante qui semble fonctionner. Dès que le processus s’arrête, toutes les tâches en attente disparaissent et les comptes ne correspondent plus.

Traiter séparément les pannes de proxy et de sortie réseau

Une sortie bloquée par la cible, un proxy hors ligne ou un nœud régional qui dérive sont des événements récurrents à grande échelle. Ce ne sont pas des exceptions, mais des conditions normales. Traitez les sorties comme des ressources remplaçables : lorsqu’une tâche échoue, déterminez d’abord si la cible limite le débit ou si la sortie est indisponible ; dans le premier cas, appliquez un backoff, dans le second, changez de sortie puis réessayez. Enregistrez aussi le taux d’échec de chaque sortie afin de retirer les groupes qui se dégradent clairement.

À l’inverse, si toutes les tâches partagent une seule sortie, une seule tâche peut dégrader la liaison et affecter toutes les suivantes. Le diagnostic impose alors de remonter les journaux pour identifier la tâche à l’origine du problème.

Vérifier la cohérence des données

Une exécution réussie ne garantit pas des données correctes. Après écriture, il faut pouvoir répondre à quelques questions : le nombre de tâches terminées correspond-il au nombre de lignes enregistrées, quelle part des résultats d’analyse est vide, le taux de champs critiques manquants a-t-il augmenté anormalement, combien de lignes sont dupliquées ?

Ces contrôles n’ont pas besoin d’être complexes. Un échantillonnage par lot suffit, mais quelqu’un doit regarder les résultats. À grande échelle, des données erronées peuvent être plus problématiques que l’absence de données.

Quelles métriques surveiller

Inutile de multiplier les métriques. Quelques indicateurs capables de refléter la santé du système suffisent.

  • Taux de réussite et répartition des types d’échec, pour voir quelles erreurs augmentent
  • Longueur de la file et temps d’attente moyen ; une accumulation qui progresse en continu signale un déséquilibre entre entrée et capacité de traitement
  • Nombre d’environnements actifs et de processus associés ; une croissance durable dans un seul sens indique souvent une fuite dans la libération des ressources
  • Production par unité de temps, pour déterminer si la limitation de débit freine le throughput
  • Taux d’échec des sorties, pour décider s’il faut remplacer un groupe de nœuds

Si l’une de ces métriques évolue durablement dans un seul sens, vérifiez d’abord la libération des ressources et la logique de retry.

Isoler la couche d’environnement

Mis ensemble, ces éléments mènent à la même conclusion : la couche d’environnement doit être gérée indépendamment des scripts. La mise en pool impose que les environnements puissent être planifiés de façon centralisée plutôt que dispersés dans chaque script ; la libération des ressources exige un état interrogeable plutôt qu’un mécanisme de secours propre à chaque script ; changer d’environnement ou de sortie lors d’un retry n’est possible que si les environnements peuvent être planifiés indépendamment.

Les scripts gèrent la logique ; la couche d’environnement gère les ressources et l’identité. Dans ce type d’architecture, PurpleMark occupe cette couche en fournissant des ressources d’environnement pouvant être créées par lots, associées à des sorties réseau indépendantes et interrogées sur leur état.

Limites de conformité

La capacité à passer à l’échelle ne signifie pas que l’on peut collecter librement. Respectez les règles robots et les conditions de service du site cible, ne collectez pas d’informations personnelles, ne contournez pas les mesures techniques de protection et contrôlez la fréquence des requêtes afin de ne pas perturber le service normal. La stabilité est une question technique ; l’autorisation de collecter en est une autre. Les deux doivent être respectées.