Vous êtes sur la page 1sur 58

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS

Ludovic Poitou
OpenDS Community Manager Sun Microsystems, Inc.

Petite prsentation
Ludovic Poitou
> Senior Staff Engineer

Sun Microsystems > Community Manager pour le projet OpenDS > Plus de 13 ans d'experience avec LDAP
> Architecte de Sun Directory Server 5.2 / 6 > Participation aux groupes LDAP l'IETF

http://blogs.sun.com/Ludo
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Agenda
Une prsentation du projet OpenDS Modles de conceptions et rflexions sur la notion de performance La JVM et les performances Conclusion

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 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
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Qu'est ce ?
OpenDS est un server en Java qui implmente le protocol LDAPv3 et ses services Il inclut sa propre base de donnes
> Bas sur Berkeley DB Java Edition > Pas accessible directement

Possde toutes les fonctions de scurit, de contrle d'accs, de gestion de mots de passes pour stocker de faon scurise les identits des utilisateurs et machines
5

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Pourquoi Faire ?
Stockage gnrique et orient objet de donnes Pages blanches et carnet d'adresses ml Principalement le coffre fort des Identits
> Pour l'Authentication et les Authorizations > Pour les Profiles et Personnalisations

La brique de base de tout systme d'Information dans les entreprises


> Utilis par l'infrastructure Web et Mail > Le fondement des produits de gestion d'Identit > Gestion d'Access, Federation, Provisionage
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Les Objectifs du projet OpenDS


Un jeu complet de Services d'Annuaire
L'annuaire base de donnes Conforme aux standards et extensions LDAP v3 Replication multi-maitre Des services de Proxy d'annuaire : repartition de charge, distribution des donnes, services de scurit... > Fonctions d'annuaire virtuel
> > > >

Capacit de croissance horizontale et verticale Utiliser le code d'OpenDS pour le produit Oracle Directory Server Enterprise Edition
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Trois Principes
Facilit d'utilisation
> Installation, Configuration, Gestion, Surveillance...

Capacit d'extension
> De nombreuses interfaces ont t dfinies > Avec des implmentations par dfault

Performance
> C'est le coeur de cette prsentation !

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

OpenDS 2.2
Disponible depuis Dcembre 2009 Un serveur d'annuaire 100% conforme LDAPv3
> Nombreuses extensions LDAP standards et exprimentales > Rplication Multi Maitre, avec 3 niveaux de cohrence des

donnes > Fonctions tendues de Scurit

S'installe en 6 clics et moins de 3 minutes Gestion par outils graphiques et textes Documentation complte sur le Wiki Localis en 6 langues
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

Pour qui ?
Les oprateurs Tlcom, le secteur financier qui utilisent les services d'annuaire pour des services clients (Portail...)
> Pour stocker les identits des clients, telephones et services > Des services de 15 120 millions d'entres, hautement

disponibles

Mais OpenDS peut tre utilis pour le service de Nommage, ou les PME
> > > >

OpenSolaris, Solaris, Linux... Coupl avec SAMBA Intgr avec Kerberos Pages blanches...
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

10

Caractristiques de performances
Comme tout serveur, les capacits de monte en charge priment
> > > >

Jusqu' plusieurs dizaines de millions d'entres Plusieurs milliers de connections Quel dbit d'oprations? Quel temps de rponse moyen ? Maximum ?

Le test de base :
> 10 M d'entres, taille moyenne 2,6K > Rplication multi-maitre entre 2 serveurs

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

11

Les rglages du test

config.ldif
> ds-cfg-db-log-file-max: 100 megabytes > ds-cfg-db-cache-percent: 70-80 > ds-cfg-db-checkpointer-bytes-interval: 100 megabytes > ds-cfg-etime-resolution: nanoseconds > ds-cfg-num-request-handlers: 4 > Replication ON
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

12

Searchrate sur x4170

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

13

Modrate sur x4170

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

14

Reflexions sur la Conception

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

15

Comment obtenir de tels rsultats ?


2 Aspects
> Le code > Le run-time : l'optimisation de la JVM et du Garbage

Collector

Une relation trs forte entre la conception du code et la gestion mmoire

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

16

Performance vs Parallelisme
Impact des performances sur le parallelisme
> Code srialis cre 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

Rglage du goulet d'tranglement L'objectif : Rpondre aux besoins

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

17

Attentions aux Sections Critiques


