Recently, we described several criteria to look at to choose a cache. Now it’s time to list Java cache providers based on these criteria.
- Java Caching System
- Guava
- Caffeine
- Ehcache
- Infinispan
- Coherence Community Edition
- Ignite
- Geode
- Hazelcast
Java Caching System
JCS is a distributed caching system written in Java. It is intended to speed up applications by providing a means to manage cached data of various dynamic natures. Like any caching system, JCS is most useful for high read, low put applications. Latency times drop sharply and bottlenecks move away from the database in an effectively cached system.
-— https://commons.apache.org/proper/commons-jcs/index.html
Name | Java Caching System |
---|---|
Provider | The Apache Foundation |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2002 |
Last commit | c6b852c |
GitHub stars | 76 |
Configuration | File-based (cache.ccf ) |
jcs.default= jcs.default.cacheattributes=\ org.apache.commons.jcs3.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=1000 jcs.default.cacheattributes.MemoryCacheName=\ org.apache.commons.jcs3.engine.memory.lru.LRUMemoryCache |
|
Sample code |
var cache = JCS.<Long, String>getInstance("cache"); // 1 cache.put(1L, "One"); // 2 var value = cache.get(1L); // 3 System.out.println(value); JCS.shutdown(); // 4
|
Local/distributed | Local and distributed |
Non-blocking | ❌ |
JCache | ✅ |
Spring Cache | ❌ |
TTL | ✅ |
Eviction strategies | LRU |
Miscellaneous |
|
Guava
Guava is a set of core Java libraries from Google that includes new collection types (such as multimap and multiset), immutable collections, a graph library, and utilities for concurrency, I/O, hashing, caching, primitives, strings, and more! It is widely used on most Java projects within Google, and widely used by many other companies as well.
— https://github.com/google/guava
Name | Guava |
---|---|
Provider | |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2010 |
Last commit | ba690ba |
GitHub stars | 42.6k |
Configuration | Programmatic |
var cache = CacheBuilder.newBuilder() .maximumSize(1000) .build() |
|
Sample code |
cache.put(1L, "One"); // 1 var value = cache.getIfPresent(1L); // 2 System.out.println(value); cache.cleanUp(); // 3
|
Local/distributed | Local |
Non-blocking | ❌ |
JCache | ❌ |
Spring Cache | ❌ |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous | Guava is a single JAR that provides cache among many other capabilities |
A third-party project provides a JCache adapter | |
The get method accepts a Callable parameter that allows to get a value from the cache or compute it and store it if it’s not found |
|
The API uses soft and weak references in keys and values | |
Allows you to attach event handlers when entries are evicted |
Caffeine
Caffeine is a high performance, near optimal caching library. For more details, see our user’s guide and browse the API docs for the latest release.
— https://github.com/ben-manes/caffeine
Name | Caffeine |
---|---|
Provider | Ben Manes |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2014 |
Last commit | 41abb08 |
GitHub stars | 10.6k |
Configuration | Programmatic |
var cache = Caffeine.newBuilder() .maximumSize(1000) .build() |
|
Sample code |
cache.put(1L, "One"); // 1 var value = cache.getIfPresent(1L); // 2 System.out.println(value); cache.cleanUp(); // 3
|
Local/distributed | Local |
Non-blocking | ✅ |
var cache = Caffeine.newBuilder() .maximumSize(1000) .<Long, String>buildAsync(); // 1 CompletableFuture future = cache.get(1L, k -> expensiveLookup(1L));
|
|
JCache | ✅ |
Spring Cache | ✅ |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous | Caffeine is rewrite of Guava, inspired by its API, but with non-blocking principles at its core. |
|
Ehcache
Ehcache is an open source, standards-based cache that boosts performance, offloads your database, and simplifies scalability. It’s the most widely-used Java-based cache because it’s robust, proven, full-featured, and integrates with other popular libraries and frameworks. Ehcache scales from in-process caching, all the way to mixed in-process/out-of-process deployments with terabyte-sized caches.
-— https://www.ehcache.org/
Name | Ehcache |
---|---|
Provider | Software AG |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2009 |
Last commit | 212c63c |
GitHub stars | 1.7k |
Configuration | Programmatic |
var cacheManager = CacheManagerBuilder .newCacheManagerBuilder() .withCache( "cache", CacheConfigurationBuilder.newCacheConfigurationBuilder( Long.class, String.class, ResourcePoolsBuilder.heap(10) ) ).build(); cacheManager.init(); var cache = cacheManager.getCache( "cache", Long.class, String.class ); |
|
Sample code |
cache.put(key, value); // 1 var value = cache.get(key); // 2 cacheManager.close(); // 3
|
Local/distributed | Local |
Non-blocking | ❌ |
JCache | ✅ |
Spring Cache | ✅ |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous | Ehcache 3.x is a complete rewrite from Ehache 2.x |
Terracota is the Enterprise version of Ehcache. It provides distributed capabilities. |
Infinispan
Infinispan is an open-source in-memory data grid that offers flexible deployment options and robust capabilities for storing, managing, and processing data. Infinispan provides a key/value data store that can hold all types of data, from Java objects to plain text. Infinispan distributes your data across elastically scalable clusters to guarantee high availability and fault tolerance, whether you use Infinispan as a volatile cache or a persistent data store.
Name | Infinispan |
---|---|
Provider | RedHat |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2009 |
Last commit | 3dd18ce |
GitHub stars | 910 |
Configuration | Programmatic |
var cacheManager = new DefaultCacheManager(); cacheManager.defineConfiguration("cache", new ConfigurationBuilder().memory().maxSize("1000").build() ); var cache = cacheManager.<Long, String>getCache("cache"); |
|
Sample code | cache.put(1L, "One"); // 1 var value = cache.get(1L); // 2 System.out.println(value); cacheManager.close(); // 3
|
Local/distributed | Local and distributed |
Non-blocking | ✅ |
CompletableFuture<String> future = cache.getAsync(1L, k -> expensiveLookup(1L)); |
|
JCache | ✅ |
Spring Cache | ✅ |
TTL | ✅ |
Eviction strategies | LFU |
Miscellaneous | Infinispan is the successor of JBoss Cache |
|
Coherence Community Edition
Coherence is scalable, fault-tolerant, cloud-ready, distributed platform for building grid-based applications and reliably storing data. The product is used at scale, for both compute and raw storage, in a vast array of industries such as critical financial trading systems, high performance telecommunication products, and eCommerce applications.
—- https://coherence.community/latest/21.06/docs/
Name | Coherence |
---|---|
Provider | Oracle |
Source | GitHub |
License | Universal Permissive License |
Inception date | 2001 |
Last commit | 5f0b968 |
GitHub stars | 340 |
Configuration | File-based |
<?xml version="1.0"?> <cache-config> <caching-scheme-mapping> <cache-mapping> <cache-name>cache</cache-name> <scheme-name>local</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <local-scheme> <scheme-name>local</scheme-name> <high-units>1000</high-units> </local-scheme> </caching-schemes> </cache-config> |
|
Sample code |
var cache = CacheFactory.<Long, String>getCache("cache"); // 1 cache.put(1L, "One"); // 2 var value = cache.get(1L); // 3 System.out.println(value); cache.close(); // 4
|
Local/distributed | Local and distributed |
Non-blocking | ✅ |
var cache = CacheFactory .<Long, String>getCache("cache") .async(); CompletableFuture future = cache.get(1L); |
|
JCache | ✅ |
Spring Cache | ❌ |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous | Oracle bought Coherence from Tangsol in 2007 |
Commercial versions are available:
|
|
|
Ignite
Distributed Database For High-Performance Computing With In-Memory Speed
-- https://ignite.apache.org/
Name | Ignite |
---|---|
Provider | GridGain |
Source | GitHub |
License | Apache 2.0 |
Inception date | ? |
Open-Sourced | 2014 |
Last commit | 73a687d |
GitHub stars | 4k |
Configuration | Programmatic |
var cacheCfg = new CacheConfiguration<Long, String>(); cacheCfg.setOnheapCacheEnabled(true); cacheCfg.setEvictionPolicyFactory( () -> new LruEvictionPolicy<>(1000) ); cacheCfg.setName("cache"); var cfg = new IgniteConfiguration(); cfg.setCacheConfiguration(cacheCfg); ignite = Ignition.start(cfg); var cache = ignite.getOrCreateCache("cache"); |
|
Code sample |
cache.put(1L, "One"); // 1 var value = cache.get(1L); // 2 System.out.println(value); ignite.close(); // 3
|
Non-blocking | ✅ |
IgniteFuture<String> future = cache.getAsync(1L); // 1
|
|
JCache | ✅ |
Spring Cache | ✅ (provided by Ignite) |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous |
|
GridGrain offers an enterprise version of Ignite named GridGain In-Memory Computing Platform |
Geode
Apache Geode is a data management platform that provides real-time, consistent access to data-intensive applications throughout widely distributed cloud architectures.
Apache Geode pools memory, CPU, network resources, and optionally local disk across multiple processes to manage application objects and behavior. It uses dynamic replication and data partitioning techniques to implement high availability, improved performance, scalability, and fault tolerance. In addition to being a distributed data container, Apache Geode is an in-memory data management system that provides reliable asynchronous event notifications and guaranteed message delivery.
--https://github.com/apache/geode
Name | Geode |
---|---|
Provider | Pivotal |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2015 |
Open-Sourced | 2019 |
Last commit | a21df0b |
GitHub stars | 2k |
Configuration | File-based and programmatic |
var cache = new CacheFactory().create(); var factory = cache.<Long, String>createRegionFactory(); factory.setEvictionAttributes( EvictionAttributes.createLRUEntryAttributes(1000) ); var region = factory.create("cache"); |
|
Code sample |
region.put(1L, "One"); // 1 var value = region.get(1L); // 2 System.out.println(value); cache.close(); // 3
|
Non-blocking | ❌ |
JCache | ❌ |
Spring Cache | ✅ |
TTL | ✅ |
Eviction strategies | LRU |
Miscellaneous | GemStone is the company that initially developed Geode. In 2010, SpringSource acquired GemStone. |
|
Hazelcast
I work for Hazelcast at the time of this writing.
Hazelcast is a streaming and memory-first application platform for fast, stateful, data-intensive workloads on-premises, at the edge or as a fully managed cloud service.
—- https://hazelcast.com/
Name | Hazelcast |
---|---|
Provider | Hazelcast |
Source | GitHub |
License | Apache 2.0 |
Inception date | 2008 |
Last commit | de91d6b |
GitHub stars | 4.6k |
Configuration | File-based and programmatic |
var hazelcast = Hazelcast.newHazelcastInstance(); hazelcast.getConfig() .getMapConfig("cache") .getEvictionConfig() .setSize(1000); var map = hazelcast.getMap("cache"); |
|
Code sample |
map.put(1L, "One"); // 1 var value = map.get(1L); // 2 System.out.println(value); hazelcast.shutdown(); // 3
|
Non-blocking | ✅ |
CompletionStage<String> stage = cache.getAsync(1L); |
|
JCache | ✅ |
Spring Cache | ✅ |
TTL | ✅ |
Eviction strategies |
|
Miscellaneous | Hazelcast provides an Enterprise edition with additional features |
|
The following Maven project shows a simple key get-put for each cache.
I tried my best to provide accurate objective information. Please let me know in the comments if something is wrong.
To go further:
Orginally published at A Java Geek on October 31st, 2021
Hazelcast.
Disclaimer: I work for Hazelcast
Thanks for your great summarization of caching tools.
I need a caching mechanism to skip inserting repeated rows in multiple isolated ETL systems, if i had a cache capable of keeping 100s millions of rows(string of 50 chars) in it, it would give me great hit percent and so much less pressure on database.
It needs to be distributed(having multiple ETL machines), each ETL could update it async, and have a local instance of cache to query it as fast as possible.
What would you recommend?