Advice on caching for multi-tenant application

1,386 views
Skip to first unread message

Sean T

unread,
Mar 20, 2014, 4:16:37 PM3/20/14
to haze...@googlegroups.com
Hi,

We are looking into using HazelCast as the cache provider for our multi-tenant application which may host up to 1000 tenants.  We would like to run Hazelcast as a separate cache server and have the app servers connect to the cache server using Java native client.

For each type of cache/map, we are evaluating two possible approaches:

1. All tenants share the same cache/map and have tenant id as part of the key.  For operations like getting count or invalidating items for one tenant, a search by tenant id needs to be performed and  those searches could be expensive.  In addition, indexing on key attributes is not supported by Hazelcast yet in the current release (3.2RC2).

2. Each tenant uses its own cache.  This make operations like removing items for one tenant more performing.  But the overhead of maintaining large of numbers of caches/maps seems to be high. I did a simple test with 3.2RC2 by creating 1000 maps and put 1000 items of simple objects into each cache. The sever uses about 900M memory. Adopting approach 1 and  putting 1,000,000 items in a single cache, the server only uses about 350M.

Do you have any advices or recommendations on the best approaches for the cache configuration?

Thanks in advance.





shailes...@gmail.com

unread,
Oct 15, 2014, 3:31:59 AM10/15/14
to haze...@googlegroups.com
This is a similar challenge that we are also grappling with. We are tempted to go with option 2 (despite of it taking more resources), as it also allows easy purging of cache per tenant. 

Sean: Could you please share which approach did you with. 

-Shailesh

giri.ve...@gmail.com

unread,
Dec 29, 2015, 4:33:31 AM12/29/15
to Hazelcast
Guys,

Would love to hear any solution/approach you may have formulated. Appreciate your input.

Thx
Giri

Cleber Muramoto

unread,
Dec 30, 2015, 12:46:21 PM12/30/15
to Hazelcast, giri.ve...@gmail.com
You could attempt to mix both 1 and 2.

Instead of creating 1000 maps, create, say, 64 and apply a partitioning scheme based on (the hash of) tenant key, like 

IMap<Object,Object>[] caches = ...

public <T> void put(T tenant,Object key,Object value){
   IMap<Object,Object> cache = cacheFor(tenant);
   cache.put(tenantKey(tenant,key),value);
}

public <T> Serializable tenantKey(T tenant,Object key){
   //Any class representation suitable for searching by the tenant key. Usually, implement IdentifiedDataSerializable instead
}

IMap<Object,Object> cacheFor(T tenant){
    return caches[hash(tenant) & (caches.length - 1)]; //only works for power of two arrays.
}

<T> int hash(T tenant){
   return tenant.hashCode(); //Or apply any suitable normalization for better hashing
}


Search by tenant id will be amortized amongst the caches, since ideally, each cache will hold 1/64 of the tenant-aware keys, compared to having a single cache.

Cheers
Reply all
Reply to author
Forward
0 new messages