Gå til indhold
AutoValue
17. oktober 2026 · Data Quality

Ugen hvor vi nær tabte 84.000 annoncer til en fejl, vi gav proxyerne skylden for

AutoValue Editorial
Ugen hvor vi nær tabte 84.000 annoncer til en fejl, vi gav proxyerne skylden for

14. september

Vi havde ventet i ugevis på denne dag. Vores udbyder af residential-proxyer var gået i sort efter en fejlslagen betaling tilbage i juli, og i to måneder kørte en stadig større del af vores 1.375 kilder degraderet eller slet ikke – forespørgsler der timede ud, IP-adresser der blev blokeret midt i en session, den slags langsomme udblødning der ikke viser sig som en outage, men nærmere som et tal der langsomt krymper, uden at nogen bemærker det, før det er pinligt. Vi fornyede. Ny pulje, 20.000 roterende residential session-linjer, hver exit afprøvet før noget kom nær produktion. 100% af afprøvningen bestod. AE, DE, JP – alle live, alle rene.

Så kørte vi en overvåget crawl, af den slags hvor man faktisk holder øje med dashboardet i stedet for at stole på cron-jobbet. Jeg forventede det modsatte af en katastrofe.

Det vi fik, var en database der havde tabt 84.401 rækker i ét enkelt hug, med 102 kilder der var faldet mere end 25% fra deres forrige snapshot. Værre end de to måneder med proxy-udhungring, vi lige havde løst.

Den forkerte teori, kort fortalt

Min første instinkt – og det vil jeg gerne lige stå ved – var, at den nye pulje på en eller anden måde var værre end afprøvningen antydede. Måske blev session-IP'erne rate-limited midt i crawlet på en måde, en engangsafprøvning ikke ville opdage. Det er en rimelig teori. Den er også forkert, og at tro på den i selv en halv dag kostede os tid, vi ikke havde, fordi crawl-cron'en forbliver pauset, hele tiden man fejlsøger en teori som den – man vil ikke have, at et dårligt pass overskriver et godt snapshot, mens man stadig gætter.

Det, der afkræftede teorien, var dubizzle. En af vores kilder med størst volumen i UAE havde rent faktisk hentet 32.595 annoncer under det pass – et helt sundt tal, proxyerne fungerede klart – og derefter kasseret næsten alle sammen. Ikke fejlet i at hente. Hentet, og så smidt væk.

16. september: fejlen findes

Det var der, det stoppede med at være en proxy-historie og blev en historie om udskiftning af rækker. Vores persistenslag tager et snapshot af hver kilde som en fuld overskrivning af <site>_cars_for_sale.csv hver eneste gang – kun de aktuelle annoncer, hele tabellen udskiftes. Det er korrekt adfærd, når et crawl afsluttes. Det er katastrofalt, når et crawl timer ud midtvejs, og scraperen skriver den partielle batch, den nåede at samle, som om det var det fuldstændige snapshot. En kilde, der normalt har 9.000 aktive annoncer, bliver overskrevet med de 1.200, den nåede at skrabe før tiden løb ud, og de andre 7.800 forsvinder – ikke fordi bilerne blev solgt, men fordi vores egen kode besluttede, at en ufuldstændig hentning var en fuldstændig.

Proxyerne lyver ikke for os. Retry-logikken var problemet, og den havde været stille og roligt dårlig i lang tid, blot maskeret af en sundere pulje, der tidligere plejede at afslutte hentningerne, før sweepet fik betydning.

Her er, hvad det sweep faktisk kostede, da vi lavede regnestykket:

Gammelt retry-sweepRettet sweep
Gentagelser per proxy31
Forsinkelse per forsøg1s—
Effektivt loft over en pulje på 50 proxyer~56 minutter per URL120 sekunders total budget
Adfærd ved timeoutskriver partiel batch som fuldt snapshotkilde springes over, forrige snapshot bevares

Seksoghalvtreds minutter om at give op på en enkelt URL. Multiplicer det over et crawl, der berører over tusind kilder, og man får præcis den slags stille, ujævnt fordelte fejl, vi så – nogle kilder fint, 102 af dem udhulet, intet i logfilerne der skriger "proxy-outage", fordi der, teknisk set, ikke var en.

25. september: løsningen, og den del der betyder noget for dig

Den patch, der blev udrullet ni dage senere, gjorde to uglamorøse ting. Den satte et loft over retry-matematikken, så en fastsiddende hentning fejler hurtigt i stedet for at æde det meste af en time, og – det er den, der rent faktisk forhindrer datatabet – en partiel hentning udskifter ikke længere det fulde sæt rækker. Hvis en kilde kun kommer igennem 1.200 af sine sædvanlige 9.000 annoncer, bevarer vi det forrige komplette snapshot i stedet for at overskrive det med en brøkdel. Samme dag landede en anden ændring, der skriver et synligt CRAWL_PAUSED-flag, som vores overvågning tjekker, før den tilkalder nogen om et dyk – så en bevidst pause læses som en pause, ikke som en alarm.

Hvorfor skulle en læser, der shopper efter en brugt Hyundai, interessere sig for noget af dette? Fordi de under-markeds-flag, vi offentliggør – 12.823 af dem live på siden fra denne uge – kun er ærlige, hvis den gruppe, vi sammenligner en annonce med, er det reelle, komplette regionale marked og ikke et timeout-afkortet fragment af det. Et godt-køb-badge bygget mod et snapshot, der har tabt tre fjerdedele af sit sammenligningssæt, er ikke et godt-køb-badge, det er støj med et grønt mærke på. Vi vil hellere pause et crawl i ni dage end at offentliggøre det.

Datasættet står i dag på 1.108.535 annoncer fordelt på 73 regioner og 1.375 kilder – større end det var, før alt dette startede, proxyer fornyet og fejlen med udskiftning af rækker lukket. Men det tal, jeg bliver ved med at vende tilbage til, er ikke totalen. Det er 84.401 – forskellen mellem et crawl, der så sundt ud på proxy-niveau, og et der faktisk var det.

Data QualityWEB ScrapingCrawl ReliabilityBelow Market Deals
Del

Relaterede artikler