Apache Ignite Documentation

GridGain Developer Hub - Apache Ignitetm

Welcome to the Apache Ignite developer hub run by GridGain. Here you'll find comprehensive guides and documentation to help you start working with Apache Ignite as quickly as possible, as well as support if you get stuck.

 

GridGain also provides Community Edition which is a distribution of Apache Ignite made available by GridGain. It is the fastest and easiest way to get started with Apache Ignite. The Community Edition is generally more stable than the Apache Ignite release available from the Apache Ignite website and may contain extra bug fixes and features that have not made it yet into the release on the Apache website.

 

Let's jump right in!

 

Documentation     Ask a Question     Download

 

Javadoc     Scaladoc     Examples

JCache and Beyond

Overview

Apache Ignite data grid is an implementation of JCache (JSR 107) specification. JCache provides a very simple to use, but yet very powerful API for data access. However, the specification purposely omits any details about data distribution and consistency to allow vendors enough freedom in their own implementations.

With JCache support you get the following:

  • Basic Cache Operations
  • ConcurrentMap APIs
  • Collocated Processing (EntryProcessor)
  • Events and Metrics
  • Pluggable Persistence

In addition to JCache, Ignite provides ACID transactions, data querying capabilities (including SQL), various memory models, queries, transactions, etc...

IgniteCache

IgniteCache interface is a gateway into Ignite cache implementation and provides methods for storing and retrieving data, executing queries, including SQL, iterating and scanning, etc.

IgniteCache is based on JCache (JSR 107), so at the very basic level the APIs can be reduced to javax.cache.Cache interface. However, IgniteCache API also provides functionality that facilitates features outside of JCache spec, like data loading, querying, asynchronous mode, etc.

You can get an instance of IgniteCache directly from Ignite:

Ignite ignite = Ignition.ignite();

// Obtain instance of cache named "myCache".
// Note that different caches may have different generics.
IgniteCache<Integer, String> cache = ignite.cache("myCache");

Dynamic Cache

You can also create an instance of the cache on the fly, in which case Ignite will create and deploy the cache across all server cluster members that match cache node filter. After a dynamic cache has been started, it will also be automatically deployed on all the newly joined server cluster members that match the cache node filter.

Ignite ignite = Ignition.ignite();

CacheConfiguration cfg = new CacheConfiguration();

cfg.setName("myCache");
cfg.setAtomicityMode(TRANSACTIONAL);

// Create cache with given name, if it does not exist.
IgniteCache<Integer, String> cache = ignite.getOrCreateCache(cfg);

XML Configuration

All caches defined in Ignite Spring XML configuration on any cluster member will also be automatically created and deployed on all the cluster servers (no need to specify the same configuration on each cluster member).

Basic Operations

Here are some basic JCache atomic operation examples.

try (Ignite ignite = Ignition.start("examples/config/example-cache.xml")) {
    IgniteCache<Integer, String> cache = ignite.cache(CACHE_NAME);
 
    // Store keys in cache (values will end up on different cache nodes).
    for (int i = 0; i < 10; i++)
        cache.put(i, Integer.toString(i));
 
    for (int i = 0; i < 10; i++)
        System.out.println("Got [key=" + i + ", val=" + cache.get(i) + ']');
}
// Put-if-absent which returns previous value.
Integer oldVal = cache.getAndPutIfAbsent("Hello", 11);
  
// Put-if-absent which returns boolean success flag.
boolean success = cache.putIfAbsent("World", 22);
  
// Replace-if-exists operation (opposite of getAndPutIfAbsent), returns previous value.
oldVal = cache.getAndReplace("Hello", 11);
 
// Replace-if-exists operation (opposite of putIfAbsent), returns boolean success flag.
success = cache.replace("World", 22);
  
// Replace-if-matches operation.
success = cache.replace("World", 2, 22);
  
// Remove-if-matches operation.
success = cache.remove("Hello", 1);

Deadlock

