In this guide, you will learn how to optimize the performance of your first Java application with Akamas.
For your very first optimization the target application will be Renaissance, a sample Java benchmark that comes already shipped with Akamas-in-a-box - no need to install anything! The optimization goal is to make Renaissance run faster (minimize the response time of the benchmark iterations). You will leverage Akamas to automatically identify the optimal JVM parameters (like the size of the heap and inner pools, type of garbage collector, etc.) that can speedup the application.
Enjoy your first optimization exercise on a simple benchmark application. Once you have completed your first optimizations, make sure to check out the other quick guides to feel the power of Akamas applied to real-world optimization scenarios.
Get ready for your first optimization!
In this scenario the goal is to make Renaissance run faster by optimizing the Java Virtual Machine (JVM) parameters.
The following picture represents the high-level architecture of how Akamas operates in this scenario.
In the following, you will first create a System with two components corresponding to the JVM and the Renaissance application (which only for your first studies is represented by a benchmark). Then you will create a Telemetry Instance from the CVS Telemetry Provider so as to collect metrics generated in CSV format by Renaissance. Finally, you will create a Workflow to automate the whole process of applying a benchmark configuration, launching the benchmark, collecting the resulting metrics. This will allow you to create your optimization Study to identify the optimal configuration.
In Akamas a System is the single object that represents the system under optimization. A System is a single resource, irrespective of the number or type of entities and layers this IT system is structured on. A System is made of one or more Components. Each Component represents one of the system's components whose parameters are involved in the optimization or whose metrics are collected to evaluate the results of such optimization.
First of all, let's create a System. In the provided repository you can find a file called
system.yaml with the following content:
name: renaissance description: The renaissance benchmark application
Create the corresponding system as follows:
akamas create system system.yaml
You can directly see in the UI under the Systems menu:
You can always list all systems and verify that a system has been correctly created:
akamas list systems
At this point, you need to add to create the two components corresponding to the JVM and the Renaissance application. For both these components you can take advantage of the corresponding pre-defined Optimization Packs. An Optimization Pack provides for each specific technology the recommended Parameters, Metrics, and Telemetry Providers.
Since Renaissance is a Java-based application, we can take advantage of the corresponding Akamas Optimization Pack.
In order to install the Akamas Optimization Pack for Java OpenJDK 11, you can either run the following command
akamas install optimization-pack Java-OpenJDK
or simply operate from the UI, by installing it from the UI section listing all Optimization Packs available in your installation:
which should result in this Optimization Pack being installed (and thus possibly ready to be de-installed)
Notice: you only need to install an Optimization Pack once. So if an Optimization Pack has already been installed there is no need to follow these instructions once again. You can verify which Optimization Packs are already installed directly from the UI or by executing the following command:
akamas list optimization-packs
Now that the Optimization Pack has been installed, you can create the JVM component for this system.
comp_jvm.yaml contains the following definition for our system:
name: jvm description: The JVM running the application componentType: java-openjdk-11
Create the corresponding component for the
akamas create component comp_jvm.yaml renaissance
You can now see the JVM component in the UI:
You can always list all components in a system and verify that they have been correctly created:
akamas list components renaissance
At this point, you can install the Optimization Pack for Renaissance. This Optimization Pack is needed because you need to tell Akamas which metric you are going to optimize. Our goal for this study is to minimize the benchmark response time, and to do so you need to create a component with the response time metric. For each benchmark execution, we will also track the CPU and memory usage of the Java process, so in the Optimization Pack we have included those metrics as well.
Let's now install the Optimization Pack. This time, you will use a JSON file already provided in the Akamas-in-a-box installation:
akamas install optimization-pack renaissance.json
Create the component by specifying the YAML file and the name of the system
akamas create component comp_renaissance.yaml renaissance
You can now see the renaissance component and the associated response time, CPU and memory usage metrics:
Now we need to move to the next step and define where to collect metrics for this system.
In this section you will configure how Akamas collects metrics related to the
renaissance system. Metrics are required both to define your optimization goal (e.g.: minimize the
renaissance.response_time metric) and analyze the optimization results.
A Telemetry Provider specifies how to collect these metrics from a source, such as a monitoring platform (e.g. Prometheus or Dynatrace), a test tool (eg. Neoload or Loadrunner) or a simple CSV file. Akamas ships several out-of-the-box Telemetry Providers.
For each specific source, an instance of the corresponding Telemetry Provider needs to be defined at the system level.
The output of Renaissance benchmark suite is a CSV report file once the benchmark completes, which includes the benchmark execution time, CPU, and memory usage. Therefore, you will now create a CSV telemetry instance.
tel_csv.yaml provides the following definition:
provider: CSV File config: protocol: scp address: benchmark username: akamas authType: password auth: akamas remoteFilePattern: renaissance-parsed.csv componentColumn: component timestampColumn: TS timestampFormat: yyyy-MM-dd HH:mm:ss zzz metrics: - metric: response_time datasourceMetric: duration_ns - metric: cpu_used datasourceMetric: cpu_used - metric: mem_used datasourceMetric: mem_used
Create the telemetry instance as follows:
akamas create telemetry-instance tel_csv.yaml renaissance
You can verify your new telemetry instance under the corresponding tab within the UI:
You can always list all telemetry instances in a system and verify that they have been correctly created:
akamas list telemetry-instances renaissance
So far you have defined how the application to be optimized looks like in terms of Akamas system and components, and the telemetry required to gather the relevant metrics. Your next step is to create a workflow, that is defining how to run optimization experiments.
How does Akamas understand when given JVM configuration is improving performance or making it worse? This is done by running optimization experiments. Thus you now need to tell Akamas how to conduct these experiments. You can do this by creating a workflow.
A workflow is a sequence of tasks that Akamas executes for every experiment, such as:
In the next guides you will learn how to define a workflow from the UI or to specify the YAML file to get it created from the CLI. But since the purpose of this guide is to focus on getting your started, for this time you will simply use the
workflow.yaml file provided in the repository, defined as the following:
name: renaissance-optimize tasks: - name: Configure Benchmark operator: FileConfigurator arguments: source: hostname: benchmark username: akamas password: akamas path: launch_benchmark.sh.templ target: hostname: benchmark username: akamas password: akamas path: launch_benchmark.sh - name: Launch Benchmark operator: Executor arguments: command: "bash launch_benchmark.sh" host: hostname: benchmark username: akamas password: akamas - name: Parse Output operator: Executor arguments: command: "bash parse_output.sh" host: hostname: benchmark username: akamas password: akamas
Create the workflow by running the following command:
akamas create workflow workflow.yaml
You can verify your new workflow has been created by accessing the corresponding Workflow menu in the UI:
You can always list all workflows and verify that they have been correctly created:
akamas list workflows
At this point, you are ready to create your optimization study.
It's now time to set up and run our first optimization! In Akamas, an optimization is called a Study.
In this scenario, you will be creating a Study with the following properties:
In the other guides you will learn how to define a study from the UI or to specify the YAML file to get it created from the CLI. Since the purpose of this guide is to focus on getting your started, for this time you will simply use the
study-max-performance.yaml file provided in the repository, defined as the following:
name: Optimize Java application performance system: renaissance goal: objective: minimize function: formula: renaissance.response_time workflow: renaissance-optimize parametersSelection: - name: jvm.jvm_gcType - name: jvm.jvm_maxHeapSize domain: [32, 1024] - name: jvm.jvm_newSize domain: [16, 1024] - name: jvm.jvm_survivorRatio - name: jvm.jvm_maxTenuringThreshold - name: jvm.jvm_maxHeapFreeRatio domain: [41, 100] metricsSelection: - renaissance.response_time - renaissance.cpu_used - renaissance.mem_used parameterConstraints: - name: "Max heap must always be greater than new size" formula: jvm.jvm_maxHeapSize > jvm.jvm_newSize steps: - name: baseline type: baseline values: jvm.jvm_maxHeapSize: 1024 - name: optimize type: optimize numberOfExperiments: 30
Create the study:
akamas create study study-max-performance.yaml
You can also check from the UI that you have this Study in the corresponding UI section.
Congratulations, your first Akamas study is ready to be started!
You can now start your first study with the command:
akamas start study 'Optimize Java application performance'
or by accessing the Study menu in the UI, clicking on the study, and then pressing the Start button:
Congratulations, your first Akamas study is now running!
You can follow the progress of the study from the UI by selecting the Progress tab:
The Progress tab also allows following the workflow tasks execution, including logs for troubleshooting:
You can also execute the following command from time to time:
akamas list experiments 'Optimize Java application performance'
Notice that you can always stop (and restart) a study before all experiments are completed. This can be done by using the Stop button in the UI.
or by executing the following command:
akamas finish study 'Optimize Java application performance'
You can now analyze the partial results of the optimization study as its experiments progress.
You can now look at the results of your first AI-driven performance optimization study.
Select your study from the UI Study menu.
The Summary tab displays high-level study information at a glance, including the best score obtained so far, a summary of the optimized parameters, and their values for the best configuration.
By optimally configuring the JVM parameters, Akamas was able to cut the application response time by almost 50%:
The Analysis tab shows the experiments' score over time.
Properly tuning a modern JVM is a complex challenge, and might require weeks of time and effort even for performance experts.
Akamas AI is designed to converge rapidly toward optimal configurations. In this case, Akamas was able to find the optimal JVM configuration after only 30 automated performance experiments:
Below the optimization chart, you can also find a table showing aggregated performance metrics and parameters set for each experiment. For each metric, you can find a percentage variation with respect to the baseline experiment, so that you can quickly see the impact the new parameters had on other interesting key metrics (you can sort them too).
The Configuration Analysis tab lets you explore the additional insights and benefits of the configurations Akamas explored with respect to other key metrics besides the goal.
In this optimization, the five best configurations Akamas found not only made the application run significantly faster, but they also made the application run more efficiently on the CPU:
From a CPU efficiency perspective, the best configuration Akamas found was able to cut CPU utilization by 28%, while still improving response time by 20%.
What are the best JVM settings Akamas found that made the application run so much faster?
You can find them in the Best Configuration table in Summary tab.
Without being told anything about how the application works, Akamas learned the best settings for some interesting JVM parameters:
Those are not easy insights to discover, without being an expert and doing dozens of manual performance experiments!
The Metrics tab allows you to check the metrics that the telemetry modules collected over time for each experiment. In the chart, Akamas present you a comparison of the key metrics related to the baseline and the best experiment (you can add more using the filters).
Despite this first optimization relies on short benchmark execution times, the best configuration is consistently faster than the baseline.
Congratulations! You have just completed your first Akamas optimization of a sample Java application!
This was just the starting point, it is now time for you to move to other (more exciting) scenarios.
Here are a couple of next steps for you:
© Akamas Spa 2018-present. Akamas and the Akamas logo are registered trademarks of Akamas Spa.