Essayer de rduire au maximum le temps pass en section critique Mais la bande passante est limite par le temps pass dans la plus grosse section critique
> Exemple : LinkedBlockingQueue > 200 000 operations sur processor x64 > 20 000 sur processor T2000 > Utilise pour la WorkQueue et les Access Logs

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

18

Le cache d'entres
Un cache permet de rduire les acces disques L'viction du cache rajoute du travail au GC
> Modifications des entres > Cache trop petit pour toutes les donnes

Un cache global est point de contention Cacher uniquement des objets qui vont etre reutiliss (et pas peut-etre) L'utilisation de cache thread local peut etre interessant
> Mais attention au cout (1000 threads ?)
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

19

Le monitoring du serveur
Les statistiques sont indispensables Mais attention a la contention
> Ecritures frequentes (update stats) > Lecture beaucoup moins

Une stratgie est de garder des statistiques par thread et de les collecter sur demande Pas encore implment dans OpenDS !

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

20

Patterns
Utilisation des I/O asynchrones Utilisation d'Objets Immuables
> Thread safe > Less code

Utilisation des Static Factories au lieu de Constructeurs


> Evite la creation d'objets > Permet des optimisations > Exemple: AttributeDescription (0, 1 ou plusieurs options) > Avec des objet immuables.
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

21

Patterns
Producteurs / Consommateurs
> Queues > Pool de Threads > Monitors

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

22

Anti-Patterns
Manipulation de chaines (String)
> Utiliser StringBuilder > Le compilateur optimise aussi Aaa + Bbb

Eviter les grandes methodes (Millier de lignes de code) Ne pas exposer la reprsentation concrete d'un objet
> Set vs LinkedHashSet

Ne pas dfinir plus de mthodes que ncessaires


Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

23

Collections Java

Vector et Hashtable sont synchroniss pour toutes les mthodes Un cout payer, mme avec un seul thread Certaines classes des collections Java ne sont pas synchronises by default.
> > > >

ArrayList, LinkedList replacent Vector HashSet, HashMap replacent Hashtable Pour synchroniser: Enrober dans une classe. Par une mthode static factory
> Collections.synchronizedList(new ArrayList())

ConcurrentHashMap, pour la concurrence Mais attention l'itrateur


Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

24

Attention aux tests de performance


Des tests reproductibles Maitrise du systme et de l'environnement Avec 100 000 entres LDAP lues par seconde, le goulet peut tre le rseau
> Utilisation de 10GB ethernet

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

25

La JVM et les paramtres des performances


Tuning GC est un art

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

26

GCs in the HotSpot JVM


Three available GCs:
> > > >

Serial GC Parallel GC / Parallel Old GC Concurrent Mark-Sweep GC (CMS) And soon Garbage First (G1)

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

27

Heap Layout (same for all GCs)


Young Generation

Old Generation

Permanent Generation

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

28

Young Generation
Allocation (new Object())

Eden

Survivor Spaces

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

29

Old Generation

Promotion (survivors from the Young Generation)

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

30

Permanent Generation

Allocation (only directly from the JVM)


Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

31

Your Dream GC
You would really like a GC that has
> Low GC overhead, > Low GC pause times, and > Good space efficiency

Unfortunately, you'll have to pick two (any two!)

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

32

Heap Sizing Tuning Advice

Supersize it!

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

33

Heap Sizing Trade-Offs


Generally, the larger the heap space, the better
> For both young and old generation > Larger space: less frequent GCs, lower GC overhead,

objects more likely to become garbage > Smaller space: faster GCs (not always! see later)

Sometimes max heap size is dictated by available memory and/or max space the JVM can address
> You have to find a good balance between young and old

generation size

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

34

Generation Size Roles


Young Generation Size
> Dictates frequency of minor GCs > Dictates how many objects will be reclaimed in the young

generation

> Along with tenuring threshold + survivor space size tuning

Old Generation
> Should comfortably hold the application's steady-state

live size > Decrease the major GC frequency as much as possible

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

35

Two Very Important Points


You should try to maximize the number of objects reclaimed in the young generation
> This is probably the most important piece of advice when

sizing a heap and/or tuning the young generation

Your application's memory footprint should not exceed the available physical memory
> This is probably the second most important piece of

advice when sizing a heap

The above apply to all GCs

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

36

Tuning Young Generation

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

37

Sizing Heap Spaces


-Xmx<size> : max heap size
> young generation + old generation

-Xms<size> : initial heap size


> young generation + old generation

-Xmn<size> : young generation size Applications with emphasis on performance tend to set -Xms and -Xmx to the same value When -Xms != -Xmx, heap growth or shrinking requires a Full GC
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

