首页 > 数据库 >Redis发布订阅模式解决Guava Cache本地缓存刷新问题

Redis发布订阅模式解决Guava Cache本地缓存刷新问题

时间:2024-03-26 19:12:45浏览次数:28  
标签:订阅 频道 缓存 Cache Redis 本地 Guava 节点 channel

为什么要用本地缓存

可以加快资源访问速度,减少第三方IO延迟,也避免了网络调用的开销,将数据存储在本地jvm内存中
可以减少外部系统的压力,可以将频繁访问、且更新场景较少的数据缓存起来,降低对远程服务或者数据库的请求次数,降低外部系统负载,提供系统整体的稳定性
缺点:
但是同时也得注意限制本地缓存的数据量,避免影响正常业务流程,防止系统OOM,不适合存储大量或者大数据结构的场景
数据不能持久化,重启系统将会导致本地缓存数据丢失,最好搭配持久化数据库进行访问,比如持久化到mysql, 用Redis做一级缓存,用本地缓存做二级缓存
数据一致性问题,当应用部署在集群环境,无法保证数据一致性,且各个节点之间的数据无法自动同步,如果需要解决这一问题,需要设计复杂的缓存同步机制

常用的本地缓存

Guava Cache
Google Guava库提供的Cache实现,可以实现缓存失效(基于时间或访问次数)、自动加载数据,、缓存统计等
EHCache
Ehcache是一个广泛使用的Java分布式缓存解决方案,虽然主要用于本地缓存,但也支持集群和分布式缓存。Ehcache 提供了丰富的配置选项,可以设定缓存项的生命周期、最大条目数以及其他复杂的缓存策略,并且与Hibernate等框架集成良好。
HashMap
最简单粗暴的本地缓存实现,无需引入额外的依赖,但不提供缓存回收、过期策略等问题

本地缓存缺点

本地缓存最大的缺点就在于数据不一致,每个服务节点都有自己的缓存副本,但是可以实现最终一致性,对于实时性要求不高的情况下,不建议使用,还是乖乖的使用redis这些分布式缓存,
但是优点也是异常的明显,几乎没有网络延迟,磁盘读取等,性能极高

实际使用中会搭配持久化数据库以及redis来使用,可以很大的提高性能,对于实时性要求不是很高的情况下,本文采用redis的订阅发布模式,发送广播消息来实现清除和更新缓存数据,基本上实现本地缓存更新的方案

Guava Cache简单使用


申明缓存以及根据key获取缓存

Redis Pub/Sub

命令介绍
https://redis.io/commands/?group=pubsub

SUBSCRIBE

SUBSCRIBE channel [channel...]
客户端订阅指定的频道

PUBLISH

PUBLISH channel message
指定频道发送消息,在Redis集群中,可以发布到任何一个节点,Redis会确保需要转发的消息,因此客户端可以连接到任一节点来订阅任意频道

UNSCRIBE

UNSUBSCRIBE [channel [channel ...]]
取消订阅消息,可以指定取消定于的channel,如果参数没有,则取消之前订阅的全部频道

这里我们新建channel名为mongo

执行publish命令可以看到消息已经过来了

值得注意的是,redis 订阅发布模式无法查看当前channel的订阅者列表,但是可以通过以下命令查看订阅频道的列表

PUBSUB CHANNELS [pattern]

PUBSUB NUMSUB [channel [channel ...]]

可以查看当前频道的订阅者数量,

spring项目中使用

回归到更新本地缓存问题,如果是通过其他方式,线上服务如果是集群的话,每次请求访问肯定会负载到其中某一个节点,无法保证所有节点的缓存更新,
如果是spring项目的话,可以在项目启动的时候进行订阅频道,项目销毁的时候进行取消订阅,因为是不同的节点订阅,所以可以保证每个节点都会订阅成功
可以利用spring的几个扩展点,比如实现InitializingBean,好在已经有了现成的轮子,RedisMessageListenerContainer

@Configuration
public class RedisMessageConfig {

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);

        // 1.订阅监听
        container.addMessageListener(new MessageListenerAdapter(new RedisMessageListener()), new ChannelTopic("mongo"));

        return container;
    }

    private class RedisMessageListener extends MessageListenerAdapter {
        @Override
        public void onMessage(Message message, byte[] pattern) {
            logger.info("redis消息接收成功:" + message.toString());
        }
    }
}

我们只需要注入RedisMessageListenerContainer即可,在RedisMessageListener执行清除本地缓存的操作


