Project: usergrid
Issue USERGRID-1007: Implement a cache for Shiro & permissions
How will a cache help improve performance? * Reduce load on Tomcat, ES and C* caused by permissons calculation. Do we need a distributed cache? * YES: Todd says we tried non-distributed cache (w/EhCache) and the caching was not effective (bad hit/mss ratio). Implementation ideas: * Use Cassandra column family implementation * Use Hazelcast cache * Use EhCache configured for distributed operation How much should we expect performance to improve? How can we test this? * JUnit + metrics collection in our cache implementation Simplest approach seems to be Cassandra. Here's a design: h1. Add new Core Persistence Cache module This is a new module that depends only on the Core Persistence Common module (and maybe Model?) and provides a generic cache interface that is "segmented" by a cache scope. When you put or get things you specify the cache scope, and it is possible to invalidate all things within a cache scope with one call. {code} public interface SegmentedCache { /** Put value into segment with ttl */ void put( CacheScope scope, K key, V value, long ttl ); /** Get value from segment */ V get( CacheScope segment, K key ); /** Delete all cache data of all types and of all scopes */ void invalidate(); /** Delete all cache data within specified segment */ void invalidate( CacheScope segment ); } {code} Caches are stored in Cassandra *Usergrid_Cache* column family: * Row-key is applicationId * Column key is toString() of K key * Value is serialized V value object h1. Plugin our Cache into Shiro at the REST module level To plugin to Shiro, we provide implementations of the Shiro *CacheManager* and *Cache* interfaces that are backed by the Cache module. When permissions are updated, we need need to ensure that the old cached permissions are invalidated. So we will modify the *EntityManager* revoke and grant methods to call invalidate for the application's cache scope.
Story points: 5