TL;DR: The main question here is: How Does Java 9 Work with Elasticsearch 6? It works well, but don’t expect miracles. Unless you’re using G1, then there are some miracles.
With Java 9 fresh out of the oven and Elasticsearch 6 still in the oven but almost fully baked, we thought we should take them out for a spin and find an answer to a couple of questions:
- Do they actually work together, or is there some crazy error to be expected?
- If yes, what are the benefits of upgrading?
Out of the list of Java 9 features and improvements, two things stood out for us:
- compact strings, because heap size could be smaller.
- G1 garbage collector improvements. Yes, we know that some advise against G1 on Lucene-based search engines such as Elasticsearch, but the argument there isn’t all that clear and we had mostly good experiences with G1 for years now. On Java 9, G1 becomes the default and CMS – currently used by Elasticsearch as default – becomes deprecated (you will see a deprecation message in the logs).
Test Conditions: Java 9 With Elasticsearch 6
We compared Java HotSpot 1.8.0_144 with OpenJDK build 9+181 using Elasticsearch 6 beta 2 on a 4 vCPU, 8GB of RAM, SSD-backed physical box. The test was to index some data (10M firewall logs) at moderate throughput (~5K docs/s from an external Logstash – this ate about 50% of the CPU) while at the same time looping a query with an aggregation.
Using Sematext Monitoring for Elasticsearch we captured pretty much all the Elasticsearch metrics known to mankind, from GC times to query latencies. There were two distinct runs: one with the default GC settings, and one with G1 GC enabled instead of CMS.
Since we knew there were no significant changes for CMS between Java 8 and 9, using it helped us pinpoint any non-GC related changes (like the influence of the new compact strings). Using G1 separately helped us see the G1-related changes.
Results: Garbage Collectors 3 Times Faster for Java 9
To our surprise, it turned out that none of those non-GC related changes existed. All the metrics we checked were similar with Java 8 and Java 9, from indexing and query throughput and latencies, to GC times, heap size variations, and CPU usage.
As an example, here’s a query latency graph (average and 99th percentile). If anything, the Java 9 result is slightly worse, especially when looking at the 99th percentile, though this can be attributed to noise.
The debate was always about stability. While we can always invoke the “time will tell” argument, what was your experience with G1?