Table of Contents
Tuning pour Alfresco
alfresco java tuning
Quelques tricks pour Alfresco sous Linux.
JVM
Alfresco démarre avec une jvm limitée en mémoire vive. Il faut changer les valeurs par défaut. Les paramètres suivants peuvent être ajoutées dans la variable JAVA_OPTS du script de démarrage alfresco.sh
Disons que nous voulons dédier 2Go de RAM à notre JVM. On va séparer cela de la façon suivante :
- 1800Mo pour le tas (heap) utilisé directement par l'application
- 256Mo pour la partie de mémoire dédiée aux objets permanents
export JAVA_OPTS='-Xms2G -Xmx2G -Xss1024k -XX:NewSize=512m -XX:MaxPermSize=248m -server -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi.dgc.server.gcInterval=1800000 -XX:+UseParallelGC -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseLargePages -XX:LargePageSizeInBytes=4m'
- Xss: la taille de la pile (stack) pour chaque thread
- Xms: la taille initiale du tas (heap)
- Xmx: la taille maximale du tas (heap)
- NewSize: la taille du tas (heap) dédié à la nouvelle génération d'objets
- MaxPermSize: la taille dédiée aux objets permanents (Spring beans, caches, etc.) qui s'additionne à Xmx pour calculer la taille totale prise par l'application
Xmx et Xss sont positionnés à la même valeur, de fait la taille de Xmx est allouée dés le démarrage de l'application et on évite les croissances/décroissances dangereuse en terme d'allocation.
Concernant la garbage collection, voir le wiki d'alfresco.
Voir aussi les tips du serveur JBoss concernant le tuning de jvm : JBoss Performance Tuning
Voir aussi: A Test of Java Virtual Machine Performance.
Utilisation des LargePages
Linux dispose d'un système d'allocation de pages mémoire de grande taille (voir ici pour une introduction du sujet, ou dans les sources du noyau “kernel/Documentation/vm/hugetlbpage.txt”). Ces pages peuvent être configurées et utilisées par la JVM pour améliorer la gestion de la mémoire.
Les étapes sont les suivantes :
Créer les pages dans la mémoire existante
Augmenter la taille maximale du segment du mémoire partagée :
kernel.shmmax = 3221225472 (3Go, la taille max de RAM sur le système)
Allouer des pages dans la mémoire vive existante:
vm.nr_hugepages = 512 (faisable via “echo 512 > /proc/sys/vm/nr_hugepages”)
La mémoire ainsi allouée est considérée comme attribuée et n'est disponible qu'au travers du système de fichier hugetlbfs (cat /proc/filesystems). Donc, avec une taille de Hugepagesize de 4mo, ca fait 4*512 = 2Go de Hugepage allouée.
# cat /proc/meminfo [...] HugePages_Total: 512 HugePages_Free: 42 HugePages_Rsvd: 42 HugePages_Surp: 0 Hugepagesize: 4096 kB
Explication prise de la doc du noyau:
33 HugePages_Total: vvv 34 HugePages_Free: www 35 HugePages_Rsvd: xxx 36 HugePages_Surp: yyy 37 Hugepagesize: zzz kB 38 39 where: 40 HugePages_Total is the size of the pool of hugepages. 41 HugePages_Free is the number of hugepages in the pool that are not yet 42 allocated. 43 HugePages_Rsvd is short for "reserved," and is the number of hugepages 44 for which a commitment to allocate from the pool has been made, but no 45 allocation has yet been made. It's vaguely analogous to overcommit. 46 HugePages_Surp is short for "surplus," and is the number of hugepages in 47 the pool above the value in /proc/sys/vm/nr_hugepages. The maximum 48 number of surplus hugepages is controlled by 49 /proc/sys/vm/nr_overcommit_hugepages.
Augmenter les ressources utilisables par Alfresco
Au niveau du système, il faut augmenter la taille maximale d'un segment de mémoire partagée, avant que java puisse utiliser la shared memory mise à dispo par les Larges Pages.
On positionne la taille max de ce segment à 2.5Go (2684354560 octets).
# sysctl -w kernel.shmmax=2684354560
Et on dit que le groupe “1665”, auquel appartient l'utilisateur alfresco, peut utiliser les hugespages. Sans ce paramètre, l'application lancée sous l'utilisateur alfresco n'aura pas le droit d'allouer de mémoire dans le filesystem hugetlbfs et allouera donc dans la mémoire classique.
# sysctl -w vm.hugetlb_shm_group=1665
L'utilisateur doit avoir le droit de placer en MEMLOCK l'ensemble des hugepages. Si alfresco est lancé depuis un bash, il faut augmenter la valeur de max locked memory à Hugepagesize * HugePages_Total (avec 2Go attribués à la jvm, on a besoin de 4096*512 = 2097152KB, disons donc 2621440KB pour être large) et stocker cela dans le fichier “/etc/security/limits.conf” (checké par pam au login).
#<domain> <type> <item> <value> # * hard nofile 4096 * soft nofile 4096 * hard memlock 2621440 * soft memlock 2621440
Une limit Hard est fixée au niveau du noyau, donc inchangeable pour l'utilisateur, alors qu'une limite Soft peut être changée par l'utilisateur via ulimit. On ne s'embête pas avec ça ici. Hard=Soft, c'est plus simple.
Dire à la JVM d'utiliser les Large Pages
Dans les paramètres JAVA_OPTS du lancement de la jvm, mettre :
-XX:+UseLargePages -XX:LargePageSizeInBytes=4m
Qui donne la taille de hugepage a utiliser, ainsi que l'ordre d'utiliser les hugepage à disposition. Attention, s'il n'y a pas de hugepage a disposition, le système reviendra en arrière et allouera dans des pages classiques.
Reste à relancer la JVM et on vois tout de suite l'utilisation des LargePages :
# cat /proc/meminfo [...] HugePages_Total: 512 HugePages_Free: 143 HugePages_Rsvd: 43 HugePages_Surp: 0 Hugepagesize: 4096 kB
troubleshooting
La méthode limits.conf ne marche pas sous lenny (à investiguer). Il faut se loguer en root et modifier les valeurs de limits puis faire un su pour lancer le script démarrage d'alfresco. Les limits Soft et Hard sont alors héritées de root et ça fonctionne.
# ulimit -H -l 2621440 # ulimit -S -l 2621440 # ulimit -H -n 4096 # ulimit -S -n 4096
puis
# su - alfresco -s /bin/bash -c '/etc/alfresco/alfresco.sh start'
Réduire le "swappiness"
vm.swappiness is a tunable kernel parameter that controls how much the kernel favors swap over RAM. At the source code level, it’s also defined as the tendency to steal mapped memory. A high swappiness value means that the kernel will be more apt to unmap mapped pages. A low swappiness value means the opposite, the kernel will be less apt to unmap mapped pages. In other words, the higher the vm.swappiness value, the more the system will swap.
Valeur choisir:
sysctl -w vm.swappiness=1
~~DISCUSSION~~