Articles
8
min of reading
May 20, 2021

How to use Apache Ignite - Cache - Part One

Charles Fonseca
I develop systems to make humanity's life easier.
More about the author
Back

Apache Ignite is a distributed computing platform developed by GridGain and later donated to theApache Foundation. This is a series of articles about the Ignite platform, aimed at considering high-performance and addressing some internal implementation issues.

Ignite is used in multiple contexts: cache, messaging, streaming, monitoring, events, distributed computing. All modules will be covered in this series. The process of how to start an Ignite node and cluster is documented here.

Memory architecture

Memory management is one of the hallmarks of Ignite; data is kept both in memory (RAM) and on disk.

If the instance is configured as cache-aside, that is, not interacting with any persistence layer (JDBC, Spring Data, Micronaut Data), it uses node disks as the source of truth in case of inconsistencies. Otherwise, a process known as change-data-capture (CDC) is responsible for any synchronisation of data in the cluster.

When allocated in the memory, a portion is destined as on-heap; i.e. it is kept in the memory destined for the Java Virtual Machine (JVM) instance of Ignite itself – which is a Java application –, which may be unnecessarily costly, since by running the garbage collector, it scans through the entire heap, which may steal some good CPU cycles from the application. The other form is off-heap, outside the memory allocated to Java, and managed exclusively by Ignite. This is represented below:

Arquitetura de memória Ignite

Cache

Features

  • Cacha data structures

The IgniteSet<T> extends Set<T> and IgniteQueue<T> extends BlockingQueue<T> interfaces allow for the creation of data structures completely distributed through nodes, with backup, and dedicated partitioning in a transparent way for users. Since these structures inherit all native language operations from the Java implementations, they are readily available.

  • Deployment for both synchronous and asynchronous operations.

All asynchronous operations implement the interface IgniteFuture<V>, whose implementation is similar to the CompletableFuture of Java, with the possibility of inserting the callback function, or stringing operations.

  • Advanced metrics

The cache API exposes its metrics, the number of cache misses, cache hits, put time, get time, data rebalancing time, and heap size. This makes the user experience very transparent, and also provides a macro view for the developer.

  • Optimised serialization/deserialization

IgniteCache<Integer, Organisation> cache = ignite.getOrCreateCache("cacheName");

Organisation org = new Organisation(

    "Microsoft", new Address("1096 Eddy Street, San Francisco, CA"), OrganisationType.PRIVATE));


cache.put(1, org);


// Get cache that will get values as binary objects.

IgniteCache<Integer, BinaryObject> binaryCache = cache.withKeepBinary();// Get recently created organisation as a binary object.

BinaryObject binary = binaryCache.get(1);// That is how magic happens

String name = binary.field("name");

The BinaryObject.field() implementation allows us to deserialize specific fields and optimise CPU use, since only the datum to be used will be processed.

Data structures distributed in cache

  • Queue

IgniteQueue<String> queue = Ignition.ignite().queue("queueName", 0, null);int TIMES = 10;for (int i = 0; i < RETRIES; i++) {

    String item = UUID.randomUUID() + "_" + i;

    queue.put(item);

    println("Queue item has been added: " + item);

}// IgniteQueue is fully compatible with Java library.

for (String item : queue)

    println("Queue item: " + item);// Take items from queue head.

for (int i = 0; i < TIMES; i++)

    println("Queue item has been read from queue head: " + queue.take());// Take items from queue head once again.

for (int i = 0; i < TIMES; i++)

    println("Queue item has been read from queue head: " + queue.poll());

  • Set

IgniteSet<String> set = Ignition.ignite().set("setName", null);for (int i = 0; i < 5; i++) {

    String item = UUID.randomUUID() + "_" + i;

    set.add(item);

}for (String item : set)

    println("Set item: " + item);println(set.contains("1"));println("Set size: " + set.size());println("Removed: " + set.remove("0"));

Recommendations


Thanks for reading!