00

Points de contrôle de pratique

Le rythme de l’entretien reste compact, pour que la page consacre son attention aux vraies décisions de conception.

  1. 01
    Clarifier le périmètre
  2. 02
    Besoins + échelle
  3. 03
    API + modèle de données
  4. 04
    Dessiner l’architecture
  5. 05
    Deep dive
  6. 06
    Décision de compromis
01

Les besoins qui façonnent la conception

Ne vous contentez pas d’énoncer les besoins : demandez-les. Chaque carte associe la contrainte de conception à une question de clarification que vous pouvez dire à voix haute avant de dessiner l’architecture.

Besoins fonctionnels

01À quoi sert le crawl — index de recherche, données d'entraînement de LLM, archivage ? Cela fixe la taille et la fraîcheur.

Récupérer les pages à partir des graines et stocker le contenu brut pour un usage en aval — le consommateur définit ce que « terminé » signifie.

02Comment le crawl grandit-il — les liens extraits sont-ils réinjectés ?

Chaque page récupérée est analysée pour en extraire les liens, qui sont filtrés puis réinjectés dans le frontier — le crawl se sustente à partir des graines.

03Politesse : exigence ou simple bonus ?

Une exigence : respecter robots.txt (y compris crawl-delay), s'identifier honnêtement via le user-agent, et ne jamais surcharger un seul hôte.

04Les opérateurs peuvent-ils injecter des graines et des URL prioritaires en cours de crawl ?

Oui. Les opérateurs peuvent pousser des URLs en haute priorité, devant les liens que le crawl trouve tout seul. Un crawl peut être dirigé, pas seulement laissé tourner.

05Que stockons-nous exactement — octets bruts, texte analysé, ou les deux ?

Les deux. Nous gardons le contenu brut dans le blob storage, plus le texte extrait et les métadonnées. Un retraitement ultérieur ne doit jamais signifier récupérer la page à nouveau.

06À quel point robots.txt doit-il être frais ?

Frais en quelques heures : un hôte ne doit jamais être crawlé sur des règles robots.txt vieilles de plus de quelques heures — agir sur une autorisation périmée est un risque de conformité.

Hors périmètreClassement et indexation de recherche (le crawler produit le corpus, pas l'index) · Rendu JavaScript des pages dynamiques · Re-crawl continu pour la fraîcheur (d'abord un seul crawl complet)

Besoins non fonctionnels

01Combien de pages, et à quelle vitesse ?

10B pages en moins de 5 jours — cette seule ligne dicte la taille de la flotte et le débit de la file.

02Qu'est-ce qui protège les sites web que nous crawlons ?

Respecter le crawl-delay de chaque hôte quel que soit le backlog : un million d'URL en file pour un seul site doit s'écouler lentement, jamais comme un flot.

03La même page vit souvent à de nombreuses URL — miroirs, paramètres de suivi, variantes www. Le corpus doit-il garder chaque page une seule fois ?

Ne jamais récupérer deux fois la même URL, et une même page atteinte via des URL différentes ne doit atterrir dans le corpus qu'une seule fois.

04Si une machine plante en cours de crawl, pouvons-nous perdre les URL sur lesquelles elle travaillait, ou chaque URL doit-elle finir par être comptabilisée ?

Rien n'est perdu en silence : chaque URL finit par être récupérée ou explicitement enregistrée comme échouée — le crash d'une machine ne doit jamais faire disparaître du travail.

05Et les espaces d'URL infinis ?

Des plafonds de profondeur, des budgets de pages par domaine et des filtres de motifs d'URL empêchent les pages de calendrier et les fermes de publicités de dévorer le crawl.

Continuez à demander — l’entretien est une conversation

Les vrais entretiens sondent bien plus qu’une liste propre. Ces questions de périmètre séparent ceux qui interrogent le problème de ceux qui le récitent.

  • Combien de temps le corpus récupéré doit-il être conservé, et devons-nous honorer une demande de retrait ou de suppression d'un propriétaire de site ?
  • Y a-t-il un budget de bande passante ou en dollars pour le crawl, ou le délai de 5 jours est-il la seule contrainte ?
  • Avons-nous besoin d'une piste d'audit de ce qui a été récupéré et quand — assez pour prouver que nous avons honoré robots.txt si un propriétaire de site se plaint ?
  • Rendons-nous le JavaScript, ou récupérons-nous uniquement le HTML brut ?
  • Un seul crawl complet suffit-il, ou le corpus a-t-il besoin d'un rafraîchissement continu ?
02

Les chiffres qui forcent les décisions d’architecture

Traitez chaque estimation comme une pression qui justifie un composant : cache, file, partition, réplica, pool de workers ou chemin de repli.

01

Débit de récupération requis

10B pages ÷ 5 jours10,000,000,000 ÷ 432,000 s ≈ 23K pages/s en continu

C'est une flotte, pas un serveur — et le frontier doit distribuer 23K URL par seconde tout en respectant la politesse d'exploration (limitation de débit par hôte).

02