If batch operations (such as IgniteCache#putAll, IgniteCache#invokeAll, etc.) are performed in parallel, then keys should be ordered in the same way to avoid deadlock. It's recommended to use TreeMap instead of HashMap to guarantee consistent ordering. Note that this is true for both ATOMIC and TRANSACTIONAL caches.

EntryProcessor

Whenever doing puts and updates in cache, you are usually sending full object state across the network. EntryProcessor allows for processing data directly on primary nodes, often transferring only the deltas instead of the full state.

Moreover, you can embed your own logic into EntryProcessors, for example, taking previous cached value and incrementing it by 1.

IgniteCache<String, Integer> cache = ignite.cache("mycache");

// Increment cache value 10 times.
for (int i = 0; i < 10; i++)
  cache.invoke("mykey", (entry, args) -> {
    Integer val = entry.getValue();

    entry.setValue(val == null ? 1 : val + 1);

    return null;
  });
IgniteCache<String, Integer> cache = ignite.jcache("mycache");

// Increment cache value 10 times.
for (int i = 0; i < 10; i++)
  cache.invoke("mykey", new EntryProcessor<String, Integer, Void>() {
    @Override 
    public Object process(MutableEntry<Integer, String> entry, Object... args) {
      Integer val = entry.getValue();

      entry.setValue(val == null ? 1 : val + 1);

      return null;
    }
  });

Atomicity

EntryProcessors are executed atomically within a lock on the given cache key.

Asynchronous Support

Just like all distributed APIs in Ignite, IgniteCache extends IgniteAsynchronousSupport interface and can be used in asynchronous mode.

// Enable asynchronous mode.
IgniteCache<String, Integer> asyncCache = ignite.cache("mycache").withAsync();

// Asynhronously store value in cache.
asyncCache.getAndPut("1", 1);

// Get future for the above invocation.
IgniteFuture<Integer> fut = asyncCache.future();

// Asynchronously listen for the operation to complete.
fut.listenAsync(f -> System.out.println("Previous cache value: " + f.get()));

Using Ignite as JCache Provider

JCache API accepts a provider-specific configuration if a cache instance needs to be created using the JCache manager. This allows you to take advantage of the distributed caching capability that Ignite provides, without any modifications to your existing code if you're migrating from a different JCache implementation.

Here is an example of how to provide an Ignite cache configuration using JCache manager:

// Get or create a cache manager.
CacheManager cacheMgr = Caching.getCachingProvider().getCacheManager();

// This is an Ignite configuration object (org.apache.ignite.configuration.CacheConfiguration).
CacheConfiguration<Integer, String> cfg = new CacheConfiguration<>();

// Specify cache mode and/or any other Ignite-specific configuration properties.
cfg.setCacheMode(CacheMode.PARTITIONED);

// Create a cache based on the configuration created above.
Cache<Integer, String> cache = cacheMgr.createCache("aCache", cfg);

// Cache operations
Integer key = 1;
String value = "11";
cache.put(key, value");
System.out.println(cache.get(key));

Additionally, the CachingProvider.getCacheManager(..) method accepts a provider-specific URI which in case of Ignite should point to the XML configuration file. For example:

// Get or create a cache manager.
CacheManager cacheMgr = Caching.getCachingProvider().getCacheManager(
  Paths.get("path/to/ignite/xml/configuration/file").toUri(), null);

// Get a cache defined in the configuration file provided above.
Cache<Integer, String> cache = cacheMgr.getCache("myCache");

// Cache operations
Integer key = 1;
String value = "11";
cache.put(key, value");
System.out.println(cache.get(key));

It's worth mentioning that the above Cache<K, V> instance will only support features of javax.cache.Cache type.

To use extended features provided by Ignite, such as SQL, scan or continuous queries, you need to convert javax.cache.Cache instance to IgniteCache instance, like so:

// Get or create a cache manager.
CacheManager cacheMgr = Caching.getCachingProvider().getCacheManager(
  Paths.get("path/to/ignite/xml/configuration/file").toUri(), null);

// Get a cache defined in the configuration file provided above.
Cache<Integer, String> cache = cacheMgr.getCache("myCache");

// Obtain org.apache.ignite.IgniteCache instance.
IgniteCache igniteCache = (IgniteCache) cache;

// Ignite specific cache operations
//......