Showing posts with label spring-data-redis. Show all posts
Showing posts with label spring-data-redis. Show all posts

Friday, May 4, 2018

RedisCacheManager Not Updating keyspace_misses

Leave a Comment

I’m using the spring-boot spring-data-redis 1.8.9.RELEASE RedisCacheManager implementation of CacheManager for caching. One metric that I want visibility into is the cache hit/miss ratio. To get that, I’m extracting the keyspace_hits and keyspace_misses exposed via the redis server which can also be viewed via the redis_cli with INFO STATS. The problem is that RedisCacheManager never registers cache misses, i.e. keyspace_misses never increments even if there is a cache "miss".

Debugging the code, I see that spring-data-redis actually checks to see if the key EXISTS in redis before retrieving it. I see the sense with this approach however when EXISTS is executed against the redis server, it does not register a cache miss.

Is there any way to use RedisCacheManager and register cache misses? I know I can use other redis objects to accomplish this but I was wondering if it could be done with the standard CacheManager implementation?

Edit

The ideal solution won't add a great deal of overhead and I am unable to edit the configuration of the redis server.

Code that RedisCacheManager uses when retrieving an element from cache. Notice Boolean exists:

public RedisCacheElement get(final RedisCacheKey cacheKey) {     Assert.notNull(cacheKey, "CacheKey must not be null!");     Boolean exists = (Boolean)this.redisOperations.execute(new RedisCallback<Boolean>() {         public Boolean doInRedis(RedisConnection connection) throws DataAccessException {             return connection.exists(cacheKey.getKeyBytes());         }     });     return !exists ? null : new RedisCacheElement(cacheKey, this.fromStoreValue(this.lookup(cacheKey))); } 

The above code will execute these commands on redis viewable via MONITOR on a cache miss. Notice again that EXISTS is executed as per the code:

Redis commands executed for a cache miss

After the above commands are executed, keyspace_misses is not incremented even though there was a cache miss:

enter image description here

0 Answers

Read More

Tuesday, April 19, 2016

Spring Session Data Redis - Get Valid Sessions, Current User from Redis Store

Leave a Comment

My question is, in distributed web application is it possible to get the valid sessions from Redis Store using RedisOperationSessionRepository. (I mean I don't want to write explicit code for putting it into Redis store and then later read it, I want to understand if framework or spring-data-redis library provides that).

I am aware that Spring Redis is able to restore sessions and server restarts also preserve the login if the session is still valid (as it is backed by Redis)

One of the functionality I am looking for is to get all the possible log in users currently in the application. I am aware of SessionRegistryImpl, and this method. but what I noticed that this method is not backed by Redis and after server restarts, log in users are not returned.

 public List<Object> getAllPrincipals() {     return new ArrayList<Object>(principals.keySet()); } 

One of the functionality I can try is from Spring Session 1.1.0, Spring session find by username.

  1. http://docs.spring.io/spring-session/docs/1.1.0.M1/reference/html5/guides/findbyusername.html
  2. https://spring.io/blog/2015/11/17/spring-session-1-1-0-m1-released

I tried and it indeed returns me valid session result, but the problem is I still need to know all the current valid user names that are using this application. (I don't know how to get them using Redis Store, again I can store in Redis and get them, but I want to know if there is better approach).

This is the piece of code, this is the way I can get current user from one of the many users that are currently using the system, if I know the session id.

    final Session session = redisOperationsSessionRepository.getSession(sessionid);      final Object obj = session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);     if (obj instanceof SecurityContext) {         final SecurityContext context = (SecurityContext) obj;         final Authentication authentication = context.getAuthentication();         if (authentication != null) {             final Object principal = authentication.getPrincipal();             if (principal != null && principal instanceof CurrentUser) {                 return (CurrentUser) principal;             }         }     } 

Now I can use above logic to get all the current user, but again I should all the valid session ids, which I don't know how to get from Redis store.

New Update : https://github.com/spring-projects/spring-session/issues/255 Here in this link, I can probably get all the session ids and look for active sessions in RedisOperationSessionRepository, but might result in performance issues.

I am not sure if I made myself clear, but can't we tell something to Redis using spring session api, just give me all the valid sessions and their current user that are currently log in. (based on last accessed time or something like that).

Thank you

1 Answers

Answers 1

Redis is basically a key-value store and does not provide such querying features.

However, you should be able to list all session using a KEYS request, then filter them on a last-activity basis, but with drawbacks mentioned in the github issue you have mentioned.

You should probably consider logging users activities in a datastore that supports relational querying, keeping Redis as a fast session store.

Read More