Explications · deux
Un téléchargement qui se passe parfaitement est le cas facile, et tous les clients le gèrent correctement. Les différences intéressantes apparaissent quand une partie du post manque, ce qui arrive bien plus souvent que le cas propre ne le laisse croire. Voici ce qui se passe réellement, et pourquoi cela coûte tant de temps.
La forme du problème
Un post Usenet n'est pas un fichier. Ce sont des milliers de petits articles, stockés indépendamment sur les serveurs de chaque fournisseur, et le NZB que vous téléchargez est la liste de leurs noms. Une sortie de 6.5 GB en compte environ 9,000.
Des articles disparaissent pour des raisons ordinaires. Les fournisseurs les conservent pendant une durée de rétention fixe puis les suppriment. Certains fournisseurs n'ont jamais reçu tel article au départ, parce que la propagation entre serveurs est imparfaite. Il arrive qu'un envoi ait été incomplet au moment de sa publication, et qu'une partie n'ait jamais existé nulle part. Quelle qu'en soit la cause, l'effet est le même : votre client demande un article, et la réponse est un refus plutôt que des données.
C'est assez courant pour que les personnes qui publient sur Usenet le prévoient. Presque chaque sortie est accompagnée de données de parité, en général des fichiers PAR2, c'est-à-dire de l'information redondante calculée à partir de l'original. Si une partie du contenu manque, la parité peut la reconstruire, à condition d'en avoir assez. Un post type porte environ 10% de parité, si bien qu'il peut perdre une bonne fraction de lui-même et rester parfaitement récupérable.
Un post endommagé n'est donc pas en général un téléchargement cassé. C'est un téléchargement qui demande un peu d'arithmétique avant d'être complet. La seule question est le temps que met un client à s'en apercevoir, et c'est là qu'ils diffèrent d'un facteur deux ou plus.
La partie coûteuse
Quand un serveur n'a pas un article, il renvoie un refus, et le client essaie alors le serveur suivant de votre liste. C'est la bonne chose à faire, parce que le deuxième fournisseur l'a très souvent. Le coût apparaît quand personne ne l'a.
Dans ce cas le client parcourt toute votre liste de fournisseurs, un serveur à la fois, et se fait refuser par chacun d'eux avant de pouvoir conclure que l'article a vraiment disparu. Le parcours est séquentiel, et les refus sont plus lents qu'on ne le suppose. Nous les avons mesurés directement, sur une ligne au repos, sans aucun contenu en transit :
| fournisseur | temps de réponse à une requête normale | temps pour refuser un article manquant |
|---|---|---|
| Fournisseur A | 77.5 ms | 78.8 ms |
| Fournisseur B | 10.5 ms | 454 ms |
| Fournisseur C | 10.8 ms | 871 ms |
| Fournisseur D | 9.9 ms | 1,227 ms |
| Fournisseur E | 10.6 ms | 2,239 ms |
Deux choses ressortent. D'abord, l'écart est énorme : un refus coûte entre 79 ms et 2.2 secondes selon le fournisseur qui répond, une différence de près de trente fois. Ensuite, un fournisseur refuse en pratiquement le temps qu'il faut pour demander, tandis qu'un autre met plus de deux cents fois son propre temps de réponse normal pour dire non. Ce n'est pas de la latence réseau, c'est du travail qui se fait de leur côté, et demander en moins d'allers-retours n'aide guère.
Faites le total : un parcours complet de cinq fournisseurs, pour un seul article qui n'existe plus, coûte environ 5 secondes. Songez maintenant qu'un post endommagé compte beaucoup d'articles de ce genre, et qu'un client qui les traite en séquence paie ce coût de façon répétée pendant que votre connexion reste inoccupée. Le téléchargement n'est pas lent parce que les données arrivent lentement. Elles ont cessé d'arriver, et le client attend qu'on lui dise ce qu'il a déjà de quoi déduire.
La solution
L'idée n'est pas de rendre les refus plus rapides, car nous ne contrôlons pas les fournisseurs. Elle est de remarquer le moment où la réponse n'a plus d'importance.
À tout instant d'un téléchargement, le client sait deux choses : combien de morceaux manquent encore à l'appel, et quelle quantité de données de parité il détient déjà. Si la parité en main suffit à reconstruire tout ce qui reste en suspens, alors la réponse à « quelqu'un a-t-il cet article ? » ne peut plus changer l'issue. Que ce soit un oui lent ou un non lent, le fichier sera reconstruit de toute façon. Poursuivre le parcours n'achète rien d'autre que du retard.
La version actuelle arrête donc de demander à ce moment-là et passe directement à la réparation. La reconstruction elle-même est rapide et l'a toujours été : environ 2.3 secondes sur un post de 6.5 GB, et ce chiffre est le même dans toutes les versions que nous avons mesurées. Le temps gagné, c'est entièrement l'attente qui n'a plus lieu.
| post de 6.5 GB, 60 articles manquants | temps jusqu'à un fichier vérifié |
|---|---|
| attendre le refus de chaque fournisseur | 23 s |
| s'arrêter dès que la parité couvre le trou | 13 s |
| dont l'arithmétique de réparation proprement dite | 2.3 s |
Le même changement ne fait absolument rien sur un post intact, ce qui est la preuve la plus claire qu'il fait bien ce que nous pensons : sans article manquant il n'y a pas de parcours à écourter, et les deux versions terminent une tâche propre de 6.5 GB en 7 secondes identiques.
C'est un compromis, pas un gain gratuit. Réparer tôt signifie garder les données de parité en mémoire au lieu de les jeter et d'en rechercher plus tard, si bien que la mémoire de pointe (RSS) sur un post lourdement endommagé passe d'environ 0.8 GB à environ 1.3 GB, et que nous tirons environ 400 MB de plus des fournisseurs. Sur un post intact la mémoire est inchangée, à 0.24 GB. Nous pensons que c'est le bon compromis pour la plupart des gens, puisque la mémoire n'est dépensée que dans le cas où elle vous fait gagner dix secondes, mais c'est un coût réel et il existe un réglage pour cela.
Les noms des fournisseurs sont volontairement tus dans le tableau des refus. Ces chiffres sont la propriété d'une mesure, un soir, depuis un seul endroit, et un fournisseur qui indexe autrement, ou que nous avons touché un mauvais soir, ne devrait pas être étiqueté lent sur la foi d'une seule série. Ce qui compte pour l'argument, c'est la forme : les refus varient énormément, et le total est assez gros pour dominer un téléchargement endommagé. Les chiffres par fournisseur et la sortie brute des sondes sont dans nos archives internes, et les chiffres de bout en bout qu'ils expliquent sont sur la page des benchmarks.