Forklaret · to
Et download, der går perfekt, er det lette tilfælde, og enhver klient klarer det kompetent. De interessante forskelle dukker op, når en del af opslaget mangler, og det sker langt oftere, end det rene tilfælde lader ane. Her står, hvad der faktisk foregår, og hvorfor det koster så meget tid.
Problemets form
Et Usenet-opslag er ikke én fil. Det er tusindvis af små artikler, hver især gemt uafhængigt på hver udbyders servere, og den NZB, du henter, er en liste over deres navne. En udgivelse på 6.5 GB er omtrent 9,000 af dem.
Artikler forsvinder af helt almindelige grunde. Udbydere gemmer dem i en fast opbevaringsperiode og sletter dem så. Nogle udbydere modtog aldrig en bestemt artikel til at begynde med, fordi udbredelsen mellem servere er ufuldkommen. Nu og da var en upload ufuldstændig, da den blev lagt op, og en del af den fandtes aldrig nogen steder. Uanset årsagen er virkningen den samme: din klient beder om en artikel, og svaret er en afvisning i stedet for data.
Det er normalt nok til, at de, der lægger op på Usenet, regner med det. Næsten enhver udgivelse følges af paritetsdata, som regel PAR2-filer, altså ekstra overflødig information beregnet ud fra originalen. Mangler en del af indholdet, kan pariteten genskabe det, forudsat at du har nok af den. Et typisk opslag bærer omkring 10% paritet, så et opslag kan miste en pæn bid af sig selv og stadig være fuldt ud til at redde.
Et beskadiget opslag er derfor sjældent et ødelagt download. Det er et download, der kræver lidt regnearbejde, før det er færdigt. Spørgsmålet er kun, hvor lang tid en klient bruger på at regne det ud, og dér adskiller de sig med en faktor to eller mere.
Den dyre del
Når en server ikke har en artikel, returnerer den en afvisning, og klienten prøver så den næste server på din liste. Det er det rigtige at gøre, for den anden udbyder har den meget ofte. Prisen viser sig, når ingen har den.
I det tilfælde går klienten hele din udbyderliste igennem, én server ad gangen, og bliver afvist af hver eneste, før den kan slutte, at artiklen virkelig er væk. Gennemgangen er sekventiel, og afvisninger er langsommere, end folk går ud fra. Vi målte dem direkte, på en hvilende linje, uden at noget indhold overhovedet bevægede sig:
| udbyder | tid til at besvare en almindelig forespørgsel | tid til at afvise en manglende artikel |
|---|---|---|
| Udbyder A | 77.5 ms | 78.8 ms |
| Udbyder B | 10.5 ms | 454 ms |
| Udbyder C | 10.8 ms | 871 ms |
| Udbyder D | 9.9 ms | 1,227 ms |
| Udbyder E | 10.6 ms | 2,239 ms |
To ting springer i øjnene. For det første er spredningen enorm: en afvisning koster et sted mellem 79 ms og 2.2 sekunder afhængigt af hvilken udbyder der svarer, en forskel på næsten tredive gange. For det andet afviser én udbyder stort set på den tid, det tager at spørge, mens en anden bruger mere end to hundrede gange sin egen normale svartid på at sige nej. Det er ikke netværksforsinkelse, det er arbejde, der foregår hos dem, og at spørge i færre tur-retur hjælper næsten ikke.
Læg det sammen: en fuld gennemgang af fem udbydere koster for én enkelt artikel, der ikke længere findes, omkring 5 sekunder. Overvej så, at et beskadiget opslag har mange sådanne artikler, og at en klient, der behandler dem i rækkefølge, betaler den pris igen og igen, mens din forbindelse ligger stille. Downloadet er ikke langsomt, fordi data kommer langsomt. Data er holdt helt op med at komme, og klienten venter på at få fortalt det, den allerede har oplysninger nok til at regne ud.
Løsningen
Indsigten er ikke at gøre afvisninger hurtigere, for vi bestemmer ikke over udbyderne. Den er at bemærke, hvornår svaret ikke længere betyder noget.
På ethvert tidspunkt under et download ved klienten to ting: hvor mange stykker der stadig mangler, og hvor mange paritetsdata den allerede har. Rækker pariteten i hånden til at genopbygge alt det udestående, kan svaret på, om nogen har denne artikel, ikke længere ændre udfaldet. Uanset om det er et langsomt ja eller et langsomt nej, bliver filen genopbygget alligevel. At fortsætte gennemgangen køber intet andet end forsinkelse.
Det nuværende build holder derfor op med at spørge på det punkt og går direkte til reparation. Selve genopbygningen er hurtig og har altid været det: omkring 2.3 sekunder på et opslag på 6.5 GB, og det tal er det samme i hver eneste version, vi har målt. Den sparede tid er udelukkende den ventetid, der ikke længere finder sted.
| opslag på 6.5 GB, 60 manglende artikler | tid til en verificeret fil |
|---|---|
| vente på at hver udbyder afviser | 23 s |
| stoppe så snart pariteten dækker hullet | 13 s |
| heraf selve reparationsregnestykket | 2.3 s |
Den samme ændring gør absolut intet på et ubeskadiget opslag, hvilket er det klareste bevis på, at den gør det, vi tror: uden manglende artikler er der ingen gennemgang at afkorte, og de to builds gennemfører en ren opgave på 6.5 GB på identiske 7 sekunder.
Det er en byttehandel, ikke en gratis gevinst. At reparere tidligt betyder at holde paritetsdata i hukommelsen frem for at smide dem væk og hente mere senere, så spidsbelastningen af hukommelse (RSS) på et hårdt beskadiget opslag stiger fra omkring 0.8 GB til omkring 1.3 GB, og vi henter cirka 400 MB mere hos udbyderne. På et ubeskadiget opslag er hukommelsen uændret på 0.24 GB. Vi mener, det er den rigtige byttehandel for de fleste, eftersom hukommelsen kun bruges i det tilfælde, hvor den giver dig ti sekunder, men det er en reel omkostning, og der findes en indstilling for den.
Udbydernavnene er bevidst udeladt i afvisningstabellen. Tallene er egenskaben ved én måling en aften fra ét sted, og en udbyder, der indekserer anderledes, eller som vi tilfældigvis ramte på en dårlig aften, bør ikke stemples som langsom på grundlag af én enkelt omgang. Det, der betyder noget for argumentet, er formen: afvisninger varierer voldsomt, og summen er stor nok til at dominere et beskadiget download. Tallene pr. udbyder og de rå måledata ligger i vores interne optegnelser, og de tal fra ende til anden, de forklarer, står på benchmarksiden.