A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.md 9.4KB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. title: Latence et boucle de rétroaction
  2. url: http://mathieu.agopian.info/blog/latence-et-boucle-de-retroaction.html
  3. hash_url: f1ed7d7dff2ed14214bdf7a25dde1d74
  4. <h2>Latence</h2>
  5. <p>La <a class="reference external" href="http://fr.wikipedia.org/wiki/Latence_%28informatique%29">latence</a> en informatique est un délai minimum de transmission. C'est un des
  6. principaux ennemis de la performance notamment dans le domaine du web.</p>
  7. <p>Un site web est généralement composé de multiples fichiers statiques (css,
  8. javascript, images et icônes en tout genre). Pour afficher la totalité d'une
  9. page, il faut donc faire de multiples requêtes au serveur, chacune prenant un
  10. certain temps de traitement, à quoi on rajoute la latence (le temps de
  11. transfert sur le réseau).</p>
  12. <p>On imagine facilement l'impact d'une forte latence lorsqu'il faut effectuer
  13. plusieurs dizaines voire centaines de requêtes. Même si la latence n'est que de
  14. 10ms, si on multiple ça par 100, on atteint déjà une seconde.</p>
  15. <p>Prenons un autre exemple&nbsp;: il n'est pas rare d'avoir des pages nécessitant des
  16. dizaines (des centaines, voire des milliers&nbsp;?) de requêtes SQL à une base de
  17. données. Là encore, il faut multiplier ce nombre de requête par le temps de
  18. traitement par la base de données, mais aussi par la latence.</p>
  19. <p>Étant donné la difficulté de réduire la latence, l'optimisation de la
  20. performance passe par le réduction du nombre de requêtes&nbsp;: on fait des
  21. <em>bundles</em> pour les fichiers statiques (on regroupe toutes les CSS ou les
  22. fichiers javascript, on crée des <em>image map</em> pour les icônes), on fait usage du
  23. <em>JOIN</em> pour les requêtes SQL...</p>
  24. </div>
  25. <div class="section" id="boucle-de-retroaction">
  26. <h2>Boucle de rétroaction</h2>
  27. <p>La <a class="reference external" href="http://fr.wikipedia.org/wiki/Boucle_de_r%C3%A9troaction">boucle de rétroaction</a> (appelée «&nbsp;feedback loop&nbsp;» en anglais) permet de
  28. raffiner un système afin d'arriver à un équilibre, à un objectif.</p>
  29. <p>Une boucle de rétroaction basée sur des mesures de position permettra à robot
  30. d'atteindre la position souhaitée&nbsp;: la vitesse et la direction seront adaptées
  31. en fonction de la distance à l'objectif.</p>
  32. <p>Plus la boucle de rétroaction sera longue, plus l'équilibre sera long a
  33. atteindre. En effet, si la mesure de position ne se fait qu'une fois toutes les
  34. 10 secondes, soit le robot devra se déplacer très lentement, soit faire de
  35. nombreux aller-retours.</p>
  36. </div>
  37. <div class="section" id="le-rapport">
  38. <h2>Le rapport&nbsp;?</h2>
  39. <p>En tant qu'informaticien, il nous arrive régulièrement d'avoir à raffiner un
  40. bout de code en fonction de différents paramètres&nbsp;: l'expression du besoin, la
  41. rapidité d'exécution, l'occupation mémoire...</p>
  42. <p>Et ce raffinage se fait par le biais d'une boucle de rétroaction qui peut
  43. prendre différentes formes&nbsp;:</p>
  44. <ul class="simple">
  45. <li>des tests automatisés (test unitaires ou fonctionnels, TDD...)</li>
  46. <li>des tests manuels</li>
  47. <li>des simulations</li>
  48. <li>des aller-retours avec l'utilisateur final, le décideur, ...</li>
  49. </ul>
  50. <p>Si la latence s'invite dans ce mécanisme, on se retrouve dans la même situation
  51. que le robot qui doit atteindre une position, mais qui n'a de retour sur sa
  52. position que rarement. Soit on avance vite et on risque les aller-retours
  53. (comprendre&nbsp;: réécriture du code), soit on avance lentement.</p>
  54. <p>Dans tous les cas, c'est un cauchemar.</p>
  55. <p>Voici quelques exemples de latence&nbsp;:</p>
  56. <ul class="simple">
  57. <li>besoin mal exprimé ou mal compris (la mesure de position n'est pas fiable)</li>
  58. <li>périmètre fonctionnel qui change (la position finale du robot change en cours
  59. de route)</li>
  60. <li>grand nombre d'aller-retours avec l'utilisateur final/décideur (nécessité de
  61. faire un très grand nombre de mesures de position)</li>
  62. <li>retours de l'utilisateur final/décideur très lents (mesure de position très
  63. rare)</li>
  64. <li>dialogue avec une API/base de données/système distant/... très lent (chaque
  65. mesure de position demande de très longs traitements)</li>
  66. <li>peu de confiance dans les résultats (nécessité de refaire plusieurs fois les
  67. mesures ou de les retraiter)</li>
  68. </ul>
  69. </div>
  70. <div class="section" id="un-exemple-concret">
  71. <h2>Un exemple concret</h2>
  72. <p>Avec mon collègue <a class="reference external" href="https://larlet.fr/david/">David</a> nous nous sommes chargés de la résolution d'un ticket
  73. pour le projet <a class="reference external" href="https://addons.mozilla.org">AMO</a>.</p>
  74. <p>Afin de pouvoir présenter des graphiques d'utilisation/téléchargement des
  75. extensions à leur auteur (comme pour <a class="reference external" href="https://addons.mozilla.org/en-US/firefox/addon/firebug/statistics/?last=30">Firebug</a>), toutes les requêtes de
  76. téléchargement et de demande de mise à jour sont enregistrées et stockées dans
  77. une base de données «&nbsp;big data&nbsp;» (pour les curieux&nbsp;: c'est stocké dans <a class="reference external" href="http://hadoop.apache.org/">Hadoop</a>
  78. et récupéré par le biais de <a class="reference external" href="https://hive.apache.org/">Hive</a>). On parle de plus d'un milliard de requête
  79. par jour, toutes requêtes confondues.</p>
  80. <p>Ce qui nous a d'abord paru simple et rapide à implémenter, s'est transformé en
  81. deux semaines de sprint (et n'est pas encore terminé).</p>
  82. <p>Nous avons subit et fait partie des différentes formes de latences listées
  83. ci-dessus&nbsp;:</p>
  84. <ul class="simple">
  85. <li>besoin mal exprimé ou mal compris&nbsp;: la répartition des tâches entre nous et
  86. notre interlocuteur a changé plusieurs fois. Par ailleurs nous n'avions
  87. aucune connaissance du système avant de nous y attaquer.</li>
  88. <li>périmètre fonctionnel qui change&nbsp;: malheureusement, arrivé au bout de la
  89. première semaine de sprint, nous avons appris qu'il nous fallait refaire la
  90. moitié de notre travail différemment suite à des contraintes non prévues.</li>
  91. <li>grand nombre d'aller-retours avec l'utilisateur final/décideur&nbsp;: à l'heure de
  92. l'écriture de ce billet, nous en sommes à 54 commentaires sur le ticket.</li>
  93. <li>retours de l'utilisateur final/décideur très lent&nbsp;: nous travaillons en
  94. France, et notre interlocuteur sur la côte ouest des USA (-9h). Il est
  95. fréquent d'avoir besoin d'attendre le lendemain pour avoir une réponse, dans
  96. un sens ou dans l'autre.</li>
  97. <li>dialogue avec un système distant très lent&nbsp;: de par le nombre de données à
  98. traiter, chaque requête à Hive (au nombre de 6) prend en moyenne 15 minutes,
  99. et la taille des données à télécharger varie entre 500Mo et 1.6Go.</li>
  100. <li>peu de confiance dans les résultats&nbsp;: nous essayions de mettre au point les
  101. requêtes Hive à exécuter, et par le même temps, le post-traitement de ces
  102. requêtes, pour coller au plus proche aux statistiques et graphiques attendus.
  103. Jouer sur deux paramètres en même temps est déjà malaisé en temps normal,
  104. mais là il nous était de plus très laborieux de confronter nos résultats avec
  105. ceux de la production.</li>
  106. </ul>
  107. </div>
  108. <div class="section" id="la-solution">
  109. <h2>La solution</h2>
  110. <p>Diminuer la latence dans la boucle de rétroaction, par tous les moyens
  111. possibles.</p>
  112. <p>De la même manière qu'il arrive régulièrement de lancer un interpréteur Python
  113. (ou un <em>ipdb</em> ;) pour bidouiller et expérimenter avec un petit bout de code
  114. et avoir des retours immédiats, il faut tout faire pour accélérer la boucle de
  115. rétroaction.</p>
  116. <ul class="simple">
  117. <li>ça paraît évident, mais connaître précisément le besoin et le contexte avant
  118. de se lancer est primordial. Nous avons facilement perdu deux à trois jours à
  119. cause de ça, en début de sprint, avec notre envie d'avancer rapidement (et de
  120. passer à quelque chose de plus fun ;)</li>
  121. <li>périmètre fonctionnel qui change&nbsp;: difficile de le prévoir ou de l'éviter,
  122. mais je pense qu'en ayant une boucle de rétroaction plus courte, nous aurions
  123. eu des résultats plus rapidement, et aurions alors plus rapidement rencontré
  124. les contraintes qui ont fait changer le périmètre.</li>
  125. <li>le nombre d'aller-retours avec l'interlocuteur, et leur lenteur&nbsp;: quand nous
  126. avons pu mettre en place un appel vidéo journalier, beaucoup de choses se
  127. sont débloquées.</li>
  128. <li>dialogue avec le système distant très lent&nbsp;: nous aurions dû <a class="reference external" href="http://www.voidspace.org.uk/python/mock/">mock</a> beaucoup
  129. plus tôt le retour des requêtes Hive. Nous aurions ensuite dû récupérer un
  130. jeu de donnée complet (plusieurs Go) le plus tôt possible pour faire des
  131. tests sur le post-traitement dans un premier temps, puis ensuite seulement
  132. essayer d'améliorer les requêtes Hive. Faire les deux en même temps est une
  133. erreur qui nous a coûté de nombreux appels à Hive (et donc de nombreuses
  134. attentes et rétro-pédalages).</li>
  135. <li>peu de confiance dans les résultats&nbsp;: encore une fois vu la taille des
  136. données à traiter, il nous était très difficile de confronter nos données à
  137. celles attendues (uniquement disponibles en production). Nous avons fini par
  138. mettre en production un post-traitement parallèle à l'actuel, et stocker les
  139. données dans d'autres tables, en attendant d'avoir la version finale et
  140. raffinée de l'algorithme et des requêtes.</li>
  141. </ul>
  142. <p>Et à ma plus grande honte, ne pas avoir de tests unitaires a été un boulet
  143. supplémentaire&nbsp;: lancer un post-traitement pour s'apercevoir 15 minutes plus
  144. tard qu'on a oublié une virgule dans le code...</p>
  145. </div>