[JAVA] Untersuchen Sie die Grenzen der "32 GB Speicherwand" in Elasticsearch

Einführung

Elasticsearch hat lange über die Existenz einer "32-GB-Wand" beim Einstellen der Größe des JVM-Heapspeichers gesprochen. Die Standardeinstellung ist 1g für Xms und Xmx. Dieser Parameter muss jedoch entsprechend der im Knoten installierten Speichergröße angepasst werden.

Legen Sie in der Elasticsearch 2.x-Ära die Größe des JVM-Heapspeichers im [Elasticsearch Definitive Guide] fest (https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html). Als Leistungstipp wurde erwähnt, dass es 32 GB nicht überschreitet. Das aktuelle offizielle Dokument empfiehlt außerdem, dass diese Größe "ungefähr" 32 GB nicht überschreiten sollte. Es ist gewesen.

Dieser Artikel fasst zusammen, wie diese genaue Schwellenwert-Speichergröße in einer Umgebung ermittelt wird. Beachten Sie, dass dieser Inhalt je nach Betriebssystemversion und JDK-Version unterschiedlich ist. Führen Sie daher die folgenden Schritte aus, um die genaue Größe in Ihrer Umgebung zu überprüfen.

Was ist eine "32 GB Wand" (ungefähr)

Zunächst geht es nicht nur um Elasticsearch. Dies ist eine Geschichte, die für alle JVM-Anwendungen gilt. Grob gesagt bezieht sich die hier erwähnte "32-GB-Wand" auf die Funktion, die Systemressourcen spart, indem die Darstellungsmethode des Referenzzeigers des im Java-Heap auf einem 64-Bit-System gespeicherten Objekts komprimiert wird. Es gibt.

Auf der folgenden Site (* 1) finden Sie eine ausführliche Erläuterung. Normalerweise beträgt die Java-Heap-Adresse auf einem 64-Bit-System 64 Bit. Nur wenn die Heap-Größe 32 GB oder weniger beträgt, lautet sie wie folgt. Es ist ein Trick, mit einer 32-Bit-Adresse Geld zu sparen, indem Sie sie innerhalb der Einschränkungen halten.

Auf diese Weise ist es möglich, eine Adresse von 35 Bit (= 2 ^ 35 ≒ 32 GB) auszudrücken, die bisher nur 4 GB (= 2 ^ 32) mit 32 Bit ausdrücken konnte. Dieser Mechanismus wird als "komprimierte OOPs" bezeichnet (siehe Komprimierte Objekte).

*1: https://www.baeldung.com/jvm-compressed-oops

hoge

Natürlich kann diese Methode nicht verwendet werden, wenn Heapspeicher mit 32 GB oder mehr verwendet werden. Daher handelt es sich um eine normale Objektreferenz mit 64 Bit. In diesem Fall ist die Effizienz der Speichernutzung geringer als bei Verwendung komprimierter OOPs. Es wird daher empfohlen, die Heap-Größe nicht über 32 GB Speicher hinaus festzulegen.

Überprüfungsverfahren

Hier verwenden wir die folgende Umgebung, um die "Grenze" komprimierter OOPs zu untersuchen und gleichzeitig die Größe des Heaps zu ändern. Zusammenfassend lässt sich sagen, dass sich diese Grenzlinie je nach GC-Typ ändert. Daher untersuchen wir jeden der beiden Typen CMS (ConcMark Sweep) und G1GC, die mit JDK11 verwendet werden können.

Umgebung

Ich habe eine virtuelle Maschine / ein virtuelles Betriebssystem mit den folgenden Spezifikationen in Azure bereitgestellt und OpenJDK und ELasticsearch installiert.

Kombination von GC-Typ und Heap-Größe

Wir haben mit den folgenden vier Kombinationen verifiziert. Beachten Sie, dass die Größe des Rahmenhaufens zwischen 01,02 und 03,04 geringfügig abweicht. (30 MB anders) Wenn die Größe die Grenzliniengröße für jeden GC überschreitet, z. B. 01 und 02, 03 und 04, können keine komprimierten OOPs verwendet werden. Unten finden Sie eine Zusammenfassung der Schritte, um dies tatsächlich zu überprüfen.

no. GC-Typ Wurfgröße(Xms/Xmx) Kann Compressed Oops verwendet werden?
01 CMS(ConcMarkSweep) 32766MB Kann verwendet werden
02 CMS(ConcMarkSweep) 32767MB Nicht verfügbar
03 G1GC 32736MB Kann verwendet werden
04 G1GC 32737MB Nicht verfügbar

Bestätigungsverfahren (1) Bestätigung nur mit der JVM

Überprüfen Sie zunächst nur die JVM. Dies verwendet eine Methode, um zu überprüfen, ob die JVM mit Compressed Oops ausgeführt wird, indem der Java-Befehl mit der Option "-XX: + PrintFlagsFinal" ausgeführt wird.

01: CMS GC unterhalb der Grenze (32766 MB)

Beachten Sie die letzte Zeile der Ausgabe unten. Der Teil, in dem "bool Use Compressed Oops = true" ist, wird ausgegeben, wenn Compressed Oops aktiviert ist. Mit anderen Worten, die "32 GB Wand" wird nicht überschritten.

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}

02: Grenze über (32767 MB) mit CMS GC

"Bool Use CompressedOops = false", das die "32 GB-Wand" überschreitet.

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}

03: Unterhalb der Grenze bei G1GC (32736 MB)

Es heißt "bool Use CompressedOops = true". Die "32 GB Wand" wird nicht überschritten.

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}

04: Grenze über (32737 MB) bei G1GC

