Afin de vérifier les interactions entre HAPROXY et APACHE et aussi essayer de trouver un «bon» réglage j'ai décidé de faire quelques essais de performance.
J'ai «cloné» le site (celui-ci) sur une machine virtuelle (cela ne doit pas beaucoup changer puisque Gandi fournit des machines virtuelles XEN) afin de pouvoir effectuer des tests de saturation et de mesure des temps de réponse en fonction du nombre de connexions en lecture seule.
Pour «charger» le service au maximum j'ai utilisé le programme «Siege» disponible dans Debian) qui permet de simuler un grand nombre de connexions à partir d'une simple liste d'URL. Comme source j'ai utilisé les URL fournies par le plan du site afin d'avoir un maximum de pages, le site n'étant pas immense j'ai obtenu #150 pages différentes pour mes tests. J'ai d'abord effectué quelques tests de charge en faisant varier quelques paramètres «Apache» :
- StartServers : nombre de processus lancés au démarrage
- MinSpareServers : nombre mini de serveurs qui doivent être disponibles
- MaxSpareServers : nombre maxi de serveurs qui peuvent être libres (si plus des processus sont tués)
- MaxClients : nombre de processus à ne pas dépasser.
Le paramètre le plus critique pour l'utilisation mémoire maximale est «MaxClient» (il pourra y avoir MaxClient processus Apache au maximum), les autres sont surtout destinés à l'optimisation de l'occupation mémoire moyenne. Pour simplifier je positionne «StartServers» = «MaxClient» = MaxSpareServers et «MinSpareServers» à 1.
Après quelques tests j'ai obtenu le meilleur fonctionnement en fixant «MaxClient» à 30 ce qui donne une utilisation mémoire de #150Mo (y compris Mysql). J'ai donc ensuite effectué des tests de «charge» avec «Siege» réglé pour envoyer les URL à la vitesse maximale depuis 10 <= N <= 140 «clients» différents et simultanés.
Le schéma des machines utilisées est le suivant :
- une machine « injecteur », c'est une machine physique
- une machine virtuelle « haproxy »
- un ou deux serveurs Apache + Mysql dans deux machines virtuelles sur deux serveurs différents.
Les résultats en fonction du nombre de requêtes en parallèle sont les suivants :
Apache + Haproxy | Apache (2 serveurs)+ Haproxy | ||||||||||
Flux | Req. | Moy. | mini | Maxi | Vol | Req. | Moy. | mini | Maxi | Vol | |
nombre | (sec) | (sec) | (sec) | MO/sec | (sec) | (sec) | (sec) | MO/sec | |||
10 | 9585 | 0,09 | 0,02 | 0,35 | 4,12 | 14825 | 0,06 | 0,01 | 1,52 | 6,36 | |
9637 | 0,09 | 0,02 | 0,34 | 4,12 | 15754 | 0,06 | 0,01 | 1,07 | 6,71 | ||
9611 | 0,09 | 0,02 | 0,35 | 4,12 | 15290 | 0,06 | 0,01 | 1,30 | 6,54 | ||
20 | 9616 | 0,19 | 0,04 | 0,54 | 4,12 | 15760 | 0,11 | 0,01 | 1,71 | 6,69 | |
9628 | 0,19 | 0,05 | 0,51 | 4,14 | 16117 | 0,11 | 0,01 | 1,61 | 6,88 | ||
9622 | 0,19 | 0,05 | 0,53 | 4,13 | 15939 | 0,11 | 0,01 | 1,66 | 6,79 | ||
40 | 9487 | 0,38 | 0,08 | 0,92 | 4,09 | 15417 | 0,23 | 0,01 | 2,98 | 6,55 | |
9491 | 0,38 | 0,05 | 0,78 | 4,06 | 14902 | 0,24 | 0,01 | 2,76 | 6,39 | ||
9489 | 0,38 | 0,07 | 0,85 | 4,08 | 15160 | 0,24 | 0,01 | 2,87 | 6,47 | ||
60 | 9583 | 0,56 | 0,18 | 0,88 | 4,02 | 14294 | 0,37 | 0,01 | 5,72 | 6,04 | |
9566 | 0,56 | 0,15 | 0,98 | 4,09 | 14659 | 0,37 | 0,02 | 8,02 | 6,17 | ||
9575 | 0,56 | 0,17 | 0,93 | 4,06 | 14477 | 0,37 | 0,02 | 6,87 | 6,11 | ||
80 | 9372 | 0,76 | 0,20 | 1,49 | 3,98 | 13446 | 0,54 | 0,03 | 6,37 | 5,34 | |
9588 | 0,74 | 0,06 | 1,18 | 4,11 | 13455 | 0,53 | 0,03 | 7,88 | 5,33 | ||
9480 | 0,75 | 0,13 | 1,34 | 4,05 | 13451 | 0,54 | 0,03 | 7,13 | 5,34 | ||
100 | 9274 | 0,96 | 0,19 | 4,02 | 4,01 | 13446 | 0,66 | 0,05 | 7,64 | 5,21 | |
9439 | 0,95 | 0,55 | 1,44 | 4,05 | 13272 | 0,67 | 0,10 | 5,69 | 5,04 | ||
9357 | 0,96 | 0,37 | 2,73 | 4,03 | 13359 | 0,67 | 0,08 | 6,67 | 5,13 | ||
120 | 9504 | 1,13 | 0,22 | 4,26 | 4,04 | 13870 | 0,77 | 0,17 | 5,36 | 5,43 | |
9622 | 1,11 | 0,27 | 4,31 | 4,12 | 14174 | 0,76 | 0,20 | 6,50 | 5,50 | ||
9563 | 1,12 | 0,25 | 4,29 | 4,08 | 14022 | 0,77 | 0,19 | 5,93 | 5,47 | ||
140 | 14473 | 0,87 | 0,11 | 6,03 | 5,58 | ||||||
14174 | 0,76 | 0,20 | 6,50 | 5,50 | |||||||
14324 | 0,82 | 0,16 | 6,27 | 5,54 |
On remarque que le nombre de requêtes traitées ne varie que peu en fonction du nombre d'injecteurs utilisés en parallèle. En effet dans tous les cas les serveurs sont à peu près à 100% de CPU puisque l'injection est effectuée à vitesse maxi, dès qu'une requête est revenue la suivante est envoyée. Les seules valeurs qui varient de manière significative sont celles correspondant aux temps de réponse moyen, mini et maxi. L'appoort d'un deuxième serveur appporte, en dehors de la fiabilité, un gain de 40 à 60%.
Avec deux serveurs Apache on n'obtient pas des performances doubles mais l'analyse des statistiques par serveur (merci le tableau récap de Haproxy) montre que l'un des serveurs traite plus de 8500 requêtes et l'autre seulement de 6 à 7000 sans que j'aie pu trouver une explication évidente. Toutefois la machine d'injection ne dispose que d'un accès réseau à 100Mbits qui permet un débit d'environ 9Mo/s vers la machine virtuelle supportant Haproxy. Le deuxième serveur Apache était situé sur une machine physique différente de celle supportant Haproxy et le premier serveur Apache.
Je vais tenter quelques tests réseau pour essayer de comprendre ces limitations.
Tests réseau réalisés avec "Iperf" installé sur toutes les machines physiques et virtuelles, résultats "bruts" :
- Injecteur <--> machine "Haproxy" : 94Mbits/s soit # 12Mo/s
- Machine Haproxy <--> serveur "rapide" : 160Mbits/s soit#20Mo/s
- Machine Haproxy <--> serveur "lent" : 100Mbits/s soit#12Mo/s
Seul l'injecteur est une machine physique. Au vu des performances réseau (maxi < 12Mo/s) le débit maximum aux environs de 6,5Mo/s est pratiquement dans les limites puisqu'il dépasse 50% du débit maxi constaté auquel il faut ajouter le débit inverse (5 à 10%) pour le contrôle de la transmission (ACK).