Cet article est la traduction d’un article de Jonathan Lewis publié sur son blog. L’article original en anglais se trouve ici.
J’ai traduit récemment un article de Doug Burns sur un concept très important lorsqu’on étudie les performances d’un système: améliorer le temps de réponse d’un traitement individuel, et améliorer le débit (throughput) d’un ensemble de traitement sont 2 objectifs différents, et souvent contradictoires.
Doug Burns donnait un exemple concret en différenciant la mesure du temps de réponse d’une session individuelle (response time) et la mesure du débit d’une charge globale (throughput). Jonathan Lewis montre ici de manière simple la théorie qu’il y a derrière. Pour aller plus loin dans la théorie, je traduirais prochainement les commentaires de Cary Millsap là dessus.
Je n’ai pas l’intention de rentrer dans la technique des files d’attentes (Queuing Theory) qui est plutôt le domaine de Cary Millsap, mais je voudrais juste donner un exemple pour montrer de quelle manière la théorie des files d’attentes (Queues) s’applique à Oracle, en répondant à la question suivante que m’a posé un client récemment:
« Comment peuvent-ils se plaindre que le temps de réponse a empiré, alors que le débit (throughput) global a augmenté de 5% ? »
La réponse malheureusement est: oui, bien sûr, le temps de réponse est peut-être pire et ceci vient justement du fait que le débit est meilleur, et je vais donner un exemple dans cette note, construit pour montrer comment cela peut se produire.
- Supposons que vous ayez une machine avec une seule CPU.
- Supposons que vous ayez deux programmes en parallèle, qui se réveillent périodiquement pour faire un certain travail.
- Le programme 1 exécute une tâche qui utilise 0,1 secondes de CPU (et aucune d’autre ressource). Il produit un résultat de N (unités de mesure de la production). Et il se réveille toutes les secondes pour s’exécuter.
- Le programme 2 exécute une tâche qui utilise 0,5 secondes de CPU (et aucune autres ressource), produit un résultat 5N (5 fois plus important que le programme 1), et se réveille toutes les cinq secondes pour s’exécuter.
Sur une durée de dix secondes, chaque programme (s’exécutant tout seul sur la machine) utilise 10% de CPU et produit 10N unités de production, et le temps de réponse est égal au temps CPU.
Mais que se passe-t-il lorsque les deux programme démarrent à peu près en même temps ?
Si vous êtes chanceux le programme 2 va commencer son travail peu de temps après que le programme 1 ne vienne de terminer le sien, et il va terminer à son tour son travail peu de temps avant le programme 1 ne recommence sa prochaine exécution.
Si vous n’avez pas cette chance les deux programme vont commencer à faire leur travail en même temps, et un seul d’entre eux aura la CPU. A ce moment là , une machine typique va utiliser des tranches de temps pour faire comme si les 2 programme s’exécutaient simultanément. Donc les 2 programme vont commencer à s’échanger la CPU (context switching), disons toutes les 0,01 secondes. La conséquence de cela (à peu près), c’est que le programme 1 va terminer son travail au bout de 0,2 secondes (0,1 pour travailler en CPU et 0,1 pour attendre) et que le programme 2 va terminer son travail au bout de 0,6 secondes (0,5 secondes de CPU et 0,1 d’attente – puisque le programme concurrent a passé 0,1 seconde en CPU).
Les temps de réponse se sont dégradés, et de manière spectaculaire dans le cas du programme 1. Nous avons beaucoup de CPU inutilisée (80%, en fait), mais le temps de réponse de chaque job va être très variable en fonction du moment ou arrivent les jobs.
Dans le cas de mon client, il y avait beaucoup plus de programme comme le programme 1 qui étaient en train de d’exécuter, et qui faisaient passer beaucoup plus de tâches de 0,1 secondes en utilisant la capacité disponible de la machine. Donc le débit (throughput) était amélioré, mais cela augmentait la probabilité que ces programme entre en collision avec celui de 0,5 secondes (ou même entre eux) et donc le temps de réponse individuel s’est dégradé.
Pour passer de mon exemple trivial à un modèle plus réaliste correspondant au monde réel, vous avez besoin de la théorie des files d’attentes (queuing theory). J’ai rendu mon exemple aussi simple que possible avec un taux d’arrivée fixe, pour deux tâches de durée fixe, se déclenchant à intervalles réguliers. Pour modéliser le monde réel, vous devez prendre en compte des tâches de durée variable, qui arrivent à des intervalles répartis de manière aléatoire – et les calculs seront alors un peu plus complexes.
Mais vous n’avez pas besoin de ces détails mathématiques pour en comprendre les conséquences importantes:
- le temps de réponse peut varier considérablement en fonction de l’heure d’arrivée, et ce même si la machine est loin chargée au maximum,
- et temps de réponse peut se détériorer, même si (ou peut-être parce que) le débit s’améliore.
Pour de plus amples commentaires sur le dilemme temps de réponse/débit, voir cet article par Doug Burns .