Upload
jug-lausanne
View
132
Download
5
Embed Size (px)
DESCRIPTION
Performances des serveurs en Java: l'expérience du projet OpenDS - Ludovic Poitou - December 2010
Citation preview
CONCEVOIR UN SERVEURULTRA-PERFORMANT EN JAVA :
L'EXPÉRIENCE DU PROJET OPENDS
Ludovic Poitou
1Friday, December 10, 2010
2
QUI SUIS-JE ?
• Ludovic Poitou
• Product Manager à ForgeRock
• Précédemment Architecte chez Sun et “Community Manager” pour le projet OpenDS
• Plus de 14 ans d'expérience avec LDAP
• Architecte de Sun Directory Server 5.2 / 6
• http://ludopoitou.wordpress.com2Friday, December 10, 2010
• ForgeRock AS - Février 2010 - Norvège
• Editeur de logiciels open source
•OpenAM (ex-OpenSSO), OpenIDM, OpenDJ (OpenDS) ...
• ForgeRock France SAS - Novembre 2010
• Centre de Recherche & Développement à Grenoble
• UK, USA, Brésil, Allemagne, Suède...
3Friday, December 10, 2010
AGENDA
• Une présentation du projet OpenDS
•Modèles de conceptions et réflexions sur la notion de performance
• La JVM et les performances
• Conclusion
4Friday, December 10, 2010
LE PROJET OPENDS
• Lancé en Open Source en July 2006
• CDDL
• Code source : https://opends.dev.java.net/
• Sponsorisé par Sun Microsystems / Oracle
• Ecrit en Java par des experts LDAP
5Friday, December 10, 2010
QU'EST CE ?
•OpenDS est un server en Java qui implémente le protocol LDAPv3 et ses services
• Il inclut sa propre base de données,
• basé sur Berkeley DB Java Edition
• Pas accessible directement
• Possède toutes les fonctions de sécurité, de contrôle d'accès, de gestion de mots de passes pour stocker de façon sécurisée les identités des utilisateurs et machines
6Friday, December 10, 2010
POURQUOI FAIRE ?• Stockage générique et orienté objet de données
• Pages blanches et carnet d'adresses mél
• Principalement le coffre fort des Identités
• Pour l'Authentication et les Authorizations
• Pour les Profiles et Personnalisations
• La brique de base de tout SI dans les entreprises
• Utilisé par l'infrastructure Web et Mail
• Le fondement des produits de gestion d'Identité
• Gestion d'Access, Fédération, Provisionnage7Friday, December 10, 2010
LES OBJECTIFS DU PROJET OPENDS
• Un jeu complet de Services d'Annuaire
• L'annuaire base de données, des services de Proxy d'annuaire, des fonctions d'annuaire virtuel
• Conformes aux standards et extensions LDAPv3
• Capacité de croissance horizontale et verticale
• Utiliser le code d'OpenDS pour le produit Oracle Directory Server Enterprise Edition
8Friday, December 10, 2010
TROIS PRINCIPES
• Facilité d'utilisation
• Installation, Configuration, Gestion, Surveillance...
• Capacité d'extension
• De nombreuses interfaces ont été définies
• Avec des implémentations par défault
• Performance
• C'est le coeur de cette présentation !9Friday, December 10, 2010
OPENDS 2.2
•Disponible depuis Décembre 2009
• Un serveur d'annuaire 100% conforme à LDAPv3
•Nombreuses extensions LDAP standards et expérimentales
• Réplication Multi Maitre, avec 3 niveaux de cohérence des données
• Fonctions étendues de Sécurité
• S'installe en 6 clics et moins de 3 minutes
• Gestion par outils graphiques et textes
•Documentation complète sur le Wiki10Friday, December 10, 2010
•Dérive d’OpenDS
• Version 2.4 la semaine prochaine
• Plus de 10 nouvelles fonctionnalités
• Un grand nombre de correctifs
•De meilleures performances
11Friday, December 10, 2010
POUR QUI ?
• Les opérateurs Télécom, le secteur financier, les portails
• Pour stocker les identités des clients, téléphones et services
•De 15 à 120 millions d'entrées, hautement disponibles
• Pour le service de Nommage, ou les PME
•OpenSolaris, Solaris, Linux..., couplé avec SAMBA, Intégré avec Kerberos
• Pages blanches...12Friday, December 10, 2010
CARACTÉRISTIQUES DE PERFORMANCES
• Comme tout serveur, les capacités de montée en charge priment
• Jusqu'à plusieurs dizaines de millions d'entrées
• Plusieurs milliers de connections
•Quel débit d'opérations?
•Quel temps de réponse moyen ? Maximum ?Photo par Roger Smith http://www.flickr.com/photos/rogersmith/
13Friday, December 10, 2010
ENVIRONNEMENT DE TEST
•OpenDS 2.2, Solaris 10, ZFS
• Le test de base :
• 10 M d'entrées, taille moyenne 2,6K
• Réplication multi-maitre entre 2 serveurs
14Friday, December 10, 2010
LES RÉGLAGES DU TEST
• config.ldif
• ds-cfg-db-log-file-max: 100 MB
• ds-cfg-db-cache-percent: 70-80
• ds-cfg-db-checkpointer-bytes-interval: 100 MB
• ds-cfg-etime-resolution: nanoseconds
• ds-cfg-num-request-handlers: 4
• Replication ON
15Friday, December 10, 2010
SEARCHRATE SUR X4170
16Friday, December 10, 2010
MODRATE SUR X4170
17Friday, December 10, 2010
REFLEXIONS SUR LA CONCEPTION
Photo par Jean-Pierre Dalbera http://www.flickr.com/people/dalbera/
18Friday, December 10, 2010
COMMENT OBTENIR DE TELS RÉSULTATS ?
• 2 Aspects
• Le code
• Le run-time : l'optimisation de la JVM et du Garbage Collector
• Une relation très forte entre la conception du code et la gestion mémoire
19Friday, December 10, 2010
PERFORMANCE VS PARALLELISME
• Impact des performances sur le parallelisme
• Code sérialisé crée des points de contentions
•Manque de ressources
• Impact du parallelisme sur les performances
• L'utilisation de plus de ressources conduit à plus de contention et impacte les performances
• Réglage du goulet d'étranglement20Friday, December 10, 2010
ATTENTION AUX SECTIONS CRITIQUES
• Essayer de minimiser le temps passé en section critique
•Mais la bande passante est limitée par le temps passé dans la plus grosse section critique
• Exemple : LinkedBlockingQueue
• 200 000 opérations sur processeur x64
• 20 000 sur processor T2000
• Utilisée pour la WorkQueue et les Access Logs
21Friday, December 10, 2010
LE CACHE D'ENTRÉES
• Un cache pour réduire les accès disques
• L'éviction du cache rajoute du travail au GC
• Un cache global est point de contention
• Cacher uniquement des objets qui vont être réutilisés (et pas peut-être)
• Utiliser un cache “thread local”, mais attention aux coûts !
22Friday, December 10, 2010
LE MONITORING DU SERVEUR
• Les statistiques sont indispensables
•Mais attention à la contention
• Ecritures fréquentes (update stats)
• Lecture beaucoup moins
• Une stratégie est de garder des statistiques par thread et de les collecter sur demande
• Pas encore implémenté dans OpenDS !23Friday, December 10, 2010
PATTERNS
• Utilisation des I/O asynchrones
• Utilisation d'Objets Immuables
• Thread safe
• Less code
• Utilisation des “Static Factories” au lieu de Constructeurs
• Evite la création d'objets
• Permet des optimisations
• Avec des objet immuables.24Friday, December 10, 2010
PATTERNS
• Producteurs / Consommateurs
•Queues
• Pool de Threads
•Monitors
25Friday, December 10, 2010
ANTI-PATTERNS
•Manipulation de chaines (String)
• Il faut utiliser “StringBuilder”
• Le compilateur optimise aussi “Aaa” + “Bbb”
• Eviter les grandes méthodes (Milliers de lignes de code)
•Ne pas exposer la représentation concrète d'un objet
• Set vs LinkedHashSet
•Ne pas définir plus de méthodes que nécessaires26Friday, December 10, 2010
COLLECTIONS JAVA• Vector et Hashtable sont synchronisés (toutes les méthodes)
=> Un cout à payer, même avec un seul thread
• Certaines classes ne sont pas synchronisées par défaut
• ArrayList, LinkedList replacent Vector
• HashSet, HashMap replacent Hashtable
• Pour synchroniser : Enrober dans une classe.Par une méthode “static factory” Collections.synchronizedList(new ArrayList())
• ConcurrentHashMap, pour la concurrence
•Mais attention à l'itérateur27Friday, December 10, 2010
ATTENTION AUX TESTS DE PERFORMANCE
•Des tests reproductibles
•Maitrise du système et de l'environnement
• Avec 100 000 entrées LDAP lues par seconde, le goulet peut être le réseau
• Utilisation de 10GB ethernet
28Friday, December 10, 2010
LA JVM ET LES PARAMÈTRES DES PERFORMANCES
“Tuning GC” est un art !
Photo par Kecko http://www.flickr.com/people/kecko/
29Friday, December 10, 2010
GC DANS LA JVM HOTSPOT
• 3 GCs disponibles:
• Serial GC
• Parallel GC / Parallel Old GC
• Concurrent Mark-Sweep GC (CMS)
• Et bientôt Garbage First (G1)30Friday, December 10, 2010
GESTION DU TAS(POUR TOUS LES GCS)
Old Generation
Permanent Generation
Young Generation
31Friday, December 10, 2010
YOUNG GENERATION
Allocation (new Object())
Survivor SpacesEden
32Friday, December 10, 2010
OLD GENERATION
Promotion(survivors from
the Young Generation)
33Friday, December 10, 2010
PERMANENT GENERATION
Allocation(only directly from the JVM)
Permanent Generation
34Friday, December 10, 2010
LE GC RÊVÉ
• Idéalement il faudrait un GC avec
• une faible consommation CPU,
• des temps de pauses infimes et
• efficace en occupation mémoire
•Malheureusement, vous ne pouvez en choisir que 2 !Photo par Craig Gorcott http://www.flickr.com/photos/craigweb/
35Friday, December 10, 2010
CONSEIL POUR REGLER LA TAILLE DU TAS DE LA JVM
LE PLUS GROS POSSIBLE
36Friday, December 10, 2010
UN EQUILIBRE A TROUVER
• Généralement, plus gros est l’espace mémoire, le mieux c’est !
• Valable pour les 2 espaces (Young Gen, Old Gen)
• Un grand espace = des GCs moins fréquents, moins d’utilisation CPU, des objets qui sont vraiment détruits
• Un petit espace = des GCs plus rapide (pas toujours)
•Quelques fois, la taille maximale dépend de la mémoire physique et/ou de l’espace d’adressage de la JVM
• Il faut trouver l'équilibre entre les tailles des générations37Friday, December 10, 2010
L’IMPACT DES TAILLES DES GENERATIONS
• La taille de la “Young Generation”
•Détermine la fréquence des GCs mineurs
•Détermine combien d’objets vont être récoltés
• Ainsi que le “Tenuring Threshold” et la taille des “Survivor Spaces”
•Old Generation
•Doit contenir les données permanentes de l’application
• Réduire la fréquence des GCs majeurs le plus possible38Friday, December 10, 2010
2 POINTS TRÈS IMPORTANTS
• Essayer de maximiser le nombre d’objets collectés dans la “Young generation”
• L’empreinte mémoire de l’application ne doit pas dépasser la la taille de la mémoire physique
• Ceci est valable quelque soit le GC
39Friday, December 10, 2010
REGLER LA “YOUNG GENERATION”
40Friday, December 10, 2010
DIMENSIONER LA TAILLE MEMOIRE
• -Xmx<size> : Taille mémoire max. (young + old generation)
• -Xms<size> : Taille mémoire initiale (young + old generation)
• -Xmn<size> : Taille mémoire pour la “Young generation”
• Pour contrôler les performances, il est préférable de mettre -Xms and -Xmx à la même valeur
•Quand -Xms != -Xmx, l’accroissement ou diminution de la mémoire nécessite un GC complet.
41Friday, December 10, 2010
DIMENSIONER LA “YOUNG GENERATION”
• La taille de l’Eden influence
• La fréquence des GCs mineurs
• Les objets qui seront réclamés à l’age 0
• Les objets alloué dans l’Eden ont un age 0
• L’age est incrémenté chaque GC mineur
• Augmenter la taille de l’Eden n’impact pas toujours la durée des GCs mineurs : celle ci est proportionnelle au nombre d’objets copiés (objets vivants)
42Friday, December 10, 2010
DIMENSIONNER LES ESPACES MEMOIRES
• -XX:NewSize=<size> : Taille initiale de la “Young generation”
• -XX:MaxNewSize=<size> : Taille maximale de la “Young generation”
• -XX:NewRatio=<ratio> : Ratio entre “young generation” et “old generation”
• Pour contrôler les performances, préférer -Xmn qui combine-XX:NewSize et -XX:MaxNewSize
43Friday, December 10, 2010
TENURING
• -XX:TargetSurvivorRatio=<%>, e.g., 50
• Pourcentage d’occupation de l’espace “Survivor”
• Laisser de l’espace pour gérer les pics
• -XX:InitialTenuringThreshold=<threshold>
• -XX:MaxTenuringThreshold=<threshold>
• -XX:+AlwaysTenure - Ne rien garder dans les “Survivor”
• -XX:+NeverTenure - Une très mauvaise idée44Friday, December 10, 2010
TENURING : AVANTAGES & INCONVENIENTS
•Maintenir le plus d’objets dans les espaces “Survivor” pour qu’ils soient collectés dans la “Young generation”
•Moins de promotion vers la “Old generation”
•Moins de GCs de la “Old generation”
•Mais éviter les nombreuses copies entre espaces “Survivor”
• Augmente le cout des GCs mineurs
• Un équilibre difficile à trouver
• Généralement, il vaut mieux copier que promouvoir45Friday, December 10, 2010
GARBAGE FIRST
46Friday, December 10, 2010
LE GC GARBAGE FIRST (G1)
•Nouveauté de la VM Java HotSpot dans JDK 7
• Une version experimentale de G1 est dans Java SE 6 depuis la version mineur 14
• G1 est vu comme le replacement à long terme du GC “Concurrent Mark-Sweep” (CMS)
• Toujours expérimental dans Java SE 6 Update 23 ☹
47Friday, December 10, 2010
CARACTERISTIQUES DE G1
• Le remplacement de CMS
• Un GC pour les Serveurs
• Parallèle, Concurrent
• S’appuie sur des Générations
• Auto Compactant
• Facile d’utilisation
• Prédictif (mais pas temps réel)
• Les étapes principales sont: remembered set (RS) maintenance, concurrent marking, and evacuation pauses.
48Friday, December 10, 2010
G1: LES OPTIONS DE LA JVM
• -XX:+UnlockExperimentalVMOptions-XX:+UseG1GC
• Temps de pause (pas garanti, sinon utiliser Java Temps Réel)
• -XX:MaxGCPauseMillis=50 (objectif de 50 millisecondes)
• -XX:GCPauseIntervalMillis=1000 (objectif de 1000 msecs)
•Dimension: -XX:+G1YoungGenSize=512m
• Parallélisme:
• -XX:+G1ParallelRSetUpdatingEnabled
• -XX:+G1ParallelRSetScanningEnabled49Friday, December 10, 2010
OPENDS ET CMS
• Les options
• CMS + Occupency
•NewGenSize = ¼ de la taille mémoire (jusqu’à 2GB)
•MaxTenuringThreshold = 1
• Temps de pause maximum GC mineur ~ 100ms
•Mais Full GC en écriture ! 10 seconds ☹50Friday, December 10, 2010
OPENDS ET G1
•Objectif: Eviter le GC Complet, meilleur contrôle des pauses
• Collaboration entre les équipes HotSpot et OpenDS
•OpenDS est utilisé comme application de référence
• Entre 20 et 30 améliorations integrées dans G1 suite aux tests
• Améliorations par 10 des performances de G1 avec de grandes zones mémoires
51Friday, December 10, 2010
LE CONTROLE DU GC
• En direct:
• VisualVM: http://visualvm.dev.java.net/
• VisualGC:
• http://java.sun.com/performance/jvmstat/
• VisualGC est aussi un module extension de VisualVM
• Peut surveiller plusieurs VM dans le même outil
• A posteriori
• GC Logging, PrintGCStats, GChisto
Photo par Rennett Stowe http://www.flickr.com/photos/tomsaint/
52Friday, December 10, 2010
LE JOURNAL DU GC ACTIVÉ EN PRODUCTION
• Activer le journal du GC en production sans crainte
• Très utile pour analyser, diagnostiquer un problème
• Coût en performance extrêmement faible
• Peut-être quelques gros fichiers à gérer
• Il y a toujours des clients qui ont peur d’activer les logs
• Un (gros) client de Sun a dit : “If someone doesn't enable GC logging in production, I shoot them!”
53Friday, December 10, 2010
PARAMETRES POUR LE JOURNAL DU GC
• -XX:+PrintGCTimeStamps
• Ajouter -XX:+PrintGCDateStamps si besoin
• -XX:+PrintGCDetails
•Donne plus de détails que -verbosegc
•Mais aussi:
• -Xloggc:<fichier>
• Permet de séparer les sorties du GC de celles de l’application
54Friday, December 10, 2010
PRINTGCSTATS• Analyse et résume les journaux du GC
• Un script disponible
• http://java.sun.com/developer/technicalArticles/Programming/turbo/PrintGCStats.zip
• Usage
• PrintGCStats -v cpus=<num> <gc log file>
•Ou <num> est le nombre de CPU de la machine qui a produit les logs.
• Peut ne pas marcher avec certains paramètres du log du GC55Friday, December 10, 2010
PRINTGCSTATS PARALLEL GC
• what count total mean max stddevgen0t(s) 193 11.470 0.05943 0.687 0.0633gen1t(s) 1 7.350 7.34973 7.350 0.0000GC(s) 194 18.819 0.09701 7.350 0.5272alloc(MB) 193 11244.609 58.26222 100.875 18.8519promo(MB) 193 807.236 4.18257 96.426 9.9291used0(MB) 193 16018.930 82.99964 114.375 17.4899used1(MB) 1 635.896 635.89648 635.896 0.0000used(MB) 194 91802.213 473.20728 736.490 87.8376commit0(MB) 193 17854.188 92.50874 114.500 9.8209commit1(MB) 193 123520.000 640.00000 640.000 0.0000commit(MB) 193 141374.188 732.50874 754.500 9.8209
alloc/elapsed_time = 11244.609 MB / 77.237 s = 145.586 MB/salloc/tot_cpu_time = 11244.609 MB / 1235.792 s = 9.099 MB/salloc/mut_cpu_time = 11244.609 MB / 934.682 s = 12.030 MB/spromo/elapsed_time = 807.236 MB / 77.237 s = 10.451 MB/spromo/gc0_time = 807.236 MB / 11.470 s = 70.380 MB/sgc_seq_load = 301.110 s / 1235.792 s = 24.366%gc_conc_load = 0.000 s / 1235.792 s = 0.000%gc_tot_load = 301.110 s / 1235.792 s = 24.366%
56Friday, December 10, 2010
PRINTGCSTATS CMS• what count total mean max stddev
gen0(s) 110 24.381 0.22164 1.751 0.2038gen0t(s) 110 24.397 0.22179 1.751 0.2038cmsIM(s) 3 0.285 0.09494 0.108 0.0112cmsRM(s) 3 0.092 0.03074 0.032 0.0015GC(s) 113 24.774 0.21924 1.751 0.2013cmsCM(s) 3 2.459 0.81967 0.835 0.0146cmsCP(s) 6 0.971 0.16183 0.191 0.0272cmsCS(s) 3 14.620 4.87333 4.916 0.0638cmsCR(s) 3 0.036 0.01200 0.016 0.0035alloc(MB) 110 11275.000 102.50000 102.500 0.0000promo(MB) 110 1322.718 12.02471 104.608 11.8770used0(MB) 110 12664.750 115.13409 115.250 1.2157used(MB) 110 56546.542 514.05947 640.625 91.5858commit0(MB) 110 12677.500 115.25000 115.250 0.0000commit1(MB) 110 70400.000 640.00000 640.000 0.0000commit(MB) 110 83077.500 755.25000 755.250 0.0000
alloc/elapsed_time = 11275.000 MB / 83.621 s = 134.835 MB/salloc/tot_cpu_time = 11275.000 MB / 1337.936 s = 8.427 MB/salloc/mut_cpu_time = 11275.000 MB / 923.472 s = 12.209 MB/spromo/elapsed_time = 1322.718 MB / 83.621 s = 15.818 MB/spromo/gc0_time = 1322.718 MB / 24.397 s = 54.217 MB/sgc_seq_load = 396.378 s / 1337.936 s = 29.626%gc_conc_load = 18.086 s / 1337.936 s = 1.352%gc_tot_load = 414.464 s / 1337.936 s = 30.978%
57Friday, December 10, 2010
GCHISTO
• Pour une visualisation graphique des journaux du GC
•Développement démarré en 2008 (mais arrêté ?)
• Affiche uniquement les temps de pause
•Open source sur Java.net : http://gchisto.dev.java.net/
• Peut ne pas marcher avec certains paramètres du log du GC
58Friday, December 10, 2010
EN RÉSUMÉ
•OpenDS: Un serveur LDAP en Java, open source
• Simple à installer et utiliser
• Conçu pour de hautes performances et haute disponibilité
•OpenDJ pour une version supportée (et améliorée)
• Le paramètrage de la JVM et du GC est un Art
• L'ingénierie des performances, un métier !
• Comprendre la JVM et les GCs est indispensable
•Qui a dit que Java est lent !59Friday, December 10, 2010
MAINTENANT...
• Essayez OpenDJ:
• http://www.opendj.org
• IRC: #opendj on freenode.net
• Participez !
60Friday, December 10, 2010
• Ludovic Poitou
• Twitter : @LudoMP
• Blog: http://ludopoitou.wordpress.com
Concevoir un serveurultra-performant en Java :
l'expérience du projet OpenDS
61Friday, December 10, 2010