Es heißt "bool Use CompressedOops = false". Es überschreitet die "32 GB Wand".

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}

Bestätigungsverfahren ② Bestätigung mit Elasticsearch

Geben Sie als Nächstes die Heap-Größe in der Datei jvm.option in Elasticsearch an und überprüfen Sie sie. Das Ergebnis wird in elasticsearch.log protokolliert, um festzustellen, ob es sich beim Start im Compressed Oops-Modus befindet. Überprüfen Sie dies.

01: CMS GC unterhalb der Grenze (32766 MB)

Nehmen Sie die folgenden Einstellungen in der Datei jvm.option vor. Die Zeilen 3-7 bleiben auf ihren Standardeinstellungen. Da wir diesmal OpenJDK11 verwenden, wird CMS für GC verwendet. (Der für gc.log verwendete GC-Typ wird ebenfalls ausgegeben.)

jvm.options


-Xms32766m
-Xmx32766m

# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30

Wenn Sie Elasticsearch mit dieser Einstellung starten, wird die folgende Zeile im Protokoll angezeigt. "Komprimierte gewöhnliche Objektzeiger [true]" am Ende der Zeile ist ein Zeichen dafür, dass Compressed Oops gültig ist.

elasticsearch.log


[2020-03-30T07:26:14,269][INFO ][o.e.e.NodeEnvironment    ] [vm01] heap size [31.9gb], compressed ordinary object pointers [true]

02: Grenze über (32767 MB) mit CMS GC

Nehmen Sie die folgenden Einstellungen in der Datei jvm.option vor. Nur die Heap-Größe der 1. und 2. Zeile wird geändert.

jvm.options


-Xms32767m
-Xmx32767m

# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30

Diesmal wurde es "komprimierte gewöhnliche Objektzeiger [false]". Sie können sehen, dass Compressed Oops deaktiviert wurde.

elasticsearch.log


[2020-03-30T09:43:01,828][INFO ][o.e.e.NodeEnvironment    ] [vm01] heap size [31.9gb], compressed ordinary object pointers [false]

03: Unterhalb der Grenze bei G1GC (32736 MB)

Die GC-Einstellungen werden gemäß den Kommentaren in der Einstellungsdatei zusammen mit der Heap-Größe geändert. Da wir diesmal OpenJDK11 verwenden, wird G1GC mit dieser Einstellung verwendet. (Ich habe auch die Ausgabe von gc.log überprüft)

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 ist hier aktiviert.

elasticsearch.log


[2020-03-30T07:22:29,694][INFO ][o.e.e.NodeEnvironment    ] [vm01] heap size [31.9gb], compressed ordinary object pointers [true]

04: G1GC über die Grenze (32737 MB)

Erhöhen Sie die Heap-Größe um 1 MB. Andere haben sich nicht verändert.

jvm.options


-Xms32737m
-Xmx32737m

10-13:-XX:-UseConcMarkSweepGC
10-13:-XX:-UseCMSInitiatingOccupancyOnly
11-:-XX:+UseG1GC
11-:-XX:G1ReservePercent=25
11-:-XX:InitiatingHeapOccupancyPercent=30

Dieses Mal ist Compressed Oops deaktiviert.

elasticsearch.log


[2020-03-30T07:23:19,486][INFO ][o.e.e.NodeEnvironment    ] [vm01] heap size [31.9gb], compressed ordinary object pointers [false]

Zusammenfassung

In Bezug auf die "32-GB-Wand", auf die in Elasticsearch häufig Bezug genommen wird, eine Übersicht über den Mechanismus von Compressed Oops (siehe komprimierte Objekte) in Bezug auf JVM im Allgemeinen und das Verfahren zum Überprüfen, ob Compressed Oops beim Starten von JVM und Elasticsearch in der tatsächlichen Umgebung aktiviert oder deaktiviert ist. Ich habe es vorgestellt. Bei der Betrachtung einer geeigneten Heap-Größe sind einige Punkte zu berücksichtigen, z. B. der Zweck von Elasticsearch (Volltextsuchcenter, metrisches Sortier- / Aggregationscenter usw.) und der von Lucene verwendete Cache-Speicher. Wenn Sie Fragen haben, wird empfohlen, eine Community-Site wie "Diskussion.elastic.co" oder einen Experten bei einer Benutzer-Community / Lernsitzung wie "Elasticsearch Tokyo User Group" zu fragen.

Recommended Posts

Untersuchen Sie die Grenzen der "32 GB Speicherwand" in Elasticsearch
Untersuchen Sie die Speichernutzung von Java-Elementen
Die Geschichte von @ViewScoped, die Speicher verschlingt
Untersuchen Sie die Liste der Zeitzonen-IDs, die in der Java ZoneId-Klasse verfügbar sind
Reihenfolge der Verarbeitung im Programm
Holen Sie sich das Ergebnis von POST in Java
Die Identität der Schienenparameter [: id]
Die Geschichte des Schreibens von Java in Emacs
Schreiben Sie die Bewegung von Rakefile in das Runbook
[Bestellmethode] Legen Sie die Reihenfolge der Daten in Rails fest
Die Geschichte des einfachen String-Vergleichs in Java
[Java] Behandlung von Java Beans in der Methodenkette
Die Geschichte eines gewöhnlichen Othello in Java
Über die Idee anonymer Klassen in Java
Die Geschichte des Lernens von Java in der ersten Programmierung
Messen Sie die Größe eines Ordners mit Java
Spüren Sie den Lauf der Zeit auch in Java
Importieren Sie Dateien derselben Hierarchie in Java