Elasticsearch a longtemps parlé de l'existence d'un "mur de 32 Go" dans la définition de la taille de la mémoire du tas JVM. Le paramètre par défaut est 1g pour Xms et Xmx, mais ce paramètre doit être dimensionné de manière appropriée en fonction de la quantité de mémoire installée dans le nœud.
À l'ère Elasticsearch 2.x, définissez la taille du tas JVM dans le Elasticsearch Definitive Guide. Il a été mentionné comme un conseil de performance qu'il ne dépasse pas 32 Go. Le [document officiel] actuel (https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html) recommande également que cette taille ne dépasse pas «environ» 32 Go. Ça a été.
Cet article résume comment trouver cette taille de mémoire seuil exacte dans un environnement. Notez que ce contenu varie en fonction de la version du système d'exploitation et de la version JDK, assurez-vous donc de bien suivre les étapes suivantes pour vérifier la taille exacte dans votre environnement.
Tout d'abord, il ne s'agit pas seulement d'Elasticsearch. C'est une histoire qui s'applique à toutes les applications JVM. En gros, le "mur de 32 Go" évoqué ici est lié à la fonction qui économise les ressources système en compressant la méthode de représentation du pointeur de référence de l'objet stocké dans le tas Java sur un système 64 bits. Il y a.
Il y a une explication détaillée sur le site suivant (* 1), mais normalement l'adresse du tas Java sur un système 64 bits est de 64 bits, mais seulement si la taille du tas est de 32 Go ou moins, c'est comme suit. C'est une astuce pour économiser de l'argent avec une adresse 32 bits en la maintenant dans les contraintes.
--Limitez l'adresse des objets du tas à une taille qui est un multiple de 8 (appelé alignement des objets)
En faisant cela, il est possible d'exprimer une adresse de 35 bits (= 2 ^ 35 ≒ 32 Go), qui n'était auparavant possible d'exprimer que 4 Go (= 2 ^ 32) avec 32 bits. Ce mécanisme est appelé "POO compressés" (voir Objets compressés).
*1: https://www.baeldung.com/jvm-compressed-oops
Bien sûr, cette méthode ne peut pas être utilisée avec une mémoire de tas de 32 Go ou plus, ce sera donc une référence d'objet normale utilisant 64 bits. Dans ce cas, l'efficacité d'utilisation de la mémoire est inférieure à celle de l'utilisation de la POO compressée, il est donc recommandé de ne pas définir la taille du tas au-delà de 32 Go de mémoire.
Ici, nous utiliserons l'environnement suivant pour explorer la «limite» des POO compressés tout en modifiant la taille du tas. En conclusion, cette ligne de démarcation change en fonction du type de GC, nous étudions donc chacun des deux types de CMS: ConcMarkSweep) et G1GC qui peuvent être utilisés avec JDK11.
J'ai déployé une machine virtuelle / un système d'exploitation avec les spécifications suivantes sur Azure et installé OpenJDK et ELasticsearch.
Nous avons vérifié avec les quatre combinaisons suivantes. Notez que la taille du tas de bordure est légèrement différente entre 01,02 et 03,04. (30 Mo différents) De plus, si la taille dépasse la taille de la ligne de délimitation pour chaque GC, comme 01 et 02, 03 et 04, les POO compressés ne peuvent pas être utilisés. Voici un résumé des étapes à suivre pour le vérifier.
no. | Type de GC | Taille du tas(Xms/Xmx) | Peut-on utiliser Compressed Oops? |
---|---|---|---|
01 | CMS(ConcMarkSweep) | 32766MB | Peut être utilisé |
02 | CMS(ConcMarkSweep) | 32767MB | Indisponible |
03 | G1GC | 32736MB | Peut être utilisé |
04 | G1GC | 32737MB | Indisponible |
Tout d'abord, vérifiez la JVM seule. Cela utilise une méthode pour vérifier si la JVM fonctionne avec Compressed Oops en exécutant la commande java avec l'option "-XX: + PrintFlagsFinal".
Notez la dernière ligne de la sortie ci-dessous. La partie où "bool Use Compressed Oops = true" est la sortie lorsque Compressed Oops est activé. En d'autres termes, le «mur de 32 Go» n'est pas dépassé.
sodo@vm01:~$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32766m -Xmx32766m 2>/dev/null | grep Compressed
size_t CompressedClassSpaceSize = 1073741824 {product} {default}
bool UseCompressedClassPointers = true {lp64_product} {ergonomic}
bool UseCompressedOops = true {lp64_product} {ergonomic}
"Bool Use CompressedOops = false", qui dépasse le "mur de 32 Go".
sodo@vm01:~$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32767m -Xmx32767m 2>/dev/null | grep Compressed
size_t CompressedClassSpaceSize = 1073741824 {product} {default}
bool UseCompressedClassPointers = false {lp64_product} {default}
bool UseCompressedOops = false {lp64_product} {default}
Il dit "bool Use CompressedOops = true". Il ne dépasse pas le "mur de 32 Go".
sodo@vm01:~$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32736m -Xmx32736m 2>/dev/null | grep Compressed
size_t CompressedClassSpaceSize = 1073741824 {product} {default}
bool UseCompressedClassPointers = true {lp64_product} {ergonomic}
bool UseCompressedOops = true {lp64_product} {ergonomic}
Il dit "bool Use CompressedOops = false". Il dépasse le "mur de 32 Go".
sodo@vm01:~$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32737m -Xmx32737m 2>/dev/null | grep Compressed
size_t CompressedClassSpaceSize = 1073741824 {product} {default}
bool UseCompressedClassPointers = false {lp64_product} {default}
bool UseCompressedOops = false {lp64_product} {default}
Ensuite, utilisez la recherche élastique pour spécifier la taille du tas dans le fichier jvm.option et vérifiez. Le résultat sera enregistré dans elasticsearch.log pour voir s'il est en mode Compressed Oops au démarrage, alors vérifiez cela.
Définissez les paramètres suivants dans le fichier jvm.option. Les lignes 3 à 7 sont laissées à leurs valeurs par défaut. Puisque nous utilisons OpenJDK11 cette fois, CMS est utilisé pour GC. (Le type GC utilisé pour gc.log est également affiché)
jvm.options
-Xms32766m
-Xmx32766m
# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30
Lorsque vous démarrez Elasticsearch avec ce paramètre, vous verrez la ligne suivante dans le journal: "Pointeurs d'objets ordinaires compressés [vrai]" à la fin de la ligne est un signe que Compressed Oops est valide.
elasticsearch.log
[2020-03-30T07:26:14,269][INFO ][o.e.e.NodeEnvironment ] [vm01] heap size [31.9gb], compressed ordinary object pointers [true]
Définissez les paramètres suivants dans le fichier jvm.option. Seule la taille du tas des 1ère et 2ème lignes est modifiée.
jvm.options
-Xms32767m
-Xmx32767m
# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30
Cette fois, il est devenu "des pointeurs d'objets ordinaires compressés [faux]". Vous pouvez voir que Compressed Oops a été désactivé.
elasticsearch.log
[2020-03-30T09:43:01,828][INFO ][o.e.e.NodeEnvironment ] [vm01] heap size [31.9gb], compressed ordinary object pointers [false]
Les paramètres du CPG sont modifiés en fonction des commentaires dans le fichier de paramètres ainsi que de la taille du tas. Puisque nous utilisons OpenJDK11 cette fois, G1GC est utilisé avec ce paramètre. (J'ai également vérifié la sortie de gc.log)
jvm.options
-Xms32736m
-Xmx32736m
10-13:-XX:-UseConcMarkSweepGC
10-13:-XX:-UseCMSInitiatingOccupancyOnly
11-:-XX:+UseG1GC
11-:-XX:G1ReservePercent=25
11-:-XX:InitiatingHeapOccupancyPercent=30
Compressed Oops est activé ici.
elasticsearch.log
[2020-03-30T07:22:29,694][INFO ][o.e.e.NodeEnvironment ] [vm01] heap size [31.9gb], compressed ordinary object pointers [true]
Augmentez la taille du tas de 1 Mo. D'autres n'ont pas changé.
jvm.options
-Xms32737m
-Xmx32737m
10-13:-XX:-UseConcMarkSweepGC
10-13:-XX:-UseCMSInitiatingOccupancyOnly
11-:-XX:+UseG1GC
11-:-XX:G1ReservePercent=25
11-:-XX:InitiatingHeapOccupancyPercent=30
Cette fois, Compressed Oops est désactivé.
elasticsearch.log
[2020-03-30T07:23:19,486][INFO ][o.e.e.NodeEnvironment ] [vm01] heap size [31.9gb], compressed ordinary object pointers [false]
Concernant le «mur de 32 Go» souvent mentionné dans Elasticsearch, un aperçu du mécanisme de Compressed Oops (voir objets compressés) lié à JVM en général, et la procédure pour vérifier si Compressed Oops est activé ou désactivé lors du démarrage de JVM et Elasticsearch dans l'environnement réel. Je l'ai présenté. En fait, lorsque l'on considère une taille de tas appropriée, il y a quelques points à considérer, tels que l'objectif d'Elasticsearch (centre de recherche en texte intégral, centre de tri métrique / d'agrégation, etc.) et la mémoire cache utilisée par Lucene. Si vous avez des questions, il est recommandé de demander à un site communautaire tel que discuss.elastic.co, ou de demander à un expert lors d'une communauté d'utilisateurs / session d'étude telle que Elasticsearch Tokyo User Group.
Recommended Posts