Uitgelegd · twee
Een download die vlekkeloos verloopt is het makkelijke geval, en elke client handelt dat vaardig af. De interessante verschillen komen boven wanneer een deel van de post ontbreekt, en dat gebeurt veel vaker dan het schone geval doet vermoeden. Dit is wat er werkelijk aan de hand is, en waarom het zoveel tijd kost.
De vorm van het probleem
Een Usenet-post is niet één bestand. Het zijn duizenden kleine artikelen, elk apart opgeslagen op de servers van elke provider, en de NZB die je downloadt is een lijst van hun namen. Een release van 6.5 GB bestaat uit ruwweg 9,000 daarvan.
Artikelen raken zoek om gewone redenen. Providers bewaren ze een vaste bewaartermijn en verwijderen ze daarna. Sommige providers hebben een bepaald artikel om te beginnen nooit ontvangen, omdat de verspreiding tussen servers onvolmaakt is. Af en toe was een upload onvolledig toen hij werd geplaatst, en heeft een deel ervan nergens ooit bestaan. Wat de oorzaak ook is, het gevolg is hetzelfde: je client vraagt om een artikel, en het antwoord is een weigering in plaats van gegevens.
Dit is gewoon genoeg dat de mensen die op Usenet plaatsen er rekening mee houden. Bijna elke release komt met pariteitsgegevens ernaast, meestal PAR2-bestanden, oftewel extra overtollige informatie berekend uit het origineel. Ontbreekt er een deel van de inhoud, dan kan pariteit het herbouwen, mits je er genoeg van hebt. Een typische post draagt zo'n 10% pariteit met zich mee, dus een post kan een flink deel van zichzelf kwijtraken en toch volledig te redden zijn.
Een beschadigde post is dus meestal geen kapotte download. Het is een download die wat rekenwerk vergt voordat hij compleet is. De enige vraag is hoe lang een client erover doet om dat uit te vogelen, en juist daar verschillen ze met een factor twee of meer.
Het dure deel
Wanneer een server een artikel niet heeft, geeft hij een weigering terug, en de client probeert dan de volgende server op je lijst. Dat is de juiste zet, want de tweede provider heeft het heel vaak wel. De kosten verschijnen wanneer niemand het heeft.
In dat geval loopt de client je hele providerlijst af, server voor server, en wordt door elk van hen geweigerd voordat hij kan concluderen dat het artikel echt weg is. Dat aflopen gebeurt op volgorde, en weigeringen zijn trager dan mensen aannemen. We hebben ze rechtstreeks gemeten, op een rustende lijn, zonder dat er ook maar iets aan inhoud bewoog:
| provider | tijd om een gewoon verzoek te beantwoorden | tijd om een ontbrekend artikel te weigeren |
|---|---|---|
| Provider A | 77.5 ms | 78.8 ms |
| Provider B | 10.5 ms | 454 ms |
| Provider C | 10.8 ms | 871 ms |
| Provider D | 9.9 ms | 1,227 ms |
| Provider E | 10.6 ms | 2,239 ms |
Twee dingen springen eruit. Ten eerste is de spreiding enorm: een weigering kost ergens tussen 79 ms en 2.2 seconden, afhankelijk van welke provider antwoordt, een verschil van bijna dertig keer. Ten tweede weigert de ene provider in ongeveer de tijd die het kost om te vragen, terwijl een andere meer dan tweehonderd keer zijn eigen normale antwoordtijd nodig heeft om nee te zeggen. Dat is geen netwerkvertraging, dat is werk dat aan hun kant gebeurt, en in minder heen-en-weer vragen helpt nauwelijks.
Tel het op: een volledige gang langs vijf providers kost, voor één enkel artikel dat niet meer bestaat, ongeveer 5 seconden. Bedenk nu dat een beschadigde post veel van zulke artikelen heeft, en dat een client die ze op volgorde afhandelt die kosten telkens opnieuw betaalt terwijl je verbinding stilligt. De download is niet traag omdat de gegevens langzaam binnenkomen. Ze komen helemaal niet meer binnen, en de client wacht tot hem verteld wordt wat hij zelf al kan afleiden.
De oplossing
Het inzicht is niet om weigeringen sneller te maken, want de providers hebben wij niet in de hand. Het is om op te merken wanneer het antwoord er niet meer toe doet.
Op elk moment tijdens een download weet de client twee dingen: hoeveel stukken nog vermist zijn, en hoeveel pariteitsgegevens hij al heeft. Is de pariteit in handen genoeg om alles wat nog openstaat te herbouwen, dan kan het antwoord op de vraag of iemand dit artikel heeft de uitkomst niet meer veranderen. Of het nu een traag ja of een traag nee is, het bestand wordt hoe dan ook herbouwd. Doorgaan met aflopen koopt niets dan vertraging.
De huidige build stopt op dat punt dus met vragen en gaat rechtstreeks over op repareren. Het herbouwen zelf is snel en was dat altijd al: ongeveer 2.3 seconden bij een post van 6.5 GB, en dat cijfer is in elke versie die we hebben gemeten hetzelfde. De gewonnen tijd is volledig het wachten dat niet meer plaatsvindt.
| post van 6.5 GB, 60 ontbrekende artikelen | tijd tot een geverifieerd bestand |
|---|---|
| wachten tot elke provider weigert | 23 s |
| stoppen zodra pariteit het gat dekt | 13 s |
| waarvan het eigenlijke reparatierekenwerk | 2.3 s |
Dezelfde verandering doet helemaal niets bij een onbeschadigde post, en dat is het duidelijkste bewijs dat ze doet wat wij denken: zonder ontbrekende artikelen valt er geen gang in te korten, en de twee builds maken een schone taak van 6.5 GB af in een identieke 7 seconden.
Het is een ruil, geen gratis winst. Vroeg repareren betekent de pariteitsgegevens in het geheugen houden in plaats van ze weg te gooien en later meer op te halen, dus stijgt het piekgeheugen (RSS) bij een zwaar beschadigde post van ongeveer 0.8 GB naar ongeveer 1.3 GB, en halen we ruwweg 400 MB meer bij de providers op. Bij een onbeschadigde post blijft het geheugen onveranderd op 0.24 GB. Wij denken dat dat voor de meeste mensen de juiste ruil is, aangezien het geheugen alleen wordt uitgegeven in het geval waarin het je tien seconden oplevert, maar het is een echte kostenpost en er is een instelling voor.
De providernamen worden in de weigeringstabel bewust weggelaten. Die cijfers zijn de eigenschap van één meting op één avond vanaf één plek, en een provider die anders indexeert, of die we toevallig op een slechte avond troffen, hoort op grond van één ronde niet als traag te worden bestempeld. Wat voor het betoog telt is de vorm: weigeringen lopen enorm uiteen, en het totaal is groot genoeg om een beschadigde download te overheersen. De cijfers per provider en de ruwe meetuitvoer staan in onze interne administratie, en de cijfers van begin tot eind die ze verklaren staan op de benchmarkpagina.