Taille de la flotte

~2 s de latence de récupération moyenne par page, soit ~0,5 pages/s par connexion · ~4K connexions concurrentes utiles par machine23K ÷ (4,000 × 0.5) ≈ 12 machines en continu — prévoir ~2× pour les réessais et les hôtes lents

Une vingtaine de fetchers tiennent l'échéance ; le goulot d'étranglement est la politesse, pas le calcul.

03

Mémoire URL-seen

10B URL dans un filtre de Bloom à 1 % de faux positifs (~10 bits chacune)10B × 10 b ≈ 12 GB — contre ~400 GB pour des chaînes exactes

Ce qui compte, c'est la réponse « certainement nouveau » du Bloom. Un faux positif saute juste une URL. Un faux négatif n'arrive jamais, donc rien n'est jamais crawlé deux fois.

04

Stockage du corpus

10B pages × ~100 KB de HTML stocké — le poids de page de plusieurs Mo souvent cité est surtout des images et des scripts que ce crawler ne récupère jamais≈ 1 PB brut

Stockage blob avec compression ; les métadonnées (hashes, URL) restent interrogeables dans un magasin séparé.

05

Pression DNS

23K récupérations/s nécessitant chacune une résolutionsans cache : 23K résolutions/s · avec cache DNS par fetcher : ~1 par nouvel hôte

Un cache DNS interne à la flotte est obligatoire — les résolveurs publics limiteraient le débit du crawl jusqu'à le tuer.

Exemple de décision

Les chiffres

Vingt-trois mille pages par seconde pendant cinq jours d'affilée. Mais la vraie contrainte va dans l'autre sens : aucun site web ne doit jamais sentir plus qu'un filet d'eau.

Mon choix

Je scinderais la frontier en deux étages. Les front queues ordonnent les URLs par priorité ; les back queues donnent à chaque hôte sa propre file, avec un token bucket par hôte qui respecte le crawl-delay. Les fetchers louent les URLs au lieu de les supprimer, acquittent au succès, et laissent les expirations de bail récupérer des crashes. Une URL passe une vérification seen par Bloom filter avant l'enfilage, et après fetch un hash de contenu attrape la même page atteinte par des URLs différentes. Les règles robots se mettent en cache par domaine avec un TTL, et le DNS a son propre cache dans la flotte.

À éviter

Ce que je NE ferais PAS : utiliser une seule file de priorité globale. Dès qu'un gros site déverse un million d'URLs, les fetchers martèlent cet hôte et le crawl devient un DDoS. Je ne suivrais pas non plus les URLs vues dans une table de base de données exacte. Cela veut dire 400 Go de chaînes et une recherche par enfilage, alors qu'un Bloom filter de 12 Go répond « certainement nouveau » gratuitement. Son rare faux positif ne fait que sauter une URL, ce qui est le bon sens dans lequel se tromper.

Changer si

Si le corpus a besoin d'une fraîcheur continue plutôt que d'un seul crawl, le frontier gagne un planificateur de re-crawl : les pages réentrent selon la fréquence de changement et l'importance, et le filtre seen passe à une structure qui prend en charge le vieillissement.

03

Chemin d’architecture

D’abord une image complète, puis chaque chemin comme son propre schéma — le chemin d’écriture et le chemin de lecture portent un trafic différent et justifient des composants différents.

Image complète

Vue d’ensemble — chaque composant

Seed URLsURL Frontier (2étages)Fetcher FleetParser +ExtractorContent Store(blob)DNS Cache +robots.txtrègles par hôteURL Seen (Bloom)certainement nouvelle ?Content HashDedupmême page, autre URL
  • Les liens extraits bouclent du parser vers le frontier — le crawl se nourrit de ses propres découvertes.
  • À l'intérieur du frontier, chaque hôte reçoit sa propre file, et une URL n'est distribuée qu'au rythme autorisé de cet hôte.
  • La politesse est intégrée à la structure qui distribue les URL — aucun fetcher isolé ne peut inonder un site, même par accident.

Chemin 1

Chemin de récupération — la politesse par conception

Frontier (filepar hôte)Token BucketFetcher (bail)Fetch + vérifrobotsContent Store

Une URL n'est distribuée que lorsque son hôte a un jeton ; le bail retourne dans la file en cas de plantage, les réessais font du backoff, et les échecs répétés atterrissent dans une file dead-letter.

Chemin 2

Chemin de découverte — la boucle qui se nourrit elle-même

