5. Frank Pavageau @fpavageau
Architecte Senior
• C++ -> PHP -> Java
• Systèmes et devops
• Tech Lead socle eCommerce
4
Monday, April 23, 12
6. Frank Pavageau @fpavageau
Architecte Senior
• C++ -> PHP -> Java
• Systèmes et devops
• Tech Lead socle eCommerce
4
Monday, April 23, 12
7. Une Plateforme web
e-commerce B2C
Apache
Tomcat
Oracle
5
Monday, April 23, 12
8. Une Plateforme web
e-commerce B2C
Apache
•12+ Serveurs
Tomcat
•10 Webapps différentes
•50+ JVMs Oracle (JDK6)
Oracle
5
Monday, April 23, 12
9. Une Plateforme web
e-commerce B2C
Apache
•12+ Serveurs
Tomcat
•10 Webapps différentes
•50+ JVMs Oracle (JDK6)
•> 30000 sessions
•250-400 Req/s
Oracle
•Variance très importante du trafic
5
Monday, April 23, 12
10. ... une victime un peu atypique...
Modélisation du catalogue sous forme de Graphe
Implémentation custom du moteur de catalogue
100% sur la Heap (pas de BDD)
Mise à jour par AtomicReference.set()
6
Monday, April 23, 12
11. ... une victime un peu atypique...
Modélisation du catalogue sous forme de Graphe
Implémentation custom du moteur de catalogue
100% sur la Heap (pas de BDD)
Mise à jour par AtomicReference.set()
Impossible de “cacher” aggressivement
Beaucoup d’objets créés à chaque Request
Raccordements SI = latence = concurrence élevée
6
Monday, April 23, 12
16. Le flagrant délit
Connections JDBC Requêtes/s
Temps Temps
9
Monday, April 23, 12
17. Le flagrant délit
Connections JDBC Requêtes/s
Temps Temps
Threads actifs
Temps
9
Monday, April 23, 12
18. Le flagrant délit
Connections JDBC Requêtes/s
Temps Temps
Threads actifs Requêtes en attente (Executor Queue Size)
Temps Temps
9
Monday, April 23, 12
19. l’explication
Heap
Taille en MB
1 heure
10
Monday, April 23, 12
20. l’explication
Heap
On manque de recul: zoom arrière!
Taille en MB
1 heure
10
Monday, April 23, 12
21. l’explication
Heap
Taille en MB
24 heures
11
Monday, April 23, 12
22. l’explication
Heap
Taille en MB
24 heures
11
Monday, April 23, 12
23. l’explication
Heap
Taille en MB
24 heures
11
Monday, April 23, 12
24. l’explication
Heap % de temps passé en GC
100
75
Taille en MB
50
25
0
1 heure 1 heure
12
Monday, April 23, 12
27. The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
13
Monday, April 23, 12
28. The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
13
Monday, April 23, 12
29. The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13
Monday, April 23, 12
30. The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13
Monday, April 23, 12
31. The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13
Monday, April 23, 12
32. G C m ’a The usual suspects...
•
• e r!!
l e
OutOfMemory Heap
OutOfMemory PermGen
•
Monday, April 23, 12
t u
Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13
33. Mais ça sert à quoi alors le GC?
“Many concurrent algorithms are very easy to
write with a GC and totally hard (to down right
impossible) using explicit free.”
Cliff Click
14
Monday, April 23, 12
34. OK, donc il suffit de régler quelques options...
15
Monday, April 23, 12
35. OK, donc il suffit de régler quelques options...
664 options....
Source: Oracle JVM 1.6.0_31 x86_64 server
15
Monday, April 23, 12
66. Garbage Collectors
• Générationnels
• Stop the world!
• Throughput ou Concurrent
45
Monday, April 23, 12
67. Combinaisons de GCs
Young
Serial Parallel
Serial
Old Parallel
Concurrent
46
Monday, April 23, 12
68. Combinaisons de GCs
Young
Serial Parallel
Serial Par défaut
Old Parallel N/A
Concurrent
47
Monday, April 23, 12
69. Combinaisons de GCs
Young
Serial Parallel
Serial
Old Parallel
Concurrent
48
Monday, April 23, 12
70. Combinaisons de GCs
Young
Serial Parallel
Serial Serial
Old Parallel
Concurrent
48
Monday, April 23, 12
71. Combinaisons de GCs
Young
Serial Parallel
Serial Serial Parallel
Old Parallel
Concurrent
48
Monday, April 23, 12
72. Combinaisons de GCs
Young
Serial Parallel
Serial Serial Parallel
Old Parallel ParallelOld
Concurrent
48
Monday, April 23, 12
73. Combinaisons de GCs
Young
Serial Parallel
Serial Serial Parallel
Old Parallel ParallelOld
Concurrent CMS
48
Monday, April 23, 12
74. Combinaisons de GCs
Young
Serial Parallel
Serial Serial Parallel
Old Parallel ParallelOld
Concurrent CMS Serial CMS
48
Monday, April 23, 12
75. Combinaisons de GCs
Young
Serial Parallel
Serial Serial Parallel
Old Parallel ParallelOld
Concurrent CMS Serial CMS
Les implémentations de Parallel diffèrent suivant les combinaisons
49
Monday, April 23, 12
78. CMS est le bon compromis
Serial 917
Parallel 852
ParallelOld 846
CMS 871
CMS Serial 937
0 250 500 750 1000
Durée moyenne du test (s)
51
Monday, April 23, 12
79. Les outils: CLI
jps, jhat, jmap, jstack, jstat
$ jstat -gcutil PID
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 40.88 58.41 18.34 66.65 2729 316.538 46 6.820 323.358
52
Monday, April 23, 12
93. OK, donc on sait mesurer... la température!
57
Monday, April 23, 12
94. OK, donc on sait mesurer... la température !
=
58
Monday, April 23, 12
95. Problème : on ne peut pas faire un diagnostic avec une simple mesure...
Il faut historiser pour constituer un
référentiel !
Credit: http://www.lhup.edu/mkhalequ/fieldtrip/geos253.htm
59
Monday, April 23, 12
96. Donc il faut persister les mesures !
• JMX + jmxtrans
• RRD
• Graphite
• etc.
60
Monday, April 23, 12
97. On peut modifier les réglages...
Credit: http://www.our-energy.com
61
Monday, April 23, 12
98. ... si on sait mesurer/isoler les effets des réglages
Situation “avant”
cputime
Effet visible du tuning
62
Monday, April 23, 12
102. JVM
Tomcat
vs.
Application
(code)
65
Monday, April 23, 12
103. 1. Le code
• Le tuning de JVM ne peut pas compenser du code de mauvaise qualité
• Des règles peuvent aider
• Privilégier les données immutables et donc réutilisables sans risque
• Sortir les invariants, notamment les instanciations, et surtout dans les boucles
• Connaitre les caractéristiques des structures de données des frameworks
(java.util, Guava, Hibernate, etc.)
• Attention au rapport poids de la structure / poids des données
66
Monday, April 23, 12
104. Exemple : HashMap
HashMap 48
Entry[16] 80 key
Entry 32
value
67
Monday, April 23, 12
105. Exemple : HashMap
HashMap 48
Entry[16] 80 key
Overhead = 160 Bytes! Entry 32
value
67
Monday, April 23, 12
106. Exemple : HashMap
HashMap 48
Entry[16] 80 key
Overhead = 160 Bytes! Entry 32
value
•SingletonMap (40 Bytes)
•initialCapacity + loadFactor
67
Monday, April 23, 12
107. GC Young / s Réduire les allocations...
68
Monday, April 23, 12
108. Charge CPU ... impacte la CPU
69
Monday, April 23, 12
109. 2. Tomcat
• Se méfier du pooling
• Les tags: enablePooling dans web/webdefault.xml
• -Dorg.apache.jasper.runtime.JspFactoryImpl.USE_POOL=false
• Attention aux buffers et à leur réutilisation
• -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
• Le nombre de JSP impacte les besoins en PermGen
• Faire des tests et mesurer les impacts!
70
Monday, April 23, 12
110. 3. Heap Size La JVM
Time
Heap Size
Time
71
Monday, April 23, 12
111. 3. La JVM
pause > 1s !
Heap Size
Time
Heap Size
Time
71
Monday, April 23, 12
112. 3. La JVM
pause > 1s !
Heap Size
Time
Heap Size
GC très fréquents
Time
71
Monday, April 23, 12
116. Young vs Old
Old
-XX:NewSize -XX:MaxNewSize
-XX:NewRatio
Young
73
Monday, April 23, 12
117. Young vs Old
•“Working Set”
Old •Caches, Pools d’objets
•HttpSession, objets de durée de
vie intermédiaire
Young Objets < RequestScope
73
Monday, April 23, 12
119. Young trop petite:
Old
Young se remplit très vite = Beaucoup de
GC Young
Promotion excessive d’objets en Old =
Young Beaucoup de GC Old
74
Monday, April 23, 12
129. Old generation : évolutions comparées
Accélérations
80
Monday, April 23, 12
130. Contraintes supplémentaires
• Prise en compte des variations irrégulières
• Augmentation de trafic => augmentation de la pression mémoire
• Pour bien fonctionner, CMS doit avoir de la marge
• Plusieurs phases successives, la plupart concurrentes avec l’application
=> le remplissage continue en même temps
81
Monday, April 23, 12
131. Contraintes supplémentaires
• Prise en compte des variations irrégulières
• Augmentation de trafic => augmentation de la pression mémoire
• Pour bien fonctionner, CMS doit avoir de la marge
• Plusieurs phases successives, la plupart concurrentes avec l’application
=> le remplissage continue en même temps
(concurrent mode failure): 2165740K->1284261K(2228224K), 8.9411250 secs
81
Monday, April 23, 12
133. Marge de manoeuvre
CMSInitiatingOccupancyFraction = 92%
par défaut
Old
Young
82
Monday, April 23, 12
134. Marge de manoeuvre
75-80% pour plus de marge
UseCMSInitiatingOccupancyOnly pour
forcer le déclenchement uniquement
sur ce critère!
Old
Young
82
Monday, April 23, 12
142. Il reste des pauses !
• RMI (donc JMX) provoque des GC explicites à intervalles réguliers
• Appels à System.gc()
• GC explicite = Full GC (Serial) = pause de 4s !
• DisableExplicitGC + CMSClassUnloadingEnabled
• ExplicitGCInvokesConcurrentAndUnloadsClasses
87
Monday, April 23, 12
146. Et après?
• Tuning des Survivors
• Taille, ratio de survivants, age maximum
• G1
• Principes et options complétement différents
• Autres JDKs : JRockit, Azul, IBM
• Vérifier les réglages à chaque changement applicatif
• Mesurer, mesurer, mesurer!
90
Monday, April 23, 12