Eugene Goldberg
Eugene Goldberg

Reputation: 15534

What is the better option for a multi-level, in-process cache?

In my spring boot application, I need to implement an in-process multi-level cache Here is an example of the data, which needs to be cached:

customer name (key, string) --data entity name (key, string) --config-1 (value, JSONObject) --config-2 (value, JSONObject)

I'm planning on having a few hundreds customer entries, each having up to a hundred "config" JSONObjects

I'm currently looking at ehcache:

Cache cache = manager.getCache("sampleCache1");
Element element = new Element("key1", "value1");
cache.put(element);

In this context, I would use "Customer_Name" in place of "key1", and "My Customer" in place of "value1", but them I would need to build a hierarchy:

customer
 -data entity
   -config

I'm not sure how to do it with ehcache. I'm also not sure whether there are better choices for what I'm trying to do.

Has anyone implemented such a multi-level hierarchical cache with ehcache or any other library?

Upvotes: 1

Views: 3043

Answers (1)

cruftex
cruftex

Reputation: 5723

For notation I use a map-like cache: value = Cache.get(key) which is more common then the EHCache2 Element

Option 1: Construct a composite key object

 class CustomerConfigurationKey {
    String customerKey;
    String dataEntityKey;
    // equals() and hashCode()
 }

This is pretty standard key/value stores including plain maps. I did address this in cache2k Quick Start.

Option 2: Use multiple levels of caches

Put a cache inside a cache and access like: data.get(customerKey).get(dataEntityKey).

You can find examples of "Composite Key" vs. "Multi Level Caches" in cache2k benchmarks DateFormattingBenchmark

This only works nicely if you have a small set at the first level. In your case you would end up with a separate cache per customer, which is to costly. So, this is only for completeness, no real option in your scenario.

Option 3: Use a map for the second level

Construct a single cache with Cache<String, Map<String, JSONObject>.

If typically all the customer data is used in a short interval, it does not make sense to cache on a finer level, since all data of a customer will be typically in memory anyways. Another example: when a customer is not active any more, the cache would expire and all of the customer data could be removed from memory.

Updating single entries of the map will have concurrency issues that you need to properly address, e.g. by copying and putting only an immutable map in the cache or by using a ConcurrentHashMap.

Upvotes: 3

Related Questions