38

Young Generation Sizing


Eden size determines
> The frequency of minor GCs > Which objects will be reclaimed at age 0 > Newly-allocated objects in Eden start from age 0 > Their age is incremented at every minor GC

Increasing the size of the Eden will not always affect minor GC times
> Remember: minor GC times are proportional to the

amount of objects they copy (i.e., the live objects), not the young generation size
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

39

Sizing Heap Spaces (iii)


-XX:NewSize=<size> : initial young generation size -XX:MaxNewSize=<size> : max young generation size -XX:NewRatio=<ratio> : young generation to old generation ratio Applications with emphasis on performance tend to use -Xmn to size the young generation since it combines the use of -XX:NewSize and -XX:MaxNewSize
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

40

Tenuring
-XX:TargetSurvivorRatio=<percent>, e.g., 50
> How much of the survivor space should be filled > Typically leave extra space to deal with spikes

-XX:InitialTenuringThreshold=<threshold> -XX:MaxTenuringThreshold=<threshold> -XX:+AlwaysTenure


> Never keep any objects in the survivor spaces

-XX:+NeverTenure
> Very bad idea!
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

41

Tenuring Threshold Trade-Offs


Try to retain as many objects as possible in the survivor spaces so that they can be reclaimed in the young generation
> Less promotion into the old generation > Less frequent old GCs

But also, try not to unnecessarily copy very longlived objects between the survivors
> Unnecessary overhead on minor GCs

Not always easy to find the perfect balance


> Generally: better copy more, than promote more
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

42

Garbage First

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

43

The Garbage First (G1) GC


Introduced in the Java HotSpot VM in JDK 7. An experimental version of G1 has also been released since Java SE 6 Update 14. G1 is the long-term replacement for HotSpot's lowlatency Concurrent Mark-Sweep (CMS) GC Should be officially supported with Java SE 6 Update 21

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

44

G1 Characteristics
> > > > > > >

Future CMS Replacement


Server Style Garbage Collector Parallel, Concurrent Generational Good Throughput Compacting Improved ease-of-use Predictable (though not hard real-time)

The main stages consist of remembered set (RS) maintenance, concurrent marking, and evacuation pauses.
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

45

JVM Options With G1


-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC PauseTime (Hints, Goal with no promise, otherwise use Java Real Time )
> -XX:MaxGCPauseMillis=50 (target of 50 milliseconds) > -XX:GCPauseIntervalMillis=1000 (target of 1000 msecs)

Generation Size
> -XX:+G1YoungGenSize=512m (for a 512 MB young gen)

Parallelism
> -XX:+G1ParallelRSetUpdatingEnabled > -XX:+G1ParallelRSetScanningEnabled
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

46

OpenDS et CMS
Les options
> CMS + Occupency > NewGenSize = heap size (up to 2GB) > MaxTenuringThreshold = 1

Max New Gen pause time ~ 100ms Mais Full GC en criture ! 10 seconds :(

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

47

OpenDS et G1
Objectif: Eviter le GC Complet, meilleur contrle des pauses Collaboration entre les quipes HotSpot et OpenDS
> OpenDS est utilis comme application de rfrence > Entre 10 et 20 amliorations integres dans G1 suite aux

tests > Amliorations par 10 des performances de G1 avec de grandes zones mmoires

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

48

Monitoring the GC
Online
> VisualVM: http://visualvm.dev.java.net/ > VisualGC: > http://java.sun.com/performance/jvmstat/ > VisualGC is also available as a VisualVM plug-in > Can monitor multiple JVMs within the same tool

Offline
> GC Logging > PrintGCStats > GChisto
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

49

GC Logging in Production
Don't be afraid to enable GC logging in production
> Very helpful when diagnosing production issues

Extremely low / non-existent overhead


> Maybe some large files in your file system. :-) > We are surprised that customers are still afraid to enable

it

Real customer quote:


> If someone doesn't enable GC logging in production, I

shoot them!

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

50

Important GC Logging Parameters


You need at least:
> -XX:+PrintGCTimeStamps > Add -XX:+PrintGCDateStamps if you must > -XX:+PrintGCDetails > Preferred over -verbosegc as it's more detailed

Also useful:
> -Xloggc:<file> > Separates GC logging output from application output

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

51

PrintGCStats
Summarizes GC logs Downloadable script from
> http://java.sun.com/developer/technicalArticles/Program

ming/turbo/PrintGCStats.zip

Usage
> PrintGCStats -v cpus=<num> <gc log file> > Where <num> is the number of CPUs on the machine where the GC log was obtained

