Version complète: sur le forum Webmaster Hub : Optimisation MySQL et Apache ?
Webmaster Hub > Création et exploitation de Sites Internet > Les fondations d'un site > Hébergement de Sites
pmadfm
Bonjour,

J'ai reçu depuis quelques semaine un PR de 5 sur mon Topsites et depuis c'est la galère je n'arrive à trouver de l'information sur l'optimisation de ce tuple mysql et apache.

Pourriez-vous m'aider SVP:

Dédibox Ubunto
DD 160 GO
Ram 1 Go
boot 40 Mo
swap 2048
/ le reste

J'allais oublier environ 5 000 000 de requêtes par jour et des pics à plus de 100 la seconde.

Le CPU vit tranquille sa petite vie et ne fait pas grand chose, et tous les sites (15) sur la boite dédié rament le soir vers 17h00 heure de pointe.

Voici mes fichiers de config
CODE

top - 18:26:49 up 9 days, 4:11, 1 user, load average: 0.04, 0.13, 0.18
Tasks: 219 total, 1 running, 217 sleeping, 0 stopped, 1 zombie
Cpu(s): 6.3% us, 1.0% sy, 0.0% ni, 92.7% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 1018456k total, 496264k used, 522192k free, 37956k buffers
Swap: 2096472k total, 11720k used, 2084752k free, 163172k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8993 mysql 15 0 509m 101m 4236 S 1.3 10.2 1:19.69 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid
10863 www-data 16 0 22680 10m 2988 S 0.0 1.1 0:00.52 /usr/sbin/apache2 -k start -DSSL
10974 www-data 16 0 21736 10m 3352 S 0.0 1.0 0:00.43 /usr/sbin/apache2 -k start -DSSL
10894 www-data 15 0 22088 10m 2928 S 0.0 1.0 0:00.90 /usr/sbin/apache2 -k start -DSSL
10879 www-data 16 0 21408 9604 2944 S 0.0 0.9 0:00.27 /usr/sbin/apache2 -k start -DSSL
10918 www-data 15 0 20496 8516 2844 S 0.0 0.8 0:00.19 /usr/sbin/apache2 -k start -DSSL
10954 www-data 16 0 19300 7632 3088 S 0.0 0.7 0:00.24 /usr/sbin/apache2 -k start -DSSL
10864 www-data 16 0 18936 7096 3288 S 0.0 0.7 0:00.24 /usr/sbin/apache2 -k start -DSSL
10956 www-data 16 0 18924 7084 3264 S 0.0 0.7 0:00.20 /usr/sbin/apache2 -k start -DSSL
10892 www-data 15 0 18340 6872 3392 S 0.3 0.7 0:00.12 /usr/sbin/apache2 -k start -DSSL
10897 www-data 16 0 18592 6780 3268 S 0.0 0.7 0:00.08 /usr/sbin/apache2 -k start -DSSL
10937 www-data 15 0 17996 5900 2776 S 0.0 0.6 0:00.08 /usr/sbin/apache2 -k start -DSSL
10842 root 16 0 17320 5556 3148 S 0.0 0.5 0:00.06 /usr/sbin/apache2 -k start -DSSL
10908 www-data 15 0 17596 5500 2712 S 0.0 0.5 0:00.08 /usr/sbin/apache2 -k start -DSSL

/* Apache 2 */
Timeout 300

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.

KeepAlive On

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.

MaxKeepAliveRequests 150

********************************
<IfModule prefork.c>
MaxClients 150
StartServers 5
MinSpareServers 5
MaxSpareServers 25
</IfModule>

<IfModule worker.c>
StartServers 5
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 150
ThreadsPerChild 5
MaxRequestsPerChild 60
*********************************

/* MySQL */

