MicroStream + Helidon =
Brave Performance Combination

Dmitry Aleksandrov
Helidon
Published in
3 min readNov 11, 2021

MicroStream provides high-performance, Java-native object graph persistence.

MicroStream replaces the heavyweight JPA and allows you to store - and partially load- any Java object graph or subgraph. It also provides microsecond response time and ultra-high throughput with minimal latencies. Now you can use MicroStream with Helidon 2.4 to create ultra fast, in-memory database applications and microservices.

MicroStream completely reworked Java’s serialization mechanisms, providing the ability to save partially loaded objects directly to disk, databases, or cloud object stores. Just choose the right Store Manager.

Helidon now has full integration with this technology.

MicroStream + Helidon MP

As mentioned above, MicroStream is now fully integrated with Helidon, which means that MicroStream components can read all their configuration directly from Helidon config.

There is a special set of annotations to inject to Storage Manager:

First, add the Maven dependency:

<dependency>
<groupId>io.helidon.integrations.microstream</groupId>
<artifactId>helidon-integrations-microstream-cdi</artifactId>
</dependency>

Then you can use the MicroStream support:

@Inject
public GreetingProvider(@MicrostreamStorage(configNode =
"one.microstream.storage.greetings")
EmbeddedStorageManager storage) {
super();
this.storage = storage;
greetingMessages = (List<String>) storage.root();
if (greetingMessages == null) {
greetingMessages = new ArrayList<>();
storage.setRoot(greetingMessages);
storage.storeRoot();
addGreeting("Hello");
}
}

The configuration will be read from the microprofile-config.properties file.

one.microstream.storage.greetings.storage-directory=./greetingsStorage

In Helidon’s official examples repository, you may find a slightly modified Greeting example. The main modification is adding a persistence to the set of “Greetings” you add. This means that if you add a new greeting, and restart the application, the set of them will not be lost.

You can try it for yourself with this example: https://github.com/oracle/helidon/tree/master/examples/integrations/microstream/greetings-mp

MicroStream + Helidon SE

The exact same functionality is provided in Helidon SE. You can use EmbeddedStorageManagerBuilderto initialize the MicroStream Storage Manager. All the configuration is taken from the Helidon Config:

GreetingService(Config config) {          
greeting.set(config.get("app.greeting").asString().orElse("Ciao"));
mctx = new GreetingServiceMicrostreamContext
(EmbeddedStorageManagerBuilder.create(config.get("microstream")));
mctx.start().await();
mctx.initRootElement();
}

As you see, all the operations with MicroStream are asynchronous and reactive.

public CompletableFuture<Void> addLogEntry(String name) {
return execute(() -> {
@SuppressWarnings("unchecked")
List<LogEntry> logs = (List<LogEntry>)
storageManager().root();
logs.add(new LogEntry(name, LocalDateTime.now()));
storageManager().store(logs);
return null;
});
}

Persisting an object is also simplified:

private void sendResponse(ServerResponse response, String name) {
String msg = String.format("%s %s!", greeting.get(), name);

mctx.addLogEntry(name);

JsonObject returnObject = JSON.createObjectBuilder()
.add("message", msg)
.build();
response.send(returnObject);
}

Try it! You can access the Helidon SE + MicroStream example in our official repository: https://github.com/oracle/helidon/tree/master/examples/integrations/microstream/greetings-se

Health Support and Metrics

Full integration includes also provide health checks and metrics support. Because Helidon is modular, you need to add a Maven dependency in order to read health checks:

<dependency>
<groupId>io.helidon.integrations.microstream</groupId>
<artifactId>helidon-integrations-microstream-health</artifactId>
</dependency>

and then for Helidon SE you should just register it:

HealthCheck microstreamHealthCheck = MicrostreamHealthCheck.create(greetService.getManager());
MetricsSupport metrics = MetricsSupport.create();
HealthSupport health = HealthSupport.builder()
.addLiveness(microstreamHealthCheck)
.addLiveness(HealthChecks.healthChecks())
.build();

The same method is used for metrics.

First, add the Maven dependency:

<dependency>
<groupId>io.helidon.integrations.microstream</groupId>
<artifactId>helidon-integrations-microstream-metrics</artifactId>
</dependency>

then, by using MicrostreamMetricsSupportobject, you can register a StorageManager:

MicrostreamMetricsSupport.builder(greetService.getManager()).build().registerMetrics();

Now all the health and metrics information is available under /health and /metrics endpoints of Helidon.

MicroStream Cache

MicroStream provides its own implementation of JSR107 — Caching Support.

It is available when you add this Maven dependency:

<dependency>
<groupId>io.helidon.integrations.microstream</groupId>
<artifactId>helidon-integrations-microstream-cdi</artifactId>
</dependency>

Then we can modify our Greetings application to use cache for our greeting:

Cache<String, String> greetingsCache;

@Inject
public GreetingsProvider(@MicrostreamCache(configNode=
"one.microstream.cache", name = "greetingsCache")
Cache<String, String> cache) {
super();
this.greetingsCache = cache;
}
public String get(String key) {
return greetingsCache.get(key);
}
public void add(String key, String responseObject) {
greetingsCache.put(key, responseObject);
}

There is a special @MicrostreamCache annotation that will read all the caching configuration from microprofile-config.properties:

#Microstream cache config
one.microstream.cache.storage.storage-directory = ./greetingsCache
one.microstream.cache.keyType = java.lang.String
one.microstream.cache.valueType = java.lang.String
one.microstream.cache.readThrough = true
one.microstream.cache.writeThrough = true

As you see, it‘s that easy!

Summary

MicroStream is a real game changer in the industry. If you want to create really performant microservices, to work in really high-pressure environments, then Helidon + MicroStream is a really great choice! Not only is it easy to set up and use, but now its fully integrated.

Kudos to MicroStream team!

More info: http://microstream.one

--

--