Redis+Caffeine多级缓存数据一致性解决方案

 更新时间:2024年12月04日 11:53:05   作者:YAnalytics  
两级缓存Redis+Caffeine可以解决缓存雪等问题也可以提高接口的性能,但是可能会出现缓存一致性问题,如果数据频繁的变更,可能会导致Redis和Caffeine数据不一致的问题,所以本文给大家介绍了Redis+Caffeine多级缓存数据一致性解决方案,需要的朋友可以参考下

问题分析

通过Redis+Caffeine,似乎可以完成一级、二级缓存中数据的同步,如果在单节点项目中是没有问题的,但是,在分布式场景下是有问题的,看下图:

说明:

  • 部署了2个transport-info微服务节点,每个微服务都有自己进程级的一级缓存,都共享同一个Redis作为二级缓存
  • 假设,所有节点的一级和二级缓存都是空的,此时,用户通过节点1查询运单物流信息,在完成后,节点1的caffeine和Redis中都会有数据
  • 接着,系统通过节点2更新了数据,此时节点2中的caffeine和Redis都是更新后的数据
  • 用户还是进行查询动作,依然是通过节点1查询,此时查询到的将是旧的数据,也就是出现了一级缓存与二级缓存之间的数据不一致的问题

解决方案

如何解决该问题呢?可以通过消息的方式解决,就是任意一个节点数据更新了数据,发个消息出来,通知其他节点,其他节点接收到消息后,将自己caffeine中相应的数据删除即可。

关于消息的实现,可以采用RabbitMQ,也可以采用Redis的消息订阅发布来实现,在这里为了应用技术的多样化,所以采用Redis的订阅发布来实现。

方案概述

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息

当有新消息通过 publish 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端。

Redis的订阅发布功能与传统的消息中间件(如:RabbitMQ)相比,相对轻量一些,针对数据准确和安全性要求没有那么高的场景可以直接使用。

代码实现

  • 在RedisConfig增加订阅的配置:
	/**
     * 配置订阅,用于解决Caffeine一致性的问题
     *
     * @param connectionFactory 链接工厂
     * @param listenerAdapter 消息监听器
     * @return 消息监听容器
     */
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                   MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new ChannelTopic(CHANNEL_TOPIC));
        return container;
    }
  • 编写RedisMessageListener用于监听消息,删除caffeine中的数据。
/**
 * redis消息监听,解决Caffeine一致性的问题
 */
@Slf4j
@Component
public class RedisMessageListener extends MessageListenerAdapter {

    @Resource
    private Cache<String, TransportInfoDTO> transportInfoCache;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 获取到消息中的运单id
        String transportOrderId = Convert.toStr(message);
        log.info("redis消息监听缓存变更,运单id:{}", transportOrderId);
        // 将本jvm中的缓存删除掉
        this.transportInfoCache.invalidate(transportOrderId);
    }
}
  • 更新数据后向redis发送消息:
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @CachePut(value = "transport-info", key = "#p0")
    public TransportInfoEntity saveOrUpdate(String transportOrderId, TransportInfoDetail infoDetail) {
		// 省略代码
 
        // 清除缓存中的数据
        // this.transportInfoCache.invalidate(transportOrderId);
        // Caffeine本地缓存一致性,发布订阅消息到redis,通知订阅者更新缓存
        this.stringRedisTemplate.convertAndSend(RedisConfig.CHANNEL_TOPIC, transportOrderId);
        // 保存/更新到MongoDB
        return this.mongoTemplate.save(transportInfoEntity);
    }

总结

本文主要讲解了在使用Redis和Caffeine多级缓存时使用Redis的发布订阅模式来保证两级缓存的数据一致性。本地缓存是基于服务本地内存的,分布式系统中当缓存更新时,可能造成多个实例间的本地缓存不一致问题。可以使用RabbitMQ或者Redis的发布订阅来解决本地缓存不一致的问题。

以上就是Redis+Caffeine多级缓存数据一致性解决方案的详细内容,更多关于Redis Caffeine缓存数据一致性的资料请关注脚本之家其它相关文章!

相关文章

  • 详解Redis使用认证密码登录

    详解Redis使用认证密码登录

    本篇文章主要介绍了详解Redis使用认证密码登录 。启用Redis的认证密码可以增加Redis服务器的安全性。有兴趣的可以了解下
    2017-06-06
  • Redis哨兵模式实现一主二从三哨兵

    Redis哨兵模式实现一主二从三哨兵

    本文主要介绍了Redis哨兵模式实现一主二从三哨兵,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Redis实现短信登录的企业实战

    Redis实现短信登录的企业实战

    本文主要介绍了Redis实现短信登录的企业实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 浅析Redis 切片集群的数据倾斜问题

    浅析Redis 切片集群的数据倾斜问题

    如果 Redis 中的部署,采用的是切片集群,数据是会按照一定的规则分散到不同的实例中保存,比如,使用 Redis Cluster 或 Codis,这篇文章主要介绍了Redis 切片集群的数据倾斜分析,需要的朋友可以参考下
    2022-06-06
  • Redis中redis-shake实现数据迁移同步

    Redis中redis-shake实现数据迁移同步

    在业务环境中使用Redis进行跨区域数据迁移和同步的挑战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • Linux中设置Redis开机启动的方法

    Linux中设置Redis开机启动的方法

    这篇文章主要给大家介绍了关于Linux中设置Redis开机启动的方法,主要包括在CentOS7.0系统和Debian 8.0系统下实现方法,文中介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-04-04
  • Redis教程(十五):C语言连接操作代码实例

    Redis教程(十五):C语言连接操作代码实例

    这篇文章主要介绍了Redis教程(十五):C语言连接操作代码实例,本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例,需要的朋友可以参考下
    2015-05-05
  • Redis 布隆过滤器命令的使用详解

    Redis 布隆过滤器命令的使用详解

    这篇文章主要介绍了Redis 布隆过滤器的相关命令的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • Redis实现多级缓存

    Redis实现多级缓存

    这篇文章主要为大家详细介绍了Redis实现多级缓存,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Redis可视化工具Redis Desktop Manager的具体使用

    Redis可视化工具Redis Desktop Manager的具体使用

    本文主要介绍了Redis可视化工具Redis Desktop Manager的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12

最新评论