Förklarat · två

Varför skadade poster spelar roll

En nedladdning som går perfekt är det lätta fallet, och varje klient hanterar det kompetent. De intressanta skillnaderna dyker upp när en del av posten saknas, vilket sker långt oftare än det rena fallet låter ana. Det här är vad som faktiskt pågår, och varför det kostar så mycket tid.

Problemets form

Vad en saknad artikel är

En Usenet-post är inte en fil. Den är tusentals små artiklar, var och en lagrad självständigt på varje leverantörs servrar, och NZB-filen du laddar ned är en lista över deras namn. En utgåva på 6.5 GB är ungefär 9,000 av dem.

Artiklar försvinner av vardagliga skäl. Leverantörer behåller dem under en fast lagringstid och raderar dem sedan. Vissa leverantörer tog aldrig emot en viss artikel från början, eftersom spridningen mellan servrar är ofullkomlig. Ibland var en uppladdning ofullständig när den publicerades, och en del av den fanns aldrig någonstans. Vad orsaken än är blir följden densamma: din klient ber om en artikel, och svaret är ett avslag i stället för data.

Det är så normalt att de som publicerar på Usenet räknar med det. Nästan varje utgåva följs av paritetsdata, vanligen PAR2-filer, alltså extra redundant information beräknad ur originalet. Saknas en del av innehållet kan pariteten återskapa det, förutsatt att du har tillräckligt. En typisk post bär omkring 10% paritet, så en post kan förlora en rejäl bit av sig själv och ändå vara fullt räddningsbar.

En skadad post är alltså oftast inte en trasig nedladdning. Det är en nedladdning som kräver lite räknande innan den är komplett. Frågan är bara hur lång tid en klient tar på sig att lista ut det, och där skiljer de sig med en faktor två eller mer.

Den dyra delen

Att fråga efter något ingen har

När en server inte har en artikel svarar den med ett avslag, och klienten prövar då nästa server i din lista. Det är rätt sak att göra, för den andra leverantören har den mycket ofta. Kostnaden dyker upp när ingen har den.

I det fallet går klienten igenom hela din leverantörslista, en server i taget, och får avslag av var och en innan den kan sluta sig till att artikeln verkligen är borta. Genomgången är sekventiell, och avslag är långsammare än folk antar. Vi mätte dem direkt, på en vilande lina, utan att något innehåll rörde sig alls:

leverantörtid att besvara en vanlig begärantid att avslå en saknad artikel
Leverantör A77.5 ms78.8 ms
Leverantör B10.5 ms454 ms
Leverantör C10.8 ms871 ms
Leverantör D9.9 ms1,227 ms
Leverantör E10.6 ms2,239 ms

Två saker sticker ut. För det första är spridningen enorm: ett avslag kostar någonstans mellan 79 ms och 2.2 sekunder beroende på vilken leverantör som svarar, en skillnad på nästan trettio gånger. För det andra avslår en leverantör i stort sett på den tid det tar att fråga, medan en annan tar mer än tvåhundra gånger sin egen normala svarstid på att säga nej. Det är inte nätverksfördröjning, det är arbete som sker på deras sida, och att fråga i färre vändor hjälper knappt.

Lägg ihop det: en fullständig genomgång av fem leverantörer kostar, för en enda artikel som inte längre finns, omkring 5 sekunder. Betänk nu att en skadad post har många sådana artiklar, och att en klient som behandlar dem i följd betalar den kostnaden gång på gång medan din förbindelse står stilla. Nedladdningen är inte långsam för att data kommer långsamt. Data har slutat komma helt, och klienten väntar på att få veta det den redan har nog med information för att räkna ut.

Lösningen

Sluta fråga, och reparera i stället

Insikten är inte att göra avslagen snabbare, för leverantörerna rår vi inte över. Den är att märka när svaret inte längre spelar någon roll.

I varje ögonblick under en nedladdning vet klienten två saker: hur många bitar som fortfarande saknas, och hur mycket paritetsdata den redan har. Räcker pariteten den håller för att bygga upp allt som återstår, kan svaret på frågan om någon har den här artikeln inte längre ändra utfallet. Vare sig det är ett långsamt ja eller ett långsamt nej byggs filen upp ändå. Att fortsätta genomgången köper inget annat än fördröjning.

Nuvarande bygge slutar alltså fråga vid den punkten och går rakt på reparation. Själva återuppbyggnaden är snabb och har alltid varit det: omkring 2.3 sekunder på en post på 6.5 GB, och den siffran är densamma i varje version vi mätt. Den sparade tiden är helt och hållet väntan som inte längre sker.

post på 6.5 GB, 60 saknade artiklartid till en verifierad fil
vänta på att varje leverantör avslår23 s
sluta så snart pariteten täcker luckan13 s
varav själva reparationsräkningen2.3 s

Samma ändring gör ingenting alls på en oskadad post, vilket är det tydligaste beviset på att den gör det vi tror: utan saknade artiklar finns ingen genomgång att korta av, och de två byggena avslutar ett rent jobb på 6.5 GB på identiska 7 sekunder.

Det är en avvägning, inte en gratis vinst. Att reparera tidigt innebär att hålla paritetsdata i minnet i stället för att kasta dem och hämta mer senare, så toppminnet (RSS) på en svårt skadad post stiger från omkring 0.8 GB till omkring 1.3 GB, och vi drar ned ungefär 400 MB mer från leverantörerna. På en oskadad post är minnet oförändrat på 0.24 GB. Vi tycker att det är rätt avvägning för de flesta, eftersom minnet bara används i det fall där det ger dig tio sekunder, men det är en verklig kostnad och det finns en inställning för den.

Leverantörsnamnen utelämnas medvetet i avslagstabellen. Siffrorna tillhör en mätning en kväll från en plats, och en leverantör som indexerar på annat sätt, eller som vi råkade nå en dålig kväll, ska inte stämplas som långsam på grundval av en enda omgång. Det som betyder något för resonemanget är formen: avslag varierar enormt, och summan är stor nog att dominera en skadad nedladdning. Siffrorna per leverantör och den råa mätutskriften finns i våra interna anteckningar, och siffrorna från början till slut som de förklarar finns på benchmarksidan.