在MessageListenerAdapter中执行清除缓存的操作

新启动几个节点进行测试一下,可以在idea config 中设置添加 Add VM options 中添加 -Dserver.port=8081,或者在Program arguments中添加 --server.port=8081进行配置
这里启动两个节点进行测试


两个节点基本上无延迟,可以在一定程序上保证不同节点缓存的一致性

扩展延伸
1、使用Redis的订阅发布模式仅仅为其中一种思路,因为不同jvm暂时无法通信,所以智能借助第三方中间件,也可以使用不同类型的消息队列,比如RabbitMQ,RocketMQ,进行广播消费,可以达到相同的效果
2、可以借助订阅发布模式,定义一个频道,通过不同的消息内容来区分需要订阅的场景,一个项目只存在这一个频道,可以将订阅发布的用处达到最大化,比如通过订阅频道刷新别的数据

标签:订阅,频道,缓存,Cache,Redis,本地,Guava,节点,channel
From: https://www.cnblogs.com/LiuFqiang/p/18090226

相关文章

  • docker compose 启动 redis
    redis.ymlversion:"2.4"services:redis:image:redis:6.2.1container_name:redisenvironment:-TZ=Asia/Shanghai#-redisPWD=cl0udsuit1privileged:truepid:"host"network_mode:"ho......
  • CentOS安装Redis
    目录一、场景二、安装一、场景1、在CentOS服务器安装Redis服务二、安装1、添加EPEL存储库sudoyuminstallepel-release2、安装Redissudoyuminstallredis安装过程遇到y/n的选择,直接选择y3、查看redis的安装情况serviceredisstatus4、以进程的......
  • docker-运行redis服务
    环境说明linux系统版本:lsb_release-a  docker版本:docker-v  不同的操作系统以及软件版本,可能会遇到不一样的问题,一定要注意版本问题。 查看docker中mysql的版本,可以去官网,需要kx上网才能打开。https://hub.docker.com/  最好是确认自己的服务器已经......
  • redis主从搭建(测试环境单机多端口)
    采用一主两从完成搭建,实现了主节点做写操作,从节点做读操作,并且主从会进行同步。步骤需要注意的有以下几点:replica-announce-ip设置为自己虚拟机的ip地址requirepass设置为无密码,否则主从节点将连接失败如果端口被占用,需要首先找到占用端口号的进程,然后将其杀死......
  • 鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业
    随着企业的快速发展,招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求,建立一个公平、公开、公正的采购环境至关重要。在这个背景下,我们开发了一款电子招标采购软件,以最大限度地控制采购成本,提高招投标工作的公开性和透明性,并确保符合国家电子招投标......
  • Redis 缓存穿透是什么?如何缓解缓存穿透?
    缓存穿透是指在使用缓存技术时,恶意或无效的请求无法从缓存中获取到数据,从而直接落到底层存储系统(如数据库)上,导致频繁地查询底层存储系统,增加系统负载并降低性能。缓存通常用于存储经常被请求的数据,以提高系统的访问速度。但是,当恶意用户故意发送无效或不存在的请求时,缓存无法......
  • redis自学(24)RESP协议
    Redis是一个CS架构的软件,通信一般分两步(不包括pipeline和PubSub):①客户端(client)向服务端(server)发送一条命令②服务端解析并执行命令,返回响应结果给客户端因此客户端发送命令的格式、服务端相应结果的格式必须有一个规范,这个规范就是通讯协议。而在Redis中采用的是RESP(Redi......
  • redis哨兵 ,redis集群 缓存 以及某些问题: 最左前缀原则,,celery架构
    Redis哨兵#主从复制存在的问题:#1主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave变成master-哨兵解决#2主从复制,只能主写数据,所以写能力和存储能力有限-集群来解决#搭建哨兵的目的一旦一主多从的架构,主库发生故障,能够自动转移一......
  • config.cache 使用
    官方地址:https://docs.pytest.org/en/8.0.x/reference/reference.html#config-cache在pytest中,cache是一个非常有用的功能,它允许你在测试会话之间持久化状态。这意味着你可以在一次测试运行中存储一些值,并在后续的测试运行中访问这些值。这对于需要重用昂贵的计算结果或避免重......
  • 鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业
    随着企业的快速发展,招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求,建立一个公平、公开、公正的采购环境至关重要。在这个背景下,我们开发了一款电子招标采购软件,以最大限度地控制采购成本,提高招投标工作的公开性和透明性,并确保符合国家电子招投标......