This is an automated email from the ASF dual-hosted git repository. git-site-role pushed a commit to branch asf-site in repository https://gitbox.apache.org/repos/asf/accumulo-website.git
The following commit(s) were added to refs/heads/asf-site by this push: new 013c8139 Automatic Site Publish by Buildbot 013c8139 is described below commit 013c8139c5661d3e4bf347de316652508ab5b3f6 Author: buildbot <us...@infra.apache.org> AuthorDate: Mon Apr 22 18:30:59 2024 +0000 Automatic Site Publish by Buildbot --- .../09/does-a-compactor-return-memory-to-OS.html | 784 +++++++++++++++++++++ output/feed.xml | 779 ++++++++++++++++---- .../java_11_G1_x1_s256_OS_manualaftercomp.png | Bin 0 -> 43355 bytes .../java_11_G1_x1_s256_OS_manualeverymin.png | Bin 0 -> 50814 bytes .../java_11_G1_x1_s256_VM_manualaftercomp.png | Bin 0 -> 75308 bytes .../java_11_G1_x1_s256_VM_manualeverymin.png | Bin 0 -> 82280 bytes .../java_11_G1_x2_s256_OS.png | Bin 0 -> 28529 bytes .../java_11_G1_x2_s256_VM.png | Bin 0 -> 47531 bytes .../java_11_UseShenandoah_x2_s256_OS.png | Bin 0 -> 42611 bytes .../java_11_UseShenandoah_x2_s256_VM.png | Bin 0 -> 61003 bytes .../java_17_G1_x1_s256_periodic60000_OS.png | Bin 0 -> 44141 bytes .../java_17_G1_x1_s256_periodic60000_VM.png | Bin 0 -> 71509 bytes ...a_17_G1_x1_s256_periodic60000_concurrent_OS.png | Bin 0 -> 43634 bytes ...a_17_G1_x1_s256_periodic60000_concurrent_VM.png | Bin 0 -> 70558 bytes .../java_17_G1_x2_s256_periodic60000_OS.png | Bin 0 -> 43125 bytes .../java_17_G1_x2_s256_periodic60000_VM.png | Bin 0 -> 66620 bytes ...a_17_G1_x2_s256_periodic60000_concurrent_OS.png | Bin 0 -> 45506 bytes ...a_17_G1_x2_s256_periodic60000_concurrent_VM.png | Bin 0 -> 63855 bytes .../java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png | Bin 0 -> 41548 bytes .../java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png | Bin 0 -> 52411 bytes ...java_17_shenandoah_x1_s256_UseShenandoah_OS.png | Bin 0 -> 40636 bytes ...java_17_shenandoah_x1_s256_UseShenandoah_VM.png | Bin 0 -> 65872 bytes ...java_17_shenandoah_x2_s256_UseShenandoah_OS.png | Bin 0 -> 43690 bytes ...java_17_shenandoah_x2_s256_UseShenandoah_VM.png | Bin 0 -> 61385 bytes .../java_21_G1_x2_s256_periodic60000_OS.png | Bin 0 -> 44449 bytes .../java_21_G1_x2_s256_periodic60000_VM.png | Bin 0 -> 66057 bytes ...ZGC_x2_s256_UseZGC_generational_uncommit_OS.png | Bin 0 -> 43089 bytes ...ZGC_x2_s256_UseZGC_generational_uncommit_VM.png | Bin 0 -> 57747 bytes .../java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png | Bin 0 -> 43433 bytes .../java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png | Bin 0 -> 53290 bytes ...java_21_shenandoah_x1_s256_UseShenandoah_OS.png | Bin 0 -> 28541 bytes ...java_21_shenandoah_x1_s256_UseShenandoah_VM.png | Bin 0 -> 54165 bytes ...java_21_shenandoah_x2_s256_UseShenandoah_OS.png | Bin 0 -> 44314 bytes ...java_21_shenandoah_x2_s256_UseShenandoah_VM.png | Bin 0 -> 60324 bytes output/index.html | 14 +- output/news/index.html | 13 +- output/search_data.json | 8 + 37 files changed, 1434 insertions(+), 164 deletions(-) diff --git a/output/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html b/output/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html new file mode 100644 index 00000000..807b23db --- /dev/null +++ b/output/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html @@ -0,0 +1,784 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous"> +<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs5/dt-1.13.6/datatables.min.css"> +<link href="/css/accumulo.css" rel="stylesheet" type="text/css"> + +<title>Does a compactor process return memory to the OS?</title> + +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script> +<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script> +<script type="text/javascript" src="https://cdn.datatables.net/v/bs5/dt-1.13.6/datatables.min.js"></script> +<script type="text/javascript" src="https://www.apachecon.com/event-images/snippet.js"></script> +<script> + // show location of canonical site if not currently on the canonical site + $(function() { + var host = window.location.host; + if (typeof host !== 'undefined' && host !== 'accumulo.apache.org') { + $('#non-canonical').show(); + } + }); + + $(function() { + // decorate section headers with anchors + return $("h2, h3, h4, h5, h6").not(".accordion-header").each(function(i, el) { + var $el, icon, id; + $el = $(el); + id = $el.attr('id'); + icon = '<span class="fa-solid fa-link"></span>'; + if (id) { + return $el.append($("<a />").addClass("header-link").attr("href", "#" + id).html(icon)); + } + }); + }); + + // fix sidebar width in documentation + $(function() { + var $affixElement = $('div[data-spy="affix"]'); + $affixElement.width($affixElement.parent().width()); + }); +</script> + +</head> +<body style="padding-top: 100px"> + + <nav class="navbar navbar-expand-lg navbar-light fixed-top bg-light"> + <div class="container"> + <a class="navbar-brand" href="/"> + <img alt="Apache Accumulo" id="nav-logo" src="/images/accumulo-logo.png" width="200"> + </a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-items"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbar-items"> + <ul class="navbar-nav me-auto"> + <li class="nav-item"><a class="nav-link" href="/downloads">Download</a></li> + <li class="nav-item"><a class="nav-link" href="/tour">Tour</a></li> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">Releases</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="/release/accumulo-3.0.0/">3.0.0 (Latest non-LTM)</a></li> + <li><a class="dropdown-item" href="/release/accumulo-2.1.2/">2.1.2 (Latest LTM)</a></li> + <li><a class="dropdown-item" href="/release/accumulo-1.10.4/">1.10.4 (Legacy LTM)</a></li> + <li><a class="dropdown-item" href="/release/">Archive</a></li> + </ul> + </li> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">Documentation</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="/docs/2.x">User Manual (2.x)</a></li> + <li><a class="dropdown-item" href="/docs/2.x/apidocs">Javadocs (2.x)</a></li> + <li><a class="dropdown-item" href="/api">Public API</a></li> + <li><a class="dropdown-item" href="/quickstart-1.x">Quickstart (1.x)</a></li> + <li><a class="dropdown-item" href="/accumulo2-maven-plugin">Accumulo Maven Plugin</a></li> + <li><a class="dropdown-item" href="/1.10/accumulo_user_manual.html">User Manual (1.10)</a></li> + <li><a class="dropdown-item" href="/1.10/apidocs">Javadocs (1.10)</a></li> + <li><a class="dropdown-item" href="/external-docs">External Docs</a></li> + <li><a class="dropdown-item" href="/docs-archive/">Archive</a></li> + </ul> + </li> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">Community</a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="/contact-us">Contact Us</a></li> + <li><a class="dropdown-item" href="/how-to-contribute">How To Contribute</a></li> + <li><a class="dropdown-item" href="/people">People</a></li> + <li><a class="dropdown-item" href="/related-projects">Related Projects</a></li> + </ul> + </li> + <li class="nav-item"><a class="nav-link" href="/search">Search</a></li> + </ul> + <ul class="navbar-nav ms-auto"> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown"> + <img alt="Apache Software Foundation" src="https://www.apache.org/foundation/press/kit/feather.svg" width="15"/> + </a> + <ul class="dropdown-menu"> + <li><a class="dropdown-item" href="https://www.apache.org">Apache Homepage <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/licenses/">License <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/foundation/sponsorship">Sponsorship <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/security">Security <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/foundation/thanks">Thanks <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/foundation/policies/conduct">Code of Conduct <span class="fa-solid fa-up-right-from-square"></span></a></li> + <li><a class="dropdown-item" href="https://www.apache.org/events/current-event.html">Current Event <span class="fa-solid fa-up-right-from-square"></span></a></li> + </ul> + </li> + </ul> + </div> + </div> +</nav> + + + <div class="container"> + <div class="row"> + <div class="col-md-12"> + + <div id="non-canonical" style="display: none; background-color: #F0E68C; padding-left: 1em;"> + Visit the official site at: <a href="https://accumulo.apache.org">https://accumulo.apache.org</a> + </div> + <div id="content"> + + <h1 class="title">Does a compactor process return memory to the OS?</h1> + + <p> +<b>Author: </b> Dominic Garguilo, Kevin Rathbun<br> +<b>Date: </b> 09 Apr 2024<br> + +</p> + +<h2 id="goal">Goal</h2> +<p>The goal of the project was to determine if, once an Accumulo process is finished using memory, the JVM would release this unused memory back to the operating system. This was specifically observed in a Compactor process during the tests, but the findings should apply to any Accumulo Server process. We looked at the memory usage of the compactor process specifically to help understand if oversubscribing compactors on a machine is a viable option.</p> + +<p>As background information, it’s important to note that modern JVMs are expected to release memory back to the operating system, rather than just growing from the initial heap size (-Xms) to the maximum heap size (-Xmx) and never releasing it. This behavior was introduced in Java 11 through the <a href="https://openjdk.org/jeps/346">JEP 346: Promptly Return Unused Committed Memory from G1</a>. This feature aims to improve the efficiency of memory usage by actively returning Java heap m [...] +<h3 id="test-scenario">Test Scenario</h3> +<p>There could be a scenario where the amount of memory on a machine limits the number of compactors that can be run. For example, on a machine with 32GB of memory, if each compactor process uses 6GB of memory, we can only “fit” 5 compactors on that machine (32/6=5.333). Since each compactor process only runs on a single core, we would only be utilizing 5 cores on that machine where we would like to be using as many as we can.</p> + +<p>If the compactor process does not return the memory to the OS, then we are stuck with only using the following number of compactor processes: +<code class="language-plaintext highlighter-rouge">(total memory)/(memory per compactor)</code>. +If the compactor processes return the memory to the OS, i.e. does not stay at the maximum 6GB once they reach it, then we can oversubscribe the memory allowing us to run more compactor processes on that machine.</p> + +<p>It should be noted that there is an inherent risk when oversubscribing processes that the user must be willing to accept if they choose to do oversubscribe. In this case, there is the possibility that all compactors run at the same time which might use all the memory on the machine. This could cause one or more of the compactor processes to be killed by the OOM killer.</p> + +<h2 id="test-setup">Test Setup</h2> + +<h3 id="environment-prerequisites">Environment Prerequisites</h3> + +<p>The machines used for testing were running Pop!_OS 22.04 a debian-based OS. The following package installation and usage steps may vary if one were try to repeat these steps.</p> + +<h4 id="install-gnuplot">Install gnuplot</h4> + +<p>This was used for plotting the memory usage of the compactor over time from the perspective of the OS</p> + +<ol> + <li><code class="language-plaintext highlighter-rouge">sudo apt install gnuplot</code></li> + <li>gnuplot was started with the command <code class="language-plaintext highlighter-rouge">gnuplot</code></li> +</ol> + +<h4 id="install-visualvm">Install VisualVM</h4> + +<p>This was used for plotting the memory usage of the compactor over time from the perspective of the JVM</p> + +<ol> + <li>Downloaded the zip from <a href="https://visualvm.github.io/">visualvm.github.io</a></li> + <li>Extracted with <code class="language-plaintext highlighter-rouge">unzip visualvm_218.zip</code></li> + <li>VisualVM was started with the command <code class="language-plaintext highlighter-rouge">./path/to/visualvm_218/bin/visualvm</code></li> +</ol> + +<h4 id="configure-and-start-accumulo">Configure and start accumulo</h4> + +<p>Accumulo 2.1 was used for experimentation. To stand up a single node instance, <a href="https://github.com/apache/fluo-uno">fluo-uno</a> was used.</p> + +<p>Steps taken to configure accumulo to start compactors:</p> + +<ol> + <li>Uncommented lines in <code class="language-plaintext highlighter-rouge">fluo-uno/install/accumulo-2.1.2/conf/cluster.yaml</code> regarding the compaction coordinator and compactor q1. A single compactor process was used, q1. This allows the external compaction processes to start up.</li> + <li>Configured the java args for the compactor process in “accumulo-env.sh.” Line: +<code class="language-plaintext highlighter-rouge">compactor) JAVA_OPTS=('-Xmx256m' '-Xms256m' "${JAVA_OPTS[@]}") ;;</code></li> + <li>Started accumulo with <code class="language-plaintext highlighter-rouge">uno start accumulo</code></li> +</ol> + +<h4 id="install-java-versions">Install java versions</h4> + +<ol> + <li>Installed java versions 11, 17 and 21. For example, Java 17 was installed with: + <ol> + <li><code class="language-plaintext highlighter-rouge">sudo apt install openjdk-17-jdk</code></li> + <li><code class="language-plaintext highlighter-rouge">sudo update-alternatives --config java</code> and select the intended version before starting the accumulo instance</li> + <li>Ensured <code class="language-plaintext highlighter-rouge">JAVA_HOME</code> was set to the intended version of java before each test run</li> + </ol> + </li> +</ol> + +<h2 id="running-the-test">Running the test</h2> + +<ol> + <li>Started accumulo using <a href="https://github.com/apache/fluo-uno">fluo-uno</a> (after changing the mentioned configuration) + <ul> + <li><code class="language-plaintext highlighter-rouge">uno start accumulo</code></li> + </ul> + </li> + <li>Opened VisualVM and selected the running compactor q1 process taking note of the PID</li> + <li>Ran <code class="language-plaintext highlighter-rouge">mem_usage_script.sh <compactor process PID></code>. This collected measurements of memory used by the compactor process over time from the perspective of the OS. We let this continue to run while the compaction script was running.</li> + <li>Configured the external compaction script as needed and executed: + <ul> + <li><code class="language-plaintext highlighter-rouge">uno jshell experiment.jsh</code></li> + </ul> + </li> + <li>Memory usage was monitored from the perspective of the JVM (using VisualVM) and from the perspective of the OS (using our collection script). +Navigated to the “Monitor” tab of the compactor in VisualVM to see the graph of memory usage from JVM perspective. +Followed the info given in the <a href="#os-memory-data-collection-script">OS Memory Data Collection Script</a> section to plot the memory usage from OS perspective.</li> +</ol> + +<p>Helpful resources:</p> +<ul> + <li><a href="https://accumulo.apache.org/blog/2021/07/08/external-compactions.html">External Compactions accumulo blog post</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/z-garbage-collector.html#GUID-8637B158-4F35-4E2D-8E7B-9DAEF15BB3CD">Z garbage collector heap size docs</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/garbage-collector-implementation.html#GUID-71D796B3-CBAB-4D80-B5C3-2620E45F6E5D">Generational Garbage Collection docs</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/garbage-first-g1-garbage-collector1.html#GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573">G1 garbage collector docs</a></li> + <li><a href="https://thomas.preissler.me/blog/2021/05/02/release-memory-back-to-the-os-with-java-11">Java 11 and memory release article</a></li> +</ul> + +<h3 id="external-compaction-test-script">External compaction test script</h3> + +<p>Initiates an external compaction of 700MB of data (20 files of size 35MB) on Compactor q1.</p> + +<p><strong><em>referred to as experiment.jsh in the test setup section</em></strong></p> + +<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">org.apache.accumulo.core.conf.Property</span><span class="o">;</span> + +<span class="kt">int</span> <span class="n">dataSize</span> <span class="o">=</span> <span class="mi">35_000_000</span><span class="o">;</span> +<span class="kt">byte</span><span class="o">[]</span> <span class="n">data</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="n">dataSize</span><span class="o">];</span> +<span class="nc">Arrays</span><span class="o">.</span><span class="na">fill</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="o">(</span><span class="kt">byte</span><span class="o">)</span> <span class="mi">65</span><span class="o">);</span> +<span class="nc">String</span> <span class="n">tableName</span> <span class="o">=</span> <span class="s">"testTable"</span><span class="o">;</span> + +<span class="kt">void</span> <span class="nf">ingestAndCompact</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> + <span class="k">try</span> <span class="o">{</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">delete</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span> + <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">TableNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> + <span class="c1">// ignore </span> + <span class="o">}</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Creating table "</span> <span class="o">+</span> <span class="n">tableName</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">create</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span> + + <span class="c1">// This is done to avoid system compactions, we want to initiate the compactions manually </span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="nc">Property</span><span class="o">.</span><span class="na">TABLE_MAJC_RATIO</span><span class="o">.</span><span class="na">getKey</span><span class="o">(),</span> <span class="s">"1000"</span><span class="o">);</span> + <span class="c1">// Configure for external compaction </span> + <span class="n">client</span><span class="o">.</span><span class="na">instanceOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="s">"tserver.compaction.major.service.cs1.planner"</span><span class="o">,</span><span class="s">"org.apache.accumulo.core.spi.compaction.DefaultCompactionPlanner"</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">instanceOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="s">"tserver.compaction.major.service.cs1.planner.opts.executors"</span><span class="o">,</span><span class="s">"[{\"name\":\"large\",\"type\":\"external\",\"queue\":\"q1\"}]"</span><span class="o">);</span> + + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="s">"table.compaction.dispatcher"</span><span class="o">,</span> <span class="s">"org.apache.accumulo.core.spi.compaction.SimpleCompactionDispatcher"</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="s">"table.compaction.dispatcher.opts.service"</span><span class="o">,</span> <span class="s">"cs1"</span><span class="o">);</span> + + <span class="kt">int</span> <span class="n">numFiles</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span> + + <span class="k">try</span> <span class="o">(</span><span class="kt">var</span> <span class="n">writer</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">createBatchWriter</span><span class="o">(</span><span class="n">tableName</span><span class="o">))</span> <span class="o">{</span> + <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">numFiles</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span> + <span class="nc">Mutation</span> <span class="n">mut</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Mutation</span><span class="o">(</span><span class="s">"r"</span> <span class="o">+</span> <span class="n">i</span><span class="o">);</span> + <span class="n">mut</span><span class="o">.</span><span class="na">at</span><span class="o">().</span><span class="na">family</span><span class="o">(</span><span class="s">"cf"</span><span class="o">).</span><span class="na">qualifier</span><span class="o">(</span><span class="s">"cq"</span><span class="o">).</span><span class="na">put</span><span class="o">(</span><span class="n">data</span><span class="o">);</span> + <span class="n">writer</span><span class="o">.</span><span class="na">addMutation</span><span class="o">(</span><span class="n">mut</span><span class="o">);</span> + <span class="n">writer</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Writing "</span> <span class="o">+</span> <span class="n">dataSize</span> <span class="o">+</span> <span class="s">" bytes to a single value"</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">flush</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">null</span><span class="o">,</span> <span class="kc">true</span><span class="o">);</span> + <span class="o">}</span> + <span class="o">}</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Compacting table"</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">compact</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="k">new</span> <span class="nc">CompactionConfig</span><span class="o">().</span><span class="na">setWait</span><span class="o">(</span><span class="kc">true</span><span class="o">));</span> + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Finished table compaction"</span><span class="o">);</span> +<span class="o">}</span> + +<span class="n">ingestAndCompact</span><span class="o">();</span> +<span class="c1">// Optionally sleep and ingestAndCompact() again, or just execute the script again.</span> +</code></pre></div></div> + +<h3 id="os-memory-data-collection-script">OS Memory Data Collection Script</h3> + +<p>Tracks the Resident Set Size (RSS) of the given PID over time, outputting the data to output_mem_usage.log. +Data is taken every 5 seconds for an hour or until stopped.</p> + +<p><strong><em>referred to as mem_usage_script.sh in the test setup section</em></strong></p> + +<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash </span> +<span class="nv">PID</span><span class="o">=</span><span class="nv">$1</span> +<span class="nb">echo</span> <span class="s2">"Tracking PID: </span><span class="nv">$PID</span><span class="s2">"</span> +<span class="nv">DURATION</span><span class="o">=</span>3600 <span class="c"># for 1 hour </span> +<span class="nv">INTERVAL</span><span class="o">=</span>5 <span class="c"># every 5 seconds </span> +<span class="nb">rm </span>output_mem_usage.log + +<span class="k">while</span> <span class="o">[</span> <span class="nv">$DURATION</span> <span class="nt">-gt</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">do + </span>ps <span class="nt">-o</span> %mem,rss <span class="nt">-p</span> <span class="nv">$PID</span> | <span class="nb">tail</span> <span class="nt">-n</span> +2 <span class="o">>></span> output_mem_usage.log + <span class="nb">sleep</span> <span class="nv">$INTERVAL</span> + <span class="nv">DURATION</span><span class="o">=</span><span class="k">$((</span>DURATION <span class="o">-</span> INTERVAL<span class="k">))</span> +<span class="k">done</span> +</code></pre></div></div> + +<p>After compactions have completed plot the data using gnuplot:</p> + +<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gnuplot +<span class="nb">set </span>title <span class="s2">"Resident Set Size (RSS) Memory usage"</span> +<span class="nb">set </span>xlabel <span class="s2">"Time"</span> +<span class="nb">set </span>ylabel <span class="s2">"Mem usage in kilobytes"</span> +plot <span class="s2">"output_mem_usage.log"</span> using <span class="o">(</span><span class="nv">$0</span><span class="k">*</span>5<span class="o">)</span>:2 with lines title <span class="s1">'Mem usage'</span> +</code></pre></div></div> + +<h2 id="data">Data</h2> + +<p>Important Notes:</p> +<ul> + <li>ZGC and G1PeriodicGCInterval are not available with Java 11, so couldn’t be tested for</li> + <li>ZGenerational for ZGC is only available in Java 21, so couldn’t be tested for in Java 17</li> + <li>G1 GC is the default GC in Java 11, 17, and 21 (doesn’t need to be specified in java args)</li> +</ul> + +<p>All Experiments Performed:</p> + +<table> + <thead> + <tr> + <th>Java Version</th> + <th>Manual Compaction</th> + <th>Xmx=1G</th> + <th>Xmx=2G</th> + <th>Xms=256m</th> + <th>XX:G1PeriodicGCInterval=60000</th> + <th>XX:-G1PeriodicGCInvokesConcurrent</th> + <th>XX:+UseShenandoahGC</th> + <th>XX:+UseZGC</th> + <th>XX:ZUncommitDelay=120</th> + <th>XX:+ZGenerational</th> + </tr> + </thead> + <tbody> + <tr> + <td>11</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + </tbody> +</table> + +<h3 id="java-11-g1-gc-with-manual-gc-via-visualvm-every-minute-java-args--xmx1g--xms256m">Java 11 G1 GC with manual GC (via VisualVM) every minute. Java args: -Xmx1G -Xms256m</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-g1-gc-with-manual-gc-via-visualvm-after-each-compaction-java-args--xmx1g--xms256m">Java 11 G1 GC with manual GC (via VisualVM) after each compaction. Java args: -Xmx1G -Xms256m</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-g1-gc-java-args--xmx2g--xms256">Java 11 G1 GC. Java args: -Xmx2G -Xms256</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-shenandoah-gc-java-args--xmx2g--xms256--xxuseshenandoahgc">Java 11 Shenandoah GC. Java args: -Xmx2G -Xms256 -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx1g--xms256m--xxg1periodicgcinterval60000">Java 17 G1 GC. Java args: -Xmx1G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx2g--xms256m--xxg1periodicgcinterval60000">Java 17 G1 GC. Java args: -Xmx2G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx1g--xms256m--xxg1periodicgcinterval60000--xx-g1periodicgcinvokesconcurrent">Java 17 G1 GC. Java args: -Xmx1G -Xms256m -XX:G1PeriodicGCInterval=60000 -XX:-G1PeriodicGCInvokesConcurrent</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzuncommitdelay120">Java 17 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-shenandoah-gc-java-args--xmx1g--xms256m--xxuseshenandoahgc">Java 17 Shenandoah GC. Java args: -Xmx1G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-shenandoah-gc-java-args--xmx2g--xms256m--xxuseshenandoahgc">Java 17 Shenandoah GC. Java args: -Xmx2G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-g1-gc-java-args--xmx2g--xms256m--xxg1periodicgcinterval60000">Java 21 G1 GC. Java args: -Xmx2G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzgenerational--xxzuncommitdelay120">Java 21 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:+ZGenerational -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzuncommitdelay120">Java 21 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-shenandoah-gc-java-args--xmx1g--xms256m--xxuseshenandoahgc">Java 21 Shenandoah GC. Java args: -Xmx1G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-shenandoah-gc-java-args--xmx2g--xms256m--xxuseshenandoahgc">Java 21 Shenandoah GC. Java args: -Xmx2G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h2 id="conclusion">Conclusion</h2> +<p>All the garbage collectors tested (G1 GC, Shenandoah GC, and ZGC) and all the Java versions tested (11, 17, 21) will release memory that is no longer used by a compactor, back to the OS*. Regardless of which GC is used, after an external compaction is done, most (but usually not all) memory is eventually released back to the OS and all memory is released back to the JVM. Although a comparable amount of memory is returned to the OS in each case, the amount of time it takes for the memo [...] + +<p>The amount that is never released back to the OS appears to be minimal and may only be present with G1 GC and Shenandoah GC. In the following graph with Java 17 using G1 GC, we see that the baseline OS memory usage before any compactions are done is a bit less than 400MB. We see that after a compaction is done and the garbage collection runs, this baseline settles at about 500MB.</p> + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> +</a></p> + +<p>On the same test run, the JVM perspective (pictured in the graph below) shows that all memory is returned (memory usage drops back down to Xms=256m after garbage collection occurs).</p> + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> +</a></p> + +<p>The roughly 100MB of unreturned memory is also present with Shenandoah GC in Java 17 and Java 21 but does not appear to be present with Java 11. With ZGC, however, we see several runs where nearly all the memory used during a compaction is returned to the OS (the graph below was from a run using ZGC with Java 21). These findings regarding the unreturned memory may or may not be significant. They may also be the result of variance between runs. More testing would need to be done to con [...] + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> +</a></p> + +<p>Another interesting finding was that the processes use more memory when more is allocated. These results were obtained from initiating a compaction of 700MB of data (see experiment.jsh script). For example, setting 2GB versus 1GB of max heap for the compactor process results in a higher peak memory usage. During a compaction, when only allocated 1GB of heap space, the max heap space is not completely utilized. When allocated 2GB, compactions exceed 1GB of heap space used. It appears t [...] + +<p>Another difference found between the GCs tested was that Shenandoah GC sometimes required two garbage collections to occur after a compaction completed to clean up the memory. Based on our experiments, when a larger max heap size was allocated (2GB vs 1GB), the first garbage collection that occurred only cleaned up about half of the now unused memory, and another garbage collection had to occur for the rest to be cleaned up. This was not the case when 1GB of max heap space was allocat [...] + +<p>*Note: When using the default GC (G1 GC), garbage collection does not automatically occur unless further garbage collection settings are specified (e.g., G1PeriodicGCInterval)</p> + + +<p><strong>View all posts in the <a href="/news">news archive</a></strong></p> + + </div> + + +<footer> + + <p><a href="https://www.apache.org/foundation/contributing"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support the ASF" id="asf-logo" height="100" /></a></p> + + <p>Copyright © 2011-2024 <a href="https://www.apache.org">The Apache Software Foundation</a>. +Licensed under the <a href="https://www.apache.org/licenses/">Apache License, Version 2.0</a>.</p> + + <p>Apache®, the names of Apache projects and their logos, and the multicolor feather +logo are registered trademarks or trademarks of The Apache Software Foundation +in the United States and/or other countries.</p> + +</footer> + + + </div> + </div> + </div> +</body> +</html> diff --git a/output/feed.xml b/output/feed.xml index e3736ca2..bbc7ab9b 100644 --- a/output/feed.xml +++ b/output/feed.xml @@ -6,11 +6,632 @@ </description> <link>https://accumulo.apache.org/</link> <atom:link href="https://accumulo.apache.org/feed.xml" rel="self" type="application/rss+xml"/> - <pubDate>Wed, 28 Feb 2024 18:16:00 +0000</pubDate> - <lastBuildDate>Wed, 28 Feb 2024 18:16:00 +0000</lastBuildDate> + <pubDate>Mon, 22 Apr 2024 18:30:52 +0000</pubDate> + <lastBuildDate>Mon, 22 Apr 2024 18:30:52 +0000</lastBuildDate> <generator>Jekyll v4.3.2</generator> + <item> + <title>Does a compactor process return memory to the OS?</title> + <description><h2 id="goal">Goal</h2> +<p>The goal of the project was to determine if, once an Accumulo process is finished using memory, the JVM would release this unused memory back to the operating system. This was specifically observed in a Compactor process during the tests, but the findings should apply to any Accumulo Server process. We looked at the memory usage of the compactor process specifically to help understand if oversubscribing compactors on a machine is a viable option.</p> + +<p>As background information, it’s important to note that modern JVMs are expected to release memory back to the operating system, rather than just growing from the initial heap size (-Xms) to the maximum heap size (-Xmx) and never releasing it. This behavior was introduced in Java 11 through the <a href="https://openjdk.org/jeps/346">JEP 346: Promptly Return Unused Committed Memory from G1</a>. This feature aims to improve the efficiency of memory usage by ac [...] +<h3 id="test-scenario">Test Scenario</h3> +<p>There could be a scenario where the amount of memory on a machine limits the number of compactors that can be run. For example, on a machine with 32GB of memory, if each compactor process uses 6GB of memory, we can only “fit” 5 compactors on that machine (32/6=5.333). Since each compactor process only runs on a single core, we would only be utilizing 5 cores on that machine where we would like to be using as many as we can.</p> + +<p>If the compactor process does not return the memory to the OS, then we are stuck with only using the following number of compactor processes: +<code class="language-plaintext highlighter-rouge">(total memory)/(memory per compactor)</code>. +If the compactor processes return the memory to the OS, i.e. does not stay at the maximum 6GB once they reach it, then we can oversubscribe the memory allowing us to run more compactor processes on that machine.</p> + +<p>It should be noted that there is an inherent risk when oversubscribing processes that the user must be willing to accept if they choose to do oversubscribe. In this case, there is the possibility that all compactors run at the same time which might use all the memory on the machine. This could cause one or more of the compactor processes to be killed by the OOM killer.</p> + +<h2 id="test-setup">Test Setup</h2> + +<h3 id="environment-prerequisites">Environment Prerequisites</h3> + +<p>The machines used for testing were running Pop!_OS 22.04 a debian-based OS. The following package installation and usage steps may vary if one were try to repeat these steps.</p> + +<h4 id="install-gnuplot">Install gnuplot</h4> + +<p>This was used for plotting the memory usage of the compactor over time from the perspective of the OS</p> + +<ol> + <li><code class="language-plaintext highlighter-rouge">sudo apt install gnuplot</code></li> + <li>gnuplot was started with the command <code class="language-plaintext highlighter-rouge">gnuplot</code></li> +</ol> + +<h4 id="install-visualvm">Install VisualVM</h4> + +<p>This was used for plotting the memory usage of the compactor over time from the perspective of the JVM</p> + +<ol> + <li>Downloaded the zip from <a href="https://visualvm.github.io/">visualvm.github.io</a></li> + <li>Extracted with <code class="language-plaintext highlighter-rouge">unzip visualvm_218.zip</code></li> + <li>VisualVM was started with the command <code class="language-plaintext highlighter-rouge">./path/to/visualvm_218/bin/visualvm</code></li> +</ol> + +<h4 id="configure-and-start-accumulo">Configure and start accumulo</h4> + +<p>Accumulo 2.1 was used for experimentation. To stand up a single node instance, <a href="https://github.com/apache/fluo-uno">fluo-uno</a> was used.</p> + +<p>Steps taken to configure accumulo to start compactors:</p> + +<ol> + <li>Uncommented lines in <code class="language-plaintext highlighter-rouge">fluo-uno/install/accumulo-2.1.2/conf/cluster.yaml</code> regarding the compaction coordinator and compactor q1. A single compactor process was used, q1. This allows the external compaction processes to start up.</li> + <li>Configured the java args for the compactor process in “accumulo-env.sh.” Line: +<code class="language-plaintext highlighter-rouge">compactor) JAVA_OPTS=('-Xmx256m' '-Xms256m' "${JAVA_OPTS[@]}") ;;</code></li> + <li>Started accumulo with <code class="language-plaintext highlighter-rouge">uno start accumulo</code></li> +</ol> + +<h4 id="install-java-versions">Install java versions</h4> + +<ol> + <li>Installed java versions 11, 17 and 21. For example, Java 17 was installed with: + <ol> + <li><code class="language-plaintext highlighter-rouge">sudo apt install openjdk-17-jdk</code></li> + <li><code class="language-plaintext highlighter-rouge">sudo update-alternatives --config java</code> and select the intended version before starting the accumulo instance</li> + <li>Ensured <code class="language-plaintext highlighter-rouge">JAVA_HOME</code> was set to the intended version of java before each test run</li> + </ol> + </li> +</ol> + +<h2 id="running-the-test">Running the test</h2> + +<ol> + <li>Started accumulo using <a href="https://github.com/apache/fluo-uno">fluo-uno</a> (after changing the mentioned configuration) + <ul> + <li><code class="language-plaintext highlighter-rouge">uno start accumulo</code></li> + </ul> + </li> + <li>Opened VisualVM and selected the running compactor q1 process taking note of the PID</li> + <li>Ran <code class="language-plaintext highlighter-rouge">mem_usage_script.sh &lt;compactor process PID&gt;</code>. This collected measurements of memory used by the compactor process over time from the perspective of the OS. We let this continue to run while the compaction script was running.</li> + <li>Configured the external compaction script as needed and executed: + <ul> + <li><code class="language-plaintext highlighter-rouge">uno jshell experiment.jsh</code></li> + </ul> + </li> + <li>Memory usage was monitored from the perspective of the JVM (using VisualVM) and from the perspective of the OS (using our collection script). +Navigated to the “Monitor” tab of the compactor in VisualVM to see the graph of memory usage from JVM perspective. +Followed the info given in the <a href="#os-memory-data-collection-script">OS Memory Data Collection Script</a> section to plot the memory usage from OS perspective.</li> +</ol> + +<p>Helpful resources:</p> +<ul> + <li><a href="https://accumulo.apache.org/blog/2021/07/08/external-compactions.html">External Compactions accumulo blog post</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/z-garbage-collector.html#GUID-8637B158-4F35-4E2D-8E7B-9DAEF15BB3CD">Z garbage collector heap size docs</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/garbage-collector-implementation.html#GUID-71D796B3-CBAB-4D80-B5C3-2620E45F6E5D">Generational Garbage Collection docs</a></li> + <li><a href="https://docs.oracle.com/en/java/javase/21/gctuning/garbage-first-g1-garbage-collector1.html#GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573">G1 garbage collector docs</a></li> + <li><a href="https://thomas.preissler.me/blog/2021/05/02/release-memory-back-to-the-os-with-java-11">Java 11 and memory release article</a></li> +</ul> + +<h3 id="external-compaction-test-script">External compaction test script</h3> + +<p>Initiates an external compaction of 700MB of data (20 files of size 35MB) on Compactor q1.</p> + +<p><strong><em>referred to as experiment.jsh in the test setup section</em></strong></p> + +<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">org.apache.accumulo.core.conf.Property</span><span class="o">;</span> + +<span class="kt">int</span> <span class="n">dataSize</span> <span class="o">=</span> <span class="mi">35_000_000</span><span class="o">;</span> +<span class="kt">byte</span><span class="o">[]</span> <span class="n">data</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="n">dataSize</span><span class="o">];</span> +<span class="nc">Arrays</span><span class="o">.</span><span class="na">fill</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="o">(</span><span class="kt">byte</span><span class="o">)</span> <span class="mi">65</span><span cl [...] +<span class="nc">String</span> <span class="n">tableName</span> <span class="o">=</span> <span class="s">"testTable"</span><span class="o">;</span> + +<span class="kt">void</span> <span class="nf">ingestAndCompact</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> + <span class="k">try</span> <span class="o">{</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">delete</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span> + <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">TableNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> + <span class="c1">// ignore </span> + <span class="o">}</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Creating table "</span> <span class="o">+</span> <span class="n">tableName</span><span class="o& [...] + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">create</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span> + + <span class="c1">// This is done to avoid system compactions, we want to initiate the compactions manually </span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="nc">Property</span><span class="o&qu [...] + <span class="c1">// Configure for external compaction </span> + <span class="n">client</span><span class="o">.</span><span class="na">instanceOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="s">"tserver.compaction.major.service.cs1.planner"</span><span class="o">,</span><span class="s"&g [...] + <span class="n">client</span><span class="o">.</span><span class="na">instanceOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="s">"tserver.compaction.major.service.cs1.planner.opts.executors"</span><span class="o">,</span><span class= [...] + + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="s">"table.compaction.dispatcher"</spa [...] + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">setProperty</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="s">"table.compaction.dispatcher.opts.service& [...] + + <span class="kt">int</span> <span class="n">numFiles</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span> + + <span class="k">try</span> <span class="o">(</span><span class="kt">var</span> <span class="n">writer</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">createBatchWriter</span><span class="o">(</span><span class="n">tableNa [...] + <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">numFiles</span&g [...] + <span class="nc">Mutation</span> <span class="n">mut</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Mutation</span><span class="o">(</span><span class="s">"r"</span> <span class="o">+</span> <span class="n">i</span><span class="o"& [...] + <span class="n">mut</span><span class="o">.</span><span class="na">at</span><span class="o">().</span><span class="na">family</span><span class="o">(</span><span class="s">"cf"</span><span class="o">).</span><span class="na">qualifier</span><span class="o"> [...] + <span class="n">writer</span><span class="o">.</span><span class="na">addMutation</span><span class="o">(</span><span class="n">mut</span><span class="o">);</span> + <span class="n">writer</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Writing "</span> <span class="o">+</span> <span class="n">dataSize</span> <span class="o [...] + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">flush</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="kc">null</span><span class="o" [...] + <span class="o">}</span> + <span class="o">}</span> + + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Compacting table"</span><span class="o">);</span> + <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">compact</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="k">new</span> <span class="nc">C [...] + <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Finished table compaction"</span><span class="o">);</span> +<span class="o">}</span> + +<span class="n">ingestAndCompact</span><span class="o">();</span> +<span class="c1">// Optionally sleep and ingestAndCompact() again, or just execute the script again.</span> +</code></pre></div></div> + +<h3 id="os-memory-data-collection-script">OS Memory Data Collection Script</h3> + +<p>Tracks the Resident Set Size (RSS) of the given PID over time, outputting the data to output_mem_usage.log. +Data is taken every 5 seconds for an hour or until stopped.</p> + +<p><strong><em>referred to as mem_usage_script.sh in the test setup section</em></strong></p> + +<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash </span> +<span class="nv">PID</span><span class="o">=</span><span class="nv">$1</span> +<span class="nb">echo</span> <span class="s2">"Tracking PID: </span><span class="nv">$PID</span><span class="s2">"</span> +<span class="nv">DURATION</span><span class="o">=</span>3600 <span class="c"># for 1 hour </span> +<span class="nv">INTERVAL</span><span class="o">=</span>5 <span class="c"># every 5 seconds </span> +<span class="nb">rm </span>output_mem_usage.log + +<span class="k">while</span> <span class="o">[</span> <span class="nv">$DURATION</span> <span class="nt">-gt</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">do + </span>ps <span class="nt">-o</span> %mem,rss <span class="nt">-p</span> <span class="nv">$PID</span> | <span class="nb">tail</span> <span class="nt">-n</span> +2 <span class="o">&gt;&gt;</span> output_mem_usage.log + <span class="nb">sleep</span> <span class="nv">$INTERVAL</span> + <span class="nv">DURATION</span><span class="o">=</span><span class="k">$((</span>DURATION <span class="o">-</span> INTERVAL<span class="k">))</span> +<span class="k">done</span> +</code></pre></div></div> + +<p>After compactions have completed plot the data using gnuplot:</p> + +<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gnuplot +<span class="nb">set </span>title <span class="s2">"Resident Set Size (RSS) Memory usage"</span> +<span class="nb">set </span>xlabel <span class="s2">"Time"</span> +<span class="nb">set </span>ylabel <span class="s2">"Mem usage in kilobytes"</span> +plot <span class="s2">"output_mem_usage.log"</span> using <span class="o">(</span><span class="nv">$0</span><span class="k">*</span>5<span class="o">)</span>:2 with lines title <span class="s1">'Mem usage'</span> +</code></pre></div></div> + +<h2 id="data">Data</h2> + +<p>Important Notes:</p> +<ul> + <li>ZGC and G1PeriodicGCInterval are not available with Java 11, so couldn’t be tested for</li> + <li>ZGenerational for ZGC is only available in Java 21, so couldn’t be tested for in Java 17</li> + <li>G1 GC is the default GC in Java 11, 17, and 21 (doesn’t need to be specified in java args)</li> +</ul> + +<p>All Experiments Performed:</p> + +<table> + <thead> + <tr> + <th>Java Version</th> + <th>Manual Compaction</th> + <th>Xmx=1G</th> + <th>Xmx=2G</th> + <th>Xms=256m</th> + <th>XX:G1PeriodicGCInterval=60000</th> + <th>XX:-G1PeriodicGCInvokesConcurrent</th> + <th>XX:+UseShenandoahGC</th> + <th>XX:+UseZGC</th> + <th>XX:ZUncommitDelay=120</th> + <th>XX:+ZGenerational</th> + </tr> + </thead> + <tbody> + <tr> + <td>11</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>11</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>17</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td>🗸</td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td>21</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td>🗸</td> + <td> </td> + <td> </td> + <td>🗸</td> + <td> </td> + <td> </td> + <td> </td> + </tr> + </tbody> +</table> + +<h3 id="java-11-g1-gc-with-manual-gc-via-visualvm-every-minute-java-args--xmx1g--xms256m">Java 11 G1 GC with manual GC (via VisualVM) every minute. Java args: -Xmx1G -Xms256m</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-g1-gc-with-manual-gc-via-visualvm-after-each-compaction-java-args--xmx1g--xms256m">Java 11 G1 GC with manual GC (via VisualVM) after each compaction. Java args: -Xmx1G -Xms256m</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-g1-gc-java-args--xmx2g--xms256">Java 11 G1 GC. Java args: -Xmx2G -Xms256</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-11-shenandoah-gc-java-args--xmx2g--xms256--xxuseshenandoahgc">Java 11 Shenandoah GC. Java args: -Xmx2G -Xms256 -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx1g--xms256m--xxg1periodicgcinterval60000">Java 17 G1 GC. Java args: -Xmx1G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx2g--xms256m--xxg1periodicgcinterval60000">Java 17 G1 GC. Java args: -Xmx2G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-g1-gc-java-args--xmx1g--xms256m--xxg1periodicgcinterval60000--xx-g1periodicgcinvokesconcurrent">Java 17 G1 GC. Java args: -Xmx1G -Xms256m -XX:G1PeriodicGCInterval=60000 -XX:-G1PeriodicGCInvokesConcurrent</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzuncommitdelay120">Java 17 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-shenandoah-gc-java-args--xmx1g--xms256m--xxuseshenandoahgc">Java 17 Shenandoah GC. Java args: -Xmx1G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-17-shenandoah-gc-java-args--xmx2g--xms256m--xxuseshenandoahgc">Java 17 Shenandoah GC. Java args: -Xmx2G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-g1-gc-java-args--xmx2g--xms256m--xxg1periodicgcinterval60000">Java 21 G1 GC. Java args: -Xmx2G -Xms256m -XX:G1PeriodicGCInterval=60000</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzgenerational--xxzuncommitdelay120">Java 21 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:+ZGenerational -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-zgc-java-args--xmx2g--xms256m--xxusezgc--xxzuncommitdelay120">Java 21 ZGC. Java args: -Xmx2G -Xms256m -XX:+UseZGC -XX:ZUncommitDelay=120</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-shenandoah-gc-java-args--xmx1g--xms256m--xxuseshenandoahgc">Java 21 Shenandoah GC. Java args: -Xmx1G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h3 id="java-21-shenandoah-gc-java-args--xmx2g--xms256m--xxuseshenandoahgc">Java 21 Shenandoah GC. Java args: -Xmx2G -Xms256m -XX:+UseShenandoahGC</h3> +<!-- creates a styled box with two images side by side --> +<!-- accepts two URLs relative to the project root and two alt text strings --> +<div class="p-3 border rounded d-flex"> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> + </a> + <a href="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> + </a> +</div> + +<h2 id="conclusion">Conclusion</h2> +<p>All the garbage collectors tested (G1 GC, Shenandoah GC, and ZGC) and all the Java versions tested (11, 17, 21) will release memory that is no longer used by a compactor, back to the OS*. Regardless of which GC is used, after an external compaction is done, most (but usually not all) memory is eventually released back to the OS and all memory is released back to the JVM. Although a comparable amount of memory is returned to the OS in each case, the amount of time it takes for th [...] + +<p>The amount that is never released back to the OS appears to be minimal and may only be present with G1 GC and Shenandoah GC. In the following graph with Java 17 using G1 GC, we see that the baseline OS memory usage before any compactions are done is a bit less than 400MB. We see that after a compaction is done and the garbage collection runs, this baseline settles at about 500MB.</p> + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> +</a></p> + +<p>On the same test run, the JVM perspective (pictured in the graph below) shows that all memory is returned (memory usage drops back down to Xms=256m after garbage collection occurs).</p> + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png"> + <img src="/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png" class="img-fluid rounded" alt="Graph showing memory usage from the JVM perspective" /> +</a></p> + +<p>The roughly 100MB of unreturned memory is also present with Shenandoah GC in Java 17 and Java 21 but does not appear to be present with Java 11. With ZGC, however, we see several runs where nearly all the memory used during a compaction is returned to the OS (the graph below was from a run using ZGC with Java 21). These findings regarding the unreturned memory may or may not be significant. They may also be the result of variance between runs. More testing would need to be done [...] + +<p><a class="p-3 border rounded d-block" href="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png"> + <img src="/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png" class="img-fluid rounded" alt="Graph showing memory usage from the OS perspective" /> +</a></p> + +<p>Another interesting finding was that the processes use more memory when more is allocated. These results were obtained from initiating a compaction of 700MB of data (see experiment.jsh script). For example, setting 2GB versus 1GB of max heap for the compactor process results in a higher peak memory usage. During a compaction, when only allocated 1GB of heap space, the max heap space is not completely utilized. When allocated 2GB, compactions exceed 1GB of heap space used. It app [...] + +<p>Another difference found between the GCs tested was that Shenandoah GC sometimes required two garbage collections to occur after a compaction completed to clean up the memory. Based on our experiments, when a larger max heap size was allocated (2GB vs 1GB), the first garbage collection that occurred only cleaned up about half of the now unused memory, and another garbage collection had to occur for the rest to be cleaned up. This was not the case when 1GB of max heap space was a [...] + +<p>*Note: When using the default GC (G1 GC), garbage collection does not automatically occur unless further garbage collection settings are specified (e.g., G1PeriodicGCInterval)</p> +</description> + <pubDate>Tue, 09 Apr 2024 00:00:00 +0000</pubDate> + <link>https://accumulo.apache.org/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html</link> + <guid isPermaLink="true">https://accumulo.apache.org/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html</guid> + + + <category>blog</category> + + </item> + <item> <title>Apache Accumulo 1.10.4</title> <description><h2 id="about">About</h2> @@ -1601,160 +2222,6 @@ stress the feature in other ways though.</p> <guid isPermaLink="true">https://accumulo.apache.org/blog/2021/07/08/external-compactions.html</guid> - <category>blog</category> - - </item> - - <item> - <title>Jshell Accumulo Feature</title> - <description><h2 id="overview">Overview</h2> - -<p>First introduced in Java 9, <a href="https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm#JSHEL-GUID-630F27C8-1195-4989-9F6B-2C51D46F52C8">JShell</a> is an interactive Read-Evaluate-Print-Loop (REPL) -Java tool that interprets user’s input and outputs the results. This tool provides a convenient -way to test out and execute quick tasks with Accumulo in the terminal. This feature is a part -of the upcoming Accumulo 2.1 release. If you’re a developer and want to get involved in testing, -<a href="/contact-us/">contact us</a> or review our <a href="/how-to-contribute/">contributing guide</a>.</p> - -<h2 id="major-features">Major Features</h2> -<ul> - <li> - <p>Default JShell script provides initial imports for interacting with Accumulo’s API and -provided in Accumulo’s binary distribution tarball</p> - </li> - <li> - <p>On startup, JShell Accumulo will automatically import the <code class="language-plaintext highlighter-rouge">CLASSPATH</code>, load in a configured -environment from user’s <code class="language-plaintext highlighter-rouge">conf/accumulo-env.sh</code>, and invoke <code class="language-plaintext highlighter-rouge">conf/jshell-init.jsh</code> -to allow rapid Accumulo task executions</p> - </li> - <li> - <p>JShell Accumulo can startup using default/custom JShell script and users can append any JShell -command-line <a href="https://docs.oracle.com/javase/9/tools/jshell.htm#JSWOR-GUID-C337353B-074A-431C-993F-60C226163F00">options</a> to the startup command</p> - </li> -</ul> - -<h2 id="booting-up-jshell-accumulo">Booting Up JShell Accumulo</h2> -<p>1) Open up a terminal and navigate to Accumulo’s installation directory</p> - -<p>2) To startup JShell with <strong>default script</strong> use this command:</p> - -<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>bin/accumulo jshell -</code></pre></div></div> -<p>3) To startup JShell with <strong>custom script</strong> use this command:</p> - -<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>bin/accumulo jshell <span class="nt">--startup</span> file/path/to/custom_script.jsh -</code></pre></div></div> -<p><strong>Note:</strong> One can execute the <code class="language-plaintext highlighter-rouge">jshell</code> command to startup JShell. However, doing so will require -manually importing the <code class="language-plaintext highlighter-rouge">CLASSPATH</code> and the configured environment from <code class="language-plaintext highlighter-rouge">conf/accumulo-env.sh</code> -and manually specifying the startup file for <code class="language-plaintext highlighter-rouge">conf/jshell-init.jsh</code> before any Accumulo tasks -can be performed. Using one of the startup commands above will automate that process -for convenience.</p> - -<h2 id="jshell-accumulo-default-script">JShell Accumulo Default Script</h2> -<p>The auto-generated <code class="language-plaintext highlighter-rouge">jshell-init.jsh</code> is a customizable file located in Accumulo’s installation -<code class="language-plaintext highlighter-rouge">conf/</code> directory. Inside, <code class="language-plaintext highlighter-rouge">jshell-init.jsh</code> contains <a href="/api/">Accumulo Java APIs</a> -formatted as import statements and <a href="https://www.javadoc.io/doc/org.apache.accumulo/accumulo-core/latest/org/apache/accumulo/core/client/AccumuloClient.html">AccumuloClient</a> build implementation. On startup, -the script automatically loads in the APIs and attempts to construct a client. Should additional -APIs and/or code implementations be needed, simply append them to <code class="language-plaintext highlighter-rouge">jshell-init.jsh</code>. -Alternatively, you can create a separate JShell script and specify the custom script’s file path -on startup.</p> - -<p>To construct an <a href="https://www.javadoc.io/doc/org.apache.accumulo/accumulo-core/latest/org/apache/accumulo/core/client/AccumuloClient.html">AccumuloClient</a>, the provided <code class="language-plaintext highlighter-rouge">conf/jshell-init.jsh</code> script finds -and uses <code class="language-plaintext highlighter-rouge">accumulo-client.properties</code> in Accumulo’s class path, and assigns the result -to a variable called <strong>client</strong>.</p> - -<p>If <code class="language-plaintext highlighter-rouge">accumulo-client.properties</code> is found, a similar result will be produced below:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Preparing JShell for Apache Accumulo - -Building Accumulo client using 'jar:file:/home/accumulo/lib/accumulo-client.jar!/accumulo-client.properties' - -Use 'client' to interact with Accumulo - -| Welcome to JShell -- Version 11.0.10 -| For an introduction type: /help intro - -jshell&gt; -</code></pre></div></div> - -<p>If <code class="language-plaintext highlighter-rouge">accumulo-client.properties</code> is not found, an <a href="https://www.javadoc.io/doc/org.apache.accumulo/accumulo-core/latest/org/apache/accumulo/core/client/AccumuloClient.html">AccumuloClient</a> will not -auto-generate and will produce the following result below:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Preparing JShell for Apache Accumulo - -'accumulo-client.properties' was not found on the classpath - -| Welcome to JShell -- Version 11.0.10 -| For an introduction type: /help intro - -jshell&gt; -</code></pre></div></div> - -<h2 id="jshell-accumulo-example">JShell Accumulo Example</h2> -<p>1) Booting up JShell Accumulo using default script</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Preparing JShell for Apache Accumulo - -Building Accumulo client using 'file:/home/accumulo/conf/accumulo-client.properties' - -Use 'client' to interact with Accumulo - -| Welcome to JShell -- Version 11.0.10 -| For an introduction type: /help intro - -jshell&gt; -</code></pre></div></div> - -<p>2) Providing JShell with an Accumulo task</p> - -<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">// Create a table called "GothamPD".</span> - <span class="n">client</span><span class="o">.</span><span class="na">tableOperations</span><span class="o">().</span><span class="na">create</span><span class="o">(</span><span class="s">"GothamPD"</span><span class="o">);</span> - - <span class="c1">// Create a Mutation object to hold all changes to a row in a table.</span> - <span class="c1">// Each row has a unique row ID.</span> - <span class="nc">Mutation</span> <span class="n">mutation</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Mutation</span><span class="o">(</span><span class="s">"id0001"</span><span class="o">);</span> - - <span class="c1">// Create key/value pairs for Batman. Put them in the "hero" family.</span> - <span class="n">mutation</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"hero"</span><span class="o">,</span> <span class="s">"alias"</span><span class="o">,</span> <span class="s">"Batman"</span><span class=& [...] - <span class="n">mutation</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"hero"</span><span class="o">,</span> <span class="s">"name"</span><span class="o">,</span> <span class="s">"Bruce Wayne"</span><span cla [...] - <span class="n">mutation</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"hero"</span><span class="o">,</span> <span class="s">"wearsCape?"</span><span class="o">,</span> <span class="s">"true"</span><span clas [...] - - <span class="c1">// Create a BatchWriter to the GothamPD table and add your mutation to it.</span> - <span class="c1">// Try w/ resources will close for us.</span> - <span class="k">try</span> <span class="o">(</span><span class="nc">BatchWriter</span> <span class="n">writer</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">createBatchWriter</span><span class="o">(</span><span class="s"> [...] - <span class="n">writer</span><span class="o">.</span><span class="na">addMutation</span><span class="o">(</span><span class="n">mutation</span><span class="o">);</span> - <span class="o">}</span> - - <span class="c1">// Read and print all rows of the "GothamPD" table.</span> - <span class="c1">// Try w/ resources will close for us.</span> - <span class="k">try</span> <span class="o">(</span><span class="nc">ScannerBase</span> <span class="n">scan</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">createScanner</span><span class="o">(</span><span class="s">" [...] - <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Gotham Police Department Persons of Interest:"</span><span class="o">);</span> - - <span class="c1">// A Scanner is an extension of java.lang.Iterable so behaves just like one.</span> - <span class="n">scan</span><span class="o">.</span><span class="na">forEach</span><span class="o">((</span><span class="n">k</span><span class="o">,</span> <span class="n">v</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="nc">System</span> [...] - <span class="o">}</span> -</code></pre></div></div> - -<p><strong>Note:</strong> The fully-qualified class name for Accumulo Scanner or -<code class="language-plaintext highlighter-rouge">org.apache.accumulo.core.client.Scanner</code> needs to be used due to conflicting issues with -Java’s built-in java.util.Scanner. However, to shorten the Accumulo Scanner’s declaration, assign -scan to <code class="language-plaintext highlighter-rouge">ScannerBase</code> type instead.</p> - -<p>3) Executing the Accumulo task above outputs:</p> - -<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mutation ==&gt; org.apache.accumulo.core.data.Mutation@1 -Gotham Police Department Persons of Interest: -Key : id0001 hero:alias [] 1618926204602 false Value : Batman -Key : id0001 hero:name [] 1618926204602 false Value : Bruce Wayne -Key : id0001 hero:wearsCape? [] 1618926204602 false Value : true - -jshell&gt; -</code></pre></div></div> -</description> - <pubDate>Wed, 21 Apr 2021 00:00:00 +0000</pubDate> - <link>https://accumulo.apache.org/blog/2021/04/21/jshell-accumulo-feature.html</link> - <guid isPermaLink="true">https://accumulo.apache.org/blog/2021/04/21/jshell-accumulo-feature.html</guid> - - <category>blog</category> </item> diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png new file mode 100644 index 00000000..3062aacf Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualaftercomp.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png new file mode 100644 index 00000000..25b91437 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_OS_manualeverymin.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png new file mode 100644 index 00000000..2d8efea4 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualaftercomp.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png new file mode 100644 index 00000000..deee77d7 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x1_s256_VM_manualeverymin.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png b/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png new file mode 100644 index 00000000..11bbbf4f Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png b/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png new file mode 100644 index 00000000..39731f45 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_G1_x2_s256_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png b/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png new file mode 100644 index 00000000..8cf486f4 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png b/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png new file mode 100644 index 00000000..27b7ca99 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_11_UseShenandoah_x2_s256_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png new file mode 100644 index 00000000..44222a4d Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png new file mode 100644 index 00000000..126d1eae Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png new file mode 100644 index 00000000..54521205 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png new file mode 100644 index 00000000..9f3960be Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x1_s256_periodic60000_concurrent_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png new file mode 100644 index 00000000..b38f6daa Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png new file mode 100644 index 00000000..7fb3f1bb Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_OS.png b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_OS.png new file mode 100644 index 00000000..b20b9b3f Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_VM.png b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_VM.png new file mode 100644 index 00000000..2675b7a3 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_G1_x2_s256_periodic60000_concurrent_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png b/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png new file mode 100644 index 00000000..6f3070bf Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png b/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png new file mode 100644 index 00000000..324e201f Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_ZGC_x2_s256_UseZGC_uncommit_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png new file mode 100644 index 00000000..8f645353 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png new file mode 100644 index 00000000..be6c6222 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x1_s256_UseShenandoah_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png new file mode 100644 index 00000000..a082366c Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png new file mode 100644 index 00000000..9f8a7d34 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_17_shenandoah_x2_s256_UseShenandoah_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png b/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png new file mode 100644 index 00000000..82ba3d7f Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png b/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png new file mode 100644 index 00000000..ea566583 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_G1_x2_s256_periodic60000_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png new file mode 100644 index 00000000..24e62df7 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png new file mode 100644 index 00000000..d74f5ca7 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_generational_uncommit_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png new file mode 100644 index 00000000..e9245da8 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png new file mode 100644 index 00000000..62ca6f33 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_ZGC_x2_s256_UseZGC_uncommit_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png new file mode 100644 index 00000000..5428715a Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png new file mode 100644 index 00000000..5b7d73d0 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x1_s256_UseShenandoah_VM.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png new file mode 100644 index 00000000..f27967a6 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_OS.png differ diff --git a/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png new file mode 100644 index 00000000..20f50565 Binary files /dev/null and b/output/images/blog/202404_compactor_memory/java_21_shenandoah_x2_s256_UseShenandoah_VM.png differ diff --git a/output/index.html b/output/index.html index 7279750b..2c5f7249 100644 --- a/output/index.html +++ b/output/index.html @@ -178,6 +178,13 @@ <p style="font-size: 24px; margin-bottom: 0px;">Latest News</p> + <div class="row latest-news-item"> + <div class="col-sm-12" style="margin-bottom: 5px"> + <span style="font-size: 12px; margin-right: 5px;">Apr 2024</span> + <a href="/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html">Does a compactor process return memory to the OS?</a> + </div> + </div> + <div class="row latest-news-item"> <div class="col-sm-12" style="margin-bottom: 5px"> <span style="font-size: 12px; margin-right: 5px;">Nov 2023</span> @@ -206,13 +213,6 @@ </div> </div> - <div class="row latest-news-item"> - <div class="col-sm-12" style="margin-bottom: 5px"> - <span style="font-size: 12px; margin-right: 5px;">Apr 2023</span> - <a href="/release/accumulo-1.10.3/">Apache Accumulo 1.10.3</a> - </div> - </div> - <div id="news-archive-link"> <p>View all posts in the <a href="/news">news archive</a></p> </div> diff --git a/output/news/index.html b/output/news/index.html index d76810cb..656aa332 100644 --- a/output/news/index.html +++ b/output/news/index.html @@ -144,10 +144,21 @@ <div> -<h3>2023</h3> +<h3>2024</h3> + <div class="row" style="margin-top: 15px"> + <div class="col-md-1">Apr 09</div> + <div class="col-md-10"><a href="/blog/2024/04/09/does-a-compactor-return-memory-to-OS.html">Does a compactor process return memory to the OS?</a></div> + </div> + + + + + <hr /> + <h3>2023</h3> + <div class="row" style="margin-top: 15px"> <div class="col-md-1">Nov 16</div> <div class="col-md-10"><a href="/release/accumulo-1.10.4/">Apache Accumulo 1.10.4</a></div> diff --git a/output/search_data.json b/output/search_data.json index 28e762ea..2ee6f556 100644 --- a/output/search_data.json +++ b/output/search_data.json @@ -330,6 +330,14 @@ }, + "blog-2024-04-09-does-a-compactor-return-memory-to-os-html": { + "title": "Does a compactor process return memory to the OS?", + "content": "GoalThe goal of the project was to determine if, once an Accumulo process is finished using memory, the JVM would release this unused memory back to the operating system. This was specifically observed in a Compactor process during the tests, but the findings should apply to any Accumulo Server process. We looked at the memory usage of the compactor process specifically to help understand if oversubscribing compactors on a machine is a viable option.As background inform [...] + "url": " /blog/2024/04/09/does-a-compactor-return-memory-to-OS.html", + "categories": "blog" + } + , + "release-accumulo-1-10-4": { "title": "Apache Accumulo 1.10.4", "content": "AboutApache Accumulo 1.10.4 is the final bug fix release of the 1.10 LTM releaseline. As of this release, the 1.10 release line is now considered end-of-life.This means that any fixes that are applied because of a bug found in thisversion will not be applied and released as a new 1.10 patch version, butinstead will be applied and released to the currently active release lines, ifthey apply to those versions.These release notes are highlights of the changes since 1.10.3. [...]