[mysqld]
port = 3306
socket = /var/run/mysqld/mysqld.sock
skip-locking
bind-address = 127.0.0.1
key_buffer = 384M
max_allowed_packet = 2M
table_cache = 1024
sort_buffer_size = 16M
read_buffer_size = 16M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 64M
thread_cache = 16
query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 32
long_query_time=30
join_buffer_size = 256K
language = /usr/share/mysql/french/
max_connections = 150
max_tmp_tables = 512
myisam_data_pointer_size = 32K
table_cache = 1024


~~~~~~

[isamchk]
key_buffer = 128M
sort_buffer_size = 128M
read_buffer = 8M
write_buffer = 8M

[myisamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 16M
write_buffer = 16M

[mysqlhotcopy]
interactive-timeout



J'ai une grande expérience de l'informatique mais très peu d'unix et des serveurs Web, aussi toute aide sera la bienvenue.

Par avance merci.
suede
quand tu dis "c'est la galere", cela veut dire que tu as des problemes ?

Ton top est pas trop mal a premiere vue.

Si tu plantes, comment est-il au moment du plantage ?
froidure_nicolas
whistling.gif
pmadfm
Bonjour,

Grand merci pour vos réponses.

En fait tous jours vers les 17 heures on ne peut plus accéder à mes sites tout devient hyper lent et les réponses n'arrivent pas aux clients.

Quand je fais un top en ssh le cpu se repose la ram est chargée et le résultat plus d'accès http posssible .

J'ai du trop chargé mysql et pas assez apache, mais mes connaissance dans le domaine sont très légères et c'est pourquoi je sollicite votre aide.

Entre temps j'ai installé APC, dommage ce n'était pas le meilleur et les load module pour charger un peu les machines clients, dont voici les changements opérés et j'ai peur que cela ne change pas grand chose :

CODE
Timeout 300
KeepAlive On
MaxKeepAliveRequests 30
<IfModule prefork.c>
MaxClients       150
StartServers      5
MinSpareServers   5
MaxSpareServers  20
</IfModule>

<IfModule worker.c>
StartServers        5
MaxClients         150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild 50
</IfModule>

<IfModule perchild.c>
NumServers           5
StartThreads         5
MinSpareThreads      5
MaxSpareThreads     10
MaxThreadsPerChild  20
MaxRequestsPerChild  0
AcceptMutex fcntl
</IfModule>

# PM Ajout par la creation des liens symbolique pour :
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so

# Afin de Stocker les data headers ... chez le client
# M604800 = 7j A2592000 30j
ExpiresDefault A300
expiresbyType text/html M604800

#Expires A2592000
expiresbyType image/gif A2592000

<IfModule mod_negotiation.c>
<IfModule mod_include.c>
    Alias /error/ "/usr/share/apache2/error/"

    <Directory "/usr/share/apache2/error">
        AllowOverride None
        Options IncludesNoExec
        AddOutputFilter Includes html
        AddHandler type-map var
        Order allow,deny
        Allow from all
        LanguagePriority fr en es de
        ForceLanguagePriority Prefer Fallback
    </Directory>

    ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
    ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
    ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
    ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
    ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
    ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
    ErrorDocument 410 /error/HTTP_GONE.html.var
    ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
    ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
    ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
    ErrorDocument 415 /error/HTTP_SERVICE_UNAVAILABLE.html.var
    ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
    ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
    ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
    ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
    ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var

</IfModule>
</IfModule>


*** MYSQL ***
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock
skip-locking
bind-address    = 127.0.0.1
key_buffer = 384M
max_allowed_packet = 2M
table_cache = 1024
sort_buffer_size = 16M
read_buffer_size = 16M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 64M
thread_cache = 16
query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 32
long_query_time=30
join_buffer_size = 256K
language = /usr/share/mysql/french/
max_connections = 150
max_tmp_tables = 512
myisam_data_pointer_size = 32K
table_cache = 1024
# Replication Master Server (default)
# binary logging is required for replication
log-bin

# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id       = 1
max_tmp_tables = 512
myisam_data_pointer_size = 32K
table_cache = 1024
[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[isamchk]
key_buffer = 128M
sort_buffer_size = 128M
read_buffer = 8M
write_buffer = 8M

[myisamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 16M
write_buffer = 16M

[mysqlhotcopy]
interactive-timeout


Si cela vous cause, n'hésitez pas à conversez ;-)

Merci d'avance et bonne journée.
pmadfm
Bonjour en complément,

voici deux stats éloquentent sur mon serveur et sur celui de webmaster hub qui lui ne perd rien et qui décoiffe, bravo à l'équipe.

CODE
httperf --timeout=1 --client=0/1 --server=01-topsites.com --port=80 --uri=/ --rate=10 --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=1
Maximum connect burst length: 12

Total: connections 100 requests 55 replies 3 test-duration 12.383 s

Connection rate: 8.1 conn/s (123.8 ms/conn, <=23 concurrent connections)
Connection time [ms]: min 1704.6 avg 1770.8 max 1903.0 median 1704.5 stddev 114.4
Connection time [ms]: connect 438.2
Connection length [replies/conn]: 1.000

Request rate: 4.4 req/s (225.2 ms/req)
Request size [B]: 66.0

Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (2 samples)
Reply time [ms]: response 1035.2 transfer 6.7
Reply size [B]: header 212.0 content 117531.0 footer 2.0 (total 117745.0)
Reply status: 1xx=0 2xx=3 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.03 system 0.11 (user 0.3% system 0.9% total 1.1%)
Net I/O: 28.1 KB/s (0.2*10^6 bps)

Errors: total 97 client-timo 97 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

Perte de request et lenteur

MasterHub
CODE
httperf --timeout=1 --client=0/1 --server=webmaster-hub.com --port=80 --uri=/ --rate=10 --send-buffer=4096 --recv-buffer=16384 --num-conns=100 --num-calls=1
Maximum connect burst length: 1

Total: connections 100 requests 100 replies 100 test-duration 9.983 s

Connection rate: 10.0 conn/s (99.8 ms/conn, <=6 concurrent connections)
Connection time [ms]: min 75.3 avg 174.7 max 577.6 median 85.5 stddev 159.1
Connection time [ms]: connect 5.4
Connection length [replies/conn]: 1.000

Request rate: 10.0 req/s (99.8 ms/req)
Request size [B]: 68.0

Reply rate [replies/s]: min 10.0 avg 10.0 max 10.0 stddev 0.0 (1 samples)
Reply time [ms]: response 150.2 transfer 19.2
Reply size [B]: header 421.0 content 44134.0 footer 2.0 (total 44557.0)
Reply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=0

CPU time [s]: user 1.92 system 7.11 (user 19.2% system 71.3% total 90.5%)
Net I/O: 436.5 KB/s (3.6*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0


Excellent 0 pertes ! Et là on voit bien que le CPU est sollicité !

Cdt Pascal
dams41
Ca dépend beaucoup de la façon dont les sites sont programmés. Si tu as un site qui se contente de récupérer des infos dans mysql, mais qui n'opère que peu de traitement, c'est normal que ta charge CPU soit réduite. Je crois que ton optimisation (si elle est possible) passerait d'abord par une optimisation des scripts côté serveur. Essaye de nous poster un exemple de requête SQL appelée depuis le script, histoire de voir comment c'est construit...
adn
Salut,

Si tes accès bases sont de la lecture pense à mettre en place un système de cache, le résultat sera flagrant. D'autre part si tu fais des modifications en base, pose toi la question de savoir si les ordres SQL peuvent être différées.
Dan
CITATION(pmadfm @ mercredi 7 février 2007, 11h56) *
voici deux stats éloquentent sur mon serveur et sur celui de webmaster hub qui lui ne perd rien et qui décoiffe, bravo à l'équipe.

Il n'y a aucun mérite... tu compares une Dedibox avec un Bi-Xeon en Dual-Core ... encore heureux qu'on remarque une différence entre les deux serveurs.

La différence principale vient du fait que ton serveur met 438 ms pour la connexion alors que le serveur du Hub met 5.4ms
Tu as donc un nombre important d'erreurs de timeout.

Et le serveur du Hub pourrait aller bien plus vite que ça, si seulement ton CPU arrivait à suivre wink.gif
Tu n'utilises que 436KB de bande passante (soit à peine plus de 4Mb), et on a 2 cartes à 100Mb/s ... on est donc à 2% d'utilisation de la bande passante.

Dan
ludo88
la solution à vo problemes de serveur : le bixeon dual core wink.gif

Mais c'est vrai que l'opimisation de l'hébergement c'est un boulot et c'est super chiant, enfin ca reste un point important...
pmadfm
Bonsoir,

Merci à tous de vos réponses en fait j'ai gratté et :

Eureka ! J’ai finis par y arriver. a_thumbsup_20.gif

Cela n’a pas été sans peine et je pense qu’il pourrait encore y avoir des améliorations mais déjà, le résultat obtenu est plus que satisfaisant pour un début.

Donc je vais vous livrer ma petite cuisine, le tout sans prétention, simplement si cela peut aider quelqu’un ce serait dommage de ne pas vous en faire profiter. Encore une fois je ne me prends pas pour un expert apache, loin s’en faut ...

L’ensemble des modifications tient en peu de lignes et principalement dans apache2.conf.

Voici le code modifié : smartass.gif
CODE
Timeout 300
KeepAlive On
MaxKeepAliveRequests 30
KeepAliveTimeout 5
ServerLimit  400

<IfModule prefork.c>
MaxClients      400
StartServers      5
MinSpareServers  70
MaxSpareServers 300
</IfModule>

<IfModule worker.c>
StartServers           5
MaxClients           400
MinSpareThreads       70
MaxSpareThreads      300
ThreadsPerChild        0
MaxRequestsPerChild 4000
</IfModule>
<IfModule perchild.c>
NumServers           5
StartThreads         5
MinSpareThreads     70
MaxSpareThreads    300
MaxThreadsPerChild  0
MaxRequestsPerChild  0
AcceptMutex fcntl
</IfModule>

#300 secondes 604800 secondes  2592000 = 30j
ExpiresDefault A300  
expiresbyType text/html M604800
expiresbyType image/gif A2592000


Positionnez AllowOverride sur none afin d’éviter qu’apache tente d’ouvrir le .htaccess dans chaque répertoire qu’il visite.

Pensez à mettre le KeepAlive et KeepAliveTimout (entre 2 et 5), permettent l’envoi de requêtes multipes. C’est very good pour les pages html comportant par exemple plusieurs images, si vous le mettez sur off alors apache va générer de multiple TCP et ainsi créer une surcharge importante pour tous les TCP, un par image ..

La directive ServerLimit permet d’overrider le par défaut qui vous limite à 256 clients.

Mon maxclient correspond à mon besoin et il est bien équilibré aujourd’hui pour moi.

Attention de bien équilibré le minspare par rapport au maxspare, ces paramètres déterminent le nombre de processus enfants, si le min est trop bas apache génèrera trop d’enfant et pendant ce temps il ne répondra pas aux requêtes et il consommera plus de ram. Normalement et là, ce n’est pas tout à fait le cas ;-) on devrait avoir un ratio de 4 afin de ne pas généré plus de 4 enfants. Ah les sales gosses ;-)
MaxRequestsPerChild n’hésitez pas à en mettre quelques milliers.
Alors maintenant quelques modules pour arranger encore plus la vie de votre serveur.
La compression http peut être activée grâce au module deflate. La communication avec le navigateur est automatique et apache de ce fait détermine automatiquement si il peut compresser ou non. (Content-Encoding: utilisation de gzip par apache)
Encore un petit truc, mettre en cache chez le client une copie des données et gérer sa conservation : économie de BP, ce contrôle du cache est exécuté par les modules mod_epires et mod_headers, en local coté serveur cela peut être effectué avec le mod_cache. Ensuite codez les Expires defaut et type.
Dernier point pour les PROS qui veulent vraiment affiner leur serveur.
En fait il y à deux type de pages, les pages statiques et les pages dynamiques, or si apaches sait gérer les deux il ne le fait pas de manière identique. En effet 3mo suffisent pour les statiques et de 3 à 20 mo de ram pour les dynamiques. Or notre ami apache ne libère pas la ram et ce jusqu’à ce que le processus meurt, aussi vous vous retrouver rapidement avec une taille de ram importante voir l’utilisation du swap = accès HD.
Deux solutions, 1 propre et un peu complexe et une débrouillardise que j’ai mise en œuvre pour l’instant.
Propre :
Montez un Apache léger (minimum de modules statiquement compilés) comme serveur frontal pour les pages statiques. Les pages requêtes dynamique doivent être envoyés au serveur Apache puissant (compilé avec les modules utiles). Un serveur frontal léger offre l'avantage d'une prise en charge rapide du contenu statique sans consommer trop de ram, et le dynamique est transféré vers le gros serveur.
Vous pouvez filtrer le transfert des requêtes via les modules mod_proxy et mod_rewrite. Vous en mettez un sur le port 80 et l’autre sur le 8092 par exemple.

Code :
CODE
ProxyPassReverse / http://%{HTTP_HOST}:8092/
RewriteEngine on                                            
RewriteCond  %{REQUEST_URI} !.*\.(gif|png|jpg)$
RewriteRule ^/(.*) http://%{HTTP_HOST}:8092/$1 [P]


Et hop, bon il faut le tester et le mettre au point mais c’est l’idée.

Votre client ne verra rien et votre ram sera heureuse.

La débrouillardise :
Crontab –e (mode root)

Puis :
*/60 10-19 * * mon,tue,wed,thu,fri,sat /etc/init.d/apache2 reload

Cela revient à dire toute les 60 minutes de 10 heures à 19 heures du lundi au samedi, pépère soit gentil de reload apache afin de virer les processus inutiles et de libérer ma RAM, non de dieu ! ;-)

Voilà j’espère que ce petit tuto pourra vous aider, enfin moi j’ai pas mal galéré et même si cela n’est pas encore pointu, mon serveur tourne et les temps de réponses sont passé de 10 minutes à 1 à 3 secondes avec au redémarrage d’apache (reload) une conso de 350 mo de ram ce qui est plus que satisfaisant sachant que j’ai configuré un mysql de ouf avec par exemple 384mo de keysbuffers etc ... enfin en gros la config que l’on trouve dans huge.ini de easyphp 2.0.

Je vous rappelle le contexte, Sur une dédibox, j’ai une quinzaine de sites web dont 4 annuaires et mon fameux Topsites qui à lui seul reçoit environ 600 000 requêtes chaque jour pour l’affichage de notre bouton statistiques sur les sites web des inscrits sur notre TopSites. Et bien sur une table qui montent jusqu’à 180 000 lignes le soir, avec l’IP, le User, le referer, une variable rate, unique_visite, totale_visite et sortie. Chaque requête d’affichage du bouton de stats génère environ 8 requêtes de lecture et de maj en mysql.
Dernier point que l’on néglige souvent et qui est pourtant évident le calcul des stats, en effet j’ai diminué mon bouton de 7.65Ko à 1.20 et je suis passé sur le domaine TopSites de 5Go à 1.5go par jour en BP. Eh oui 600 000 * de 6.45 ko = trop lourd ...

J'allais oublié, je suis heureux de n'avoir pas du investir dans un bi-néon smile.gif
au fait sur mon httpperf je ne perds plus de clients tout le monde à sa réponse et mon cpu monte maintenant de manière significative, ah le feignant. cool.gif

Cordialement Pascal
pmadfm
Bonjour,

Pour la Crontab mettez plutôt :

CODE
0,15    *        * * * /etc/init.d/apache2 reload > /dev/null 2>&1


Toutes suggestions pour l'amélioration de ces codes et informations seront les bienvenues.

Merci.
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.