Erklärt · zwei
Ein Download, der glatt läuft, ist der leichte Fall, und jeder Client bewältigt ihn ordentlich. Die interessanten Unterschiede zeigen sich, wenn ein Teil des Posts fehlt, und das kommt weit häufiger vor, als der saubere Fall vermuten lässt. Hier steht, was dabei tatsächlich vorgeht und warum es so viel Zeit kostet.
Die Gestalt des Problems
Ein Usenet-Post ist keine einzelne Datei. Er besteht aus Tausenden kleiner Artikel, jeder unabhängig auf den Servern jedes Providers abgelegt, und die NZB, die du lädst, ist eine Liste ihrer Namen. Eine 6.5 GB große Veröffentlichung sind rund 9,000 davon.
Artikel gehen aus alltäglichen Gründen verloren. Provider halten sie eine feste Vorhaltezeit lang und löschen sie dann. Manche Provider haben einen bestimmten Artikel von vornherein nie erhalten, weil die Verbreitung zwischen Servern unvollkommen ist. Gelegentlich war ein Upload beim Posten unvollständig, und ein Teil davon existierte nirgends. Was auch immer die Ursache ist, die Wirkung ist dieselbe: dein Client fragt nach einem Artikel, und die Antwort ist eine Ablehnung statt Daten.
Das ist so normal, dass die Leute, die ins Usenet posten, damit rechnen. Fast jede Veröffentlichung bringt Paritätsdaten mit, meist PAR2-Dateien, also zusätzliche redundante Information, die aus dem Original berechnet wurde. Fehlt ein Teil der Nutzdaten, kann Parität ihn rekonstruieren, sofern genug davon da ist. Ein typischer Post führt etwa 10% Parität mit, ein Post kann also einen beachtlichen Teil von sich verlieren und bleibt vollständig wiederherstellbar.
Ein beschädigter Post ist also meist kein kaputter Download. Er ist ein Download, der vor der Fertigstellung etwas Rechnerei verlangt. Die Frage ist nur, wie lange ein Client braucht, um das herauszufinden, und genau darin unterscheiden sie sich um den Faktor zwei oder mehr.
Der teure Teil
Hat ein Server einen Artikel nicht, gibt er eine Ablehnung zurück, und der Client versucht dann den nächsten Server auf deiner Liste. Das ist richtig so, denn der zweite Provider hat ihn sehr oft. Der Preis zeigt sich, wenn ihn niemand hat.
Dann geht der Client deine gesamte Providerliste durch, Server für Server, und wird von jedem einzelnen abgewiesen, bevor er schließen kann, dass der Artikel wirklich weg ist. Der Durchgang ist seriell, und Ablehnungen sind langsamer, als man annimmt. Wir haben sie direkt gemessen, auf einer ruhenden Leitung, ohne dass irgendwelche Nutzdaten flossen:
| Provider | Zeit für die Antwort auf eine normale Anfrage | Zeit, einen fehlenden Artikel abzulehnen |
|---|---|---|
| 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 |
Zwei Dinge stechen hervor. Erstens ist die Spanne enorm: eine Ablehnung kostet irgendetwas zwischen 79 ms und 2.2 Sekunden, je nachdem welcher Provider antwortet, ein Unterschied von fast dem Dreißigfachen. Zweitens lehnt ein Provider praktisch in der Zeit ab, die das Fragen dauert, während ein anderer mehr als das Zweihundertfache seiner eigenen normalen Antwortzeit braucht, um nein zu sagen. Das ist keine Netzwerklatenz, das ist Arbeit auf ihrer Seite, und in weniger Umläufen zu fragen hilft kaum.
Rechne es zusammen: ein vollständiger Durchgang über fünf Provider kostet für einen einzigen Artikel, den es nicht mehr gibt, etwa 5 Sekunden. Nun bedenke, dass ein beschädigter Post viele solcher Artikel hat und dass ein Client, der sie der Reihe nach abarbeitet, diesen Preis wieder und wieder zahlt, während deine Verbindung untätig daliegt. Der Download ist nicht langsam, weil die Daten langsam ankommen. Sie kommen gar nicht mehr an, und der Client wartet darauf, dass man ihm sagt, was er längst selbst erschließen könnte.
Die Lösung
Die Einsicht besteht nicht darin, Ablehnungen schneller zu machen, denn die Provider kontrollieren wir nicht. Sie besteht darin, den Moment zu bemerken, in dem die Antwort keine Rolle mehr spielt.
In jedem Augenblick eines Downloads weiß der Client zweierlei: wie viele Stücke noch fehlen und wie viele Paritätsdaten er bereits hält. Reicht die vorhandene Parität, um alles noch Ausstehende neu aufzubauen, dann kann die Antwort auf „hat irgendwer diesen Artikel?“ das Ergebnis nicht mehr ändern. Ob langsames Ja oder langsames Nein, die Datei wird so oder so wiederhergestellt. Den Durchgang fortzusetzen bringt nichts außer Verzögerung.
Der aktuelle Build hört an dieser Stelle also auf zu fragen und geht direkt zur Reparatur über. Die Rekonstruktion selbst ist schnell und war es immer: etwa 2.3 Sekunden bei einem 6.5 GB großen Post, und diese Zahl ist in jeder von uns gemessenen Version gleich. Die eingesparte Zeit ist vollständig das Warten, das nun entfällt.
| Post mit 6.5 GB, 60 fehlende Artikel | Zeit bis zur geprüften Datei |
|---|---|
| auf die Ablehnung jedes Providers warten | 23 s |
| aufhören, sobald die Parität die Lücke deckt | 13 s |
| davon die eigentliche Reparaturrechnung | 2.3 s |
Dieselbe Änderung bewirkt bei einem unbeschädigten Post überhaupt nichts, was der klarste Beleg dafür ist, dass sie tut, was wir denken: ohne fehlende Artikel gibt es keinen Durchgang abzukürzen, und beide Builds beenden einen sauberen 6.5 GB-Auftrag in identischen 7 Sekunden.
Es ist ein Tausch, kein Gratisgewinn. Früh zu reparieren heißt, die Paritätsdaten im Speicher zu halten, statt sie zu verwerfen und später mehr zu holen, also steigt die Speicherspitze (RSS) bei einem schwer beschädigten Post von etwa 0.8 GB auf etwa 1.3 GB, und wir ziehen rund 400 MB mehr von den Providern. Bei einem unbeschädigten Post bleibt der Speicher unverändert bei 0.24 GB. Wir halten das für die meisten Leute für den richtigen Tausch, da der Speicher nur in dem Fall ausgegeben wird, in dem er dir zehn Sekunden bringt, aber es ist ein echter Preis, und es gibt eine Einstellung dafür.
Die Providernamen bleiben in der Ablehnungstabelle bewusst ungenannt. Diese Zahlen sind das Ergebnis einer Messung an einem Abend von einem Ort, und ein Provider, der anders indexiert oder den wir zufällig an einem schlechten Abend erwischt haben, sollte nicht aufgrund einer einzigen Runde als langsam abgestempelt werden. Für das Argument zählt die Gestalt: Ablehnungen schwanken enorm, und die Summe ist groß genug, um einen beschädigten Download zu beherrschen. Die Zahlen je Provider und die rohe Messausgabe liegen in unseren internen Aufzeichnungen, und die Ende-zu-Ende-Zahlen, die sie erklären, stehen auf der Benchmark-Seite.