RedisCacheManager 未更新 keyspace_misses

Posted

技术标签:

【中文标题】RedisCacheManager 未更新 keyspace_misses【英文标题】:RedisCacheManager Not Updating keyspace_misses 【发布时间】:2018-10-06 12:43:46 【问题描述】:

我正在使用 CacheManager 的 spring-boot spring-data-redis 1.8.9.RELEASE RedisCacheManager 实现进行缓存。我想要了解的一个指标是缓存命中/未命中率。为此,我提取了通过 redis 服务器公开的 keyspace_hits and keyspace_misses,也可以通过带有 INFO STATS 的 redis_cli 查看。问题是 RedisCacheManager 从不注册缓存未命中,即即使存在缓存“未命中”,keyspace_misses 也永远不会增加。

调试代码,我看到spring-data-redis实际上在检索之前检查redis中的键EXISTS是否存在。我看到了这种方法的意义,但是当EXISTS 对 redis 服务器执行时,它不会注册缓存未命中。

有没有办法使用 RedisCacheManager 并注册缓存未命中?我知道我可以使用其他 redis 对象来完成此操作,但我想知道是否可以使用标准 CacheManager 实现来完成?

编辑

理想的解决方案不会增加很多开销,我无法编辑 redis 服务器的配置。

RedisCacheManager 从缓存中检索元素时使用的代码。通知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)));

以上代码将在缓存未命中时在可通过MONITOR 查看的redis 上执行这些命令。再次注意EXISTS 是按照代码执行的:

执行上述命令后,keyspace_misses 不会增加,即使有缓存未命中:

【问题讨论】:

对空键调用的任何阻塞操作(BLPOP、BRPOP 和 BRPOPLPUSH)都会导致 keyspace_misses 递增。 你准备好走多远?您可以从源代码构建 Redis 并添加将 EXISTS 注册为缓存未命中的行。 @Imaskar 感谢评论,但我无法对 redis 服务器进行任何更改。 @AlwaysLearning,你有没有为你的查询找到解决方案。我们也面临同样的问题。您的意见将对我们有所帮助。我们使用的是以下版本的 redis:Redis server v=3.2.12 @Prakash,不幸的是,没有找到可行的解决方案。 【参考方案1】:

问题中提到的代码是Spring提供的RedisCache的一部分。

    扩展并创建 RedisCache 类的自定义实现,以覆盖“get”方法的行为以满足您的需要。 扩展 RedisCacheManager 以覆盖方法“createRedisCache”以使用您在第一步中创建的自定义 RedisCache 而不是默认缓存。

【讨论】:

感谢您的意见。你能提供工作代码来证明你的答案吗?我看了一下,我没有看到一个可行的机制来完成上述操作。 我知道这很旧,但我可以确认这个方法有效,它有点令人费解,因为并非所有类和构造函数都是公共的,但可以创建一个 Cache 装饰器并创建一个 CacheManager 来装饰缓存与您的实现。

以上是关于RedisCacheManager 未更新 keyspace_misses的主要内容,如果未能解决你的问题,请参考以下文章

springboot 中 RedisCacheManager rm = new RedisCacheManager(redisTemplate);我的项目没这个构造

如何在 spring-data 2.0.x 中创建 RedisCacheManager

如何将默认过期的 RedisCacheManager 迁移到 Spring Data Redis 2.0?

Vue data更新了,但视图未更新

SpringBoot2.3.0自定义RedisCacheManager并对缓存Jackson序列化

未更新的组件列表