ParserLink ExtractorURL Filter(motifs,URL Seen (Bloom)Frontier enqueue

Chaque page produit des liens ; les filtres rejettent les pièges et les déchets, le filtre de Bloom rejette tout ce qui a déjà été vu, et les survivants réentrent dans le frontier.

04

API et modèle de données

Avant d’optimiser, rendez le contrat inspectable : endpoints, entités, propriété, retries et état.

QUEUEfrontier.enqueue(url, depth)

résaccepté · rejeté (déjà vu / filtré / hors budget)

Contrat interne, pas REST — un crawler n'a pas d'API publique. La mise en file passe d'abord le filtre URL-seen et les filtres de motifs.

QUEUEfrontier.lease(fetcher_id) → CrawlTask

réstâche avec bail TTL · ack(task) en cas de succès · nack → réessai avec backoff

Les back-queues par hôte imposent la politesse : un fetcher ne reçoit une URL que lorsque le token bucket de cet hôte a un jeton.

GEThttps://{host}/robots.txt (external)

résrègles mises en cache dans DomainState avec TTL

L'unique contrat externe : respecter Disallow et crawl-delay, et envoyer un User-Agent honnête.

Entités principales

CrawlTask

url · domain · depth · status: queued/leased/done/failed · retries

L'unité de travail ; louée (pas supprimée) pendant qu'un fetcher la traite, pour que les plantages s'auto-réparent.

DomainState

domain (PK) · robots_rules · crawl_delay · last_fetch_at · pages_crawled

Les règles robots sont mises en cache par domaine avec un TTL ; le token bucket vit ici.

Page

url · content_hash (SHA-256) · fetched_at · blob_ref

content_hash alimente la deuxième couche de déduplication — un contenu identique sous des URL différentes n'est stocké qu'une fois.

05

Directions de deep dive

Choisissez une voie pour le dernier tiers de l’entretien. Chaque voie vous donne le sujet, la question de l’examinateur à laquelle répondre, et le mode d’échec à éviter.

Focus

Un million d'URL, un petit site

Question

Le frontier détient un million d'URL pour un site web modeste. Qu'est-ce qui garantit qu'il ne se fait jamais pilonner ?

Réponse

Toutes ces URL vont dans une seule file pour cet hôte. Un token bucket lié au crawl-delay du site les libère une à une, et les fetchers ne peuvent prendre que ce que le bucket accorde. Ajoutez mille machines et cet hôte voit toujours le même filet — c'est la file qui l'impose, pas la bonne volonté.

À éviter

Limiter le débit à l'intérieur des fetchers — la politesse doit être structurelle, dans la file par hôte, sinon une flotte mise à l'échelle la casse.

Focus

Ai-je déjà vu cette URL

Question

Dix milliards d'URL — comment répondez-vous à « déjà vue ? » par mise en file, en mémoire, et que coûte ici un faux positif de Bloom ?

Réponse

Consultez un filtre de Bloom avant chaque mise en file. Dix milliards d'URL à environ 10 bits chacune tiennent dans à peu près 12 Go, contre 400 Go pour des chaînes exactes. Il ne donne jamais de faux négatif, donc rien n'est crawlé deux fois. Un rare faux positif se contente de sauter une URL — le bon sens dans lequel se tromper.

À éviter

Traiter le faux positif comme une erreur — sauter une URL est le coût prévu ; crawler deux fois est l'échec.

Focus

Même page, URL différente

Question

Miroirs, paramètres de suivi, et www/non-www servent tous un contenu identique. Où se situe la deuxième couche de déduplication, et sur quelle clé ?

Réponse

La deuxième couche se place après le fetch, indexée sur un hash de contenu. Hachez le corps de la page et cherchez-le dans un store de hashs déjà vus. En cas de correspondance, gardez une copie canonique et enregistrez l'autre URL comme alias. La normalisation gère les paramètres de tracking et les variantes www ; seul le hash attrape des pages identiques venant d'hôtes différents.

À éviter

La normalisation d'URL seule — seul un hash de contenu attrape les vrais doublons entre hôtes.

Focus

Le calendrier infini

Question

Un site génère à l'infini un lien « mois suivant » valide. Qu'est-ce qui borne le crawl, et comment détectez-vous le piège ?

Réponse

Trois limites s'empilent : un plafond de profondeur, un budget de pages par domaine, et des filtres de motifs d'URL qui repèrent les formes fabriquées par machine comme des dates sans cesse incrémentées. C'est le budget qui fait la vraie détection. Quand un petit domaine consomme des milliers de pages quasi identiques, il est throttlé ou coupé — pour qu'aucun piège ne puisse dévorer le crawl.

À éviter

Se fier à la seule profondeur — les budgets par domaine et les heuristiques de motifs d'URL doivent l'épauler.

Focus

Un fetcher meurt en détenant 4 000 URL

Question

Une machine plante en pleine récupération. Qu'advient-il de son travail en cours, et que coûte la récupération ?

Réponse

Rien n'est perdu, parce que chaque URL était louée, pas supprimée. Quand la machine morte cesse d'accuser réception, ses 4 000 baux expirent et les URL retournent dans la file pour d'autres fetchers. La reprise ne coûte que le délai d'expiration des baux plus le refetch de ce qui était en vol — borné et pas cher.

À éviter

Supprimer une URL de la file au moment de la distribution — louez avec un délai, acquittez à l'achèvement.

Prêt à vous entraîner ?

Expliquez crawler web à voix haute et obtenez une évaluation IA de votre explication.

S’entraîner avec l’IA →