Search code examples
spring-bootcachinghazelcastspring-cache

What is the formal difference between a Cache and Map in version 5.0 of Hazelcast?


While implementing Hazelcast for the first time in set of web APIs, the usage of Map and Cache is inconsistent.

For example, creating a cache using SpringCacheManager results in the creation of a map

var sCache = springCacheManager.getCache("testCache");
sCache.putIfAbsent("test", "test2");

However, creating a cache using the CachingProvider CacheManager results in the creation of an actual cache that must be opened and closed (as per the documentation)

try (var cache = Caching.getCachingProvider().getCacheManager(null, null,
            HazelcastCachingProvider.propertiesByInstanceName("hazelcache")).createCache("actualCache", config)) {
        cache.putIfAbsent("test", "test");
    }

Another example, using the @Cacheable annotation will create a map, even though the documentation outlines the usage of a Cache. The following code will successfully return the first computed value using a Map in hazelcast. A cache is never used.

@Cacheable(value = "counter")
public Boolean test(Integer addTo) {
    counter += addTo;
    return counter % 2 != 0;
}

Is there a formal definition within Hazelcast of a cache vs a map? Are both usable for the same purpose?

The image below contains a view into a test Hazelcast Management Center that shows the above components, namely the maps and caches. These are all generated by the same client.

enter image description here

test


Solution

  • There are Cache, Spring Cache and Map to consider here.

    For Cache, Hazelcast is an implementation provider for the Java caching standard, JSR107. These show as "Cache" on the Management Center, and if you run hazelcastInstance.getDistributedObjects() they'll be of type ICache. It's in the Hazelcast documentation here.

    For Map, Hazelcast provides a data structure IMap which is mostly a superset of java.util.Map. These show as "Map" on the Management Center.

    Spring also provides caching, and you can set CacheType for JSR107 or directly with Hazelcast, or allow Spring to pick. When Spring uses Hazelcast directly, it will use IMap not ICache for storage.

    If you pick JCache or configure Spring to use JCache, then you get standards compliant behaviour. You have caching, and can easily swap caching provider from Hazelcast to something else should you want to.

    Map gives you operations such as executeOnKey to update one or more entries in situ. If the entry is a compound object but only a small part is changing, this can be a more efficient way to update it than sending the whole value.