It might not work with some of the printing flags


Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

52

PrintGCStats Parallel GC

what gen0t(s) gen1t(s) GC(s) alloc(MB) promo(MB) used0(MB) used1(MB) used(MB) commit0(MB) commit1(MB) commit(MB)

count 193 1 194 193 193 193 1 194 193 193 193 = = = = = = = =

total 11.470 7.350 18.819 11244.609 807.236 16018.930 635.896 91802.213 17854.188 123520.000 141374.188 11244.609 11244.609 11244.609 807.236 807.236 301.110 0.000 301.110 MB MB MB MB MB s s s / / / / / / / /

mean 0.05943 7.34973 0.09701 58.26222 4.18257 82.99964 635.89648 473.20728 92.50874 640.00000 732.50874 77.237 1235.792 934.682 77.237 11.470 1235.792 1235.792 1235.792 s s s s s s s s

max 0.687 7.350 7.350 100.875 96.426 114.375 635.896 736.490 114.500 640.000 754.500

stddev 0.0633 0.0000 0.5272 18.8519 9.9291 17.4899 0.0000 87.8376 9.8209 0.0000 9.8209

alloc/elapsed_time alloc/tot_cpu_time alloc/mut_cpu_time promo/elapsed_time promo/gc0_time gc_seq_load gc_conc_load gc_tot_load

= 145.586 MB/s = 9.099 MB/s = 12.030 MB/s = 10.451 MB/s = 70.380 MB/s = 24.366% = 0.000% = 24.366%

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

53

PrintGCStats CMS

what gen0(s) gen0t(s) cmsIM(s) cmsRM(s) GC(s) cmsCM(s) cmsCP(s) cmsCS(s) cmsCR(s) alloc(MB) promo(MB) used0(MB) used(MB) commit0(MB) commit1(MB) commit(MB)

count 110 110 3 3 113 3 6 3 3 110 110 110 110 110 110 110

total 24.381 24.397 0.285 0.092 24.774 2.459 0.971 14.620 0.036 11275.000 1322.718 12664.750 56546.542 12677.500 70400.000 83077.500

mean 0.22164 0.22179 0.09494 0.03074 0.21924 0.81967 0.16183 4.87333 0.01200 102.50000 12.02471 115.13409 514.05947 115.25000 640.00000 755.25000

max 1.751 1.751 0.108 0.032 1.751 0.835 0.191 4.916 0.016 102.500 104.608 115.250 640.625 115.250 640.000 755.250

stddev 0.2038 0.2038 0.0112 0.0015 0.2013 0.0146 0.0272 0.0638 0.0035 0.0000 11.8770 1.2157 91.5858 0.0000 0.0000 0.0000

alloc/elapsed_time = 11275.000 MB / 83.621 s = 134.835 MB/s alloc/tot_cpu_time = 11275.000 MB / 1337.936 s = 8.427 MB/s alloc/mut_cpu_time = 11275.000 MB / 923.472 s = 12.209 MB/s promo/elapsed_time = 1322.718 MB / 83.621 s = 15.818 MB/s promo/gc0_time = 1322.718 MB / 24.397 s = 54.217 MB/s gc_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 : l'exprience du projet OpenDS = Mai 2010 1337.936 s 25 30.978% Concevoir un serveur ultra-performant en Java /

54

GChisto
Graphical GC log visualizer Under development
> Currently, can only show pause times

Open source at
> http://gchisto.dev.java.net/

It might not work with some of the printing flags

Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

55

En Rsum
OpenDS
> Un serveur LDAP en Java, open source > Simple installer et utiliser > Conu pour de hautes performances et haute

disponibilit

Le paramtrage de la JVM et du GC est un Art L'ingnierie des performances, un mtier ! Comprendre la JVM et les GCs est indispensable Qui a dit que Java est lent !
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

56

Maintenant...
Essayez OpenDS:
> http://www.opends.org

Rejoignez la communit
> > > >

Join/Login sur Java.net http://opends.dev.java.net Request a Role IRC: #opends on freenode.net

OpenDS est localis en plusieurs langues, mais les contributions sont apprcies
Concevoir un serveur ultra-performant en Java : l'exprience du projet OpenDS 25 Mai 2010

57

Concevoir un serveur TEMPLATE ultra-performant en Java : l'exprience du projet ENDING SLIDE WITHOUT PHOTO OpenDS
Ludovic Poitou
ludovic.poitou@sun.com http://blogs.sun.com/Ludo

58