skip to Main Content

I’m trying to collect the cache metrics in detail, capture them as events, for instance; object is hit from cache, or it was a miss, it took X milliseconds, not just aggregated metrics. Since Spring Cache abstraction is already good enough, I thought I would find something like interceptors or filters but there does not seem one. How would one go with it, implementing a CacheManager without themselves? By reference, I’m using Redis cache with Lettuce Client, but would prefer the Cache abstraction to stay and capture cache events in a central place.

  • Being relatively new to Spring, I’m not even sure what’s the best way to do these. I tried creating my CacheManager wrapping redis one, but not sure how it plays with auto-configuration.
  • My own cache manager just proxies all the calls to the wrapped one, but it does not know if it’s whether a cache hit or miss, they are called even if the cache is empty with the actual method call.

2

Answers


  1. It doesn’t seems, that Lettuce offers the availability to measure the hit/miss of a cache.
    Lettuce has some built-in metrics like a histrogram or latency. A link to the wiki.

    You can try to grab some metrics from redis itself. Have a look to the redis-docs.
    There you can get some more data like read/write hit/miss or evicted_objects.

    All in all: I don’t think that a object-level metric (= a per-key metric?) isn’t really helpful. Did you want to know, how fast is object-id-abc vs object-id-def?

    But if you really need that: You can define the RedisClient as bean by yourself with a custom implementation (proxy-pattern or override some of the methods). Then you can measure the time.
    I see no way, to get the cache hit/miss from redis. Maybe you will find something in the lettuce-github-repo and/or the redis-api.
    You can try to archive that with the execution-time (when it takes long to get a value, it was maybe not in cache), but this is very unstable and you will get a lot of false positives.


    Edit

    As a other idea: In your proxy you can store the metric how often a key was requested (it should be measure as timeunit like requests/hour). Combined with the execution-time you are near to the cache hit/miss-metric.

    Login or Signup to reply.
  2. Are you looking for RedisCache.getStatistics?

    It returns CacheStatistics.

    public interface CacheStatistics {
    
        /**
         * @return the name of the {@link RedisCache}.
         */
        String getCacheName();
    
        /**
         * @return number of put operations on the cache.
         */
        long getPuts();
    
        /**
         * @return the total number of get operations including both {@link #getHits() hits} and {@link #getMisses() misses}.
         */
        long getGets();
    
        /**
         * @return the number of cache get hits.
         */
        long getHits();
    
        /**
         * @return number of cache get misses.
         */
        long getMisses();
    
        /**
         * @return the number of {@link #getGets() gets} that have not yet been answered (neither {@link #getHits() hit} nor
         *         {@link #getMisses() miss}).
         */
        default long getPending() {
            return getGets() - (getHits() + getMisses());
        }
    
        /**
         * @return number of cache removals.
         */
        long getDeletes();
    
        /**
         * @param unit the time unit to report the lock wait duration.
         * @return lock duration using the given {@link TimeUnit} if the cache is configured to use locking.
         */
        long getLockWaitDuration(TimeUnit unit);
    
        /**
         * @return initial point in time when started statistics capturing.
         */
        Instant getSince();
    
        /**
         * @return instantaneous point in time of last statistics counter reset. Equals {@link #getSince()} if never reset.
         */
        Instant getLastReset();
    
        /**
         * @return the statistics time.
         */
        default Instant getTime() {
            return Instant.now();
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search