redis--缓存同步

一、三种缓存同步基础方案

表格

方案 原理 优点 缺点 适用场景
设置有效期 给缓存设置 TTL,到期自动删除;查询时回写 最简单,无代码侵入 数据不一致窗口大,时效差 更新频率低、对一致性要求低
同步双写 修改数据库的同时,直接更新 / 删除缓存 实时性强,一致性好 业务代码耦合高,数据库和缓存双操作,存在失败风险 强一致性、高时效业务
异步通知 改库后发送事件,监听服务收到事件再更新缓存 低耦合,可同时通知多个下游服务 存在短暂数据不一致 多服务需要同步缓存,时效性要求一般

异步通知有两种实现:基于 MQ 、基于 Canal 监听 binlog

1. 基于 MQ 异步通知流程

  1. 用户修改商品,item-service 先写 MySQL
  2. 写入成功后,item-service 向 MQ 发送数据变更消息
  3. cache-service监听 MQ 消息
  4. 收到消息后,更新 Redis 缓存 ✅优点:业务可控,消息可以做重试 ❌缺点:需要业务代码手动发消息,代码有侵入;如果数据库成功但是发 MQ 失败,会出现数据不一致

2. 基于 Canal 异步通知流程

  1. 用户修改商品,item-service写入 MySQL
  2. MySQL 写入 binlog 二进制日志
  3. Canal 伪装成 MySQL 的 Slave 节点,拉取 master 的 binlog,监听数据变更
  4. Canal 把变更行数据推送给 Canal 客户端(cache-service)
  5. 客户端收到变更,更新 Redis 缓存 ✅优点:完全无业务代码侵入,不需要业务服务发消息;可以监听数据库所有变更 ❌缺点:依赖 binlog,有一定延迟;需要单独部署 Canal 服务

Canal 核心原理:伪装成 MySQL 从库,向 Master 发送 dump 协议,拉取 binlog,解析 binlog 拿到 DML 变更(增 / 删 / 改),推送给客户端。 下游可以对接 Redis、ES、MQ、HBase 等。

二、SpringBoot 整合 Canal 客户端

  1. 引入 Maven 依赖(第三方 canal-starter)

    top.javatool canal-spring-boot-starter 1.2.1-RELEASE
  2. yml 配置

    canal:
    destination: heima # 和canal-server配置的实例名称一致
    server: 192.168.150.101:11111 # canal服务地址端口

  3. 实体类(JPA 注解做字段映射)

    @Data
    @TableName("tb_item")
    public class Item {
    @Id
    @TableId(type = IdType.AUTO)
    private Long id;
    @Column(name = "name")
    private String name;
    private Date updateTime;

    复制代码
     // 数据库不存在的字段,忽略映射
     @Transient
     @TableField(exist = false)
     private Integer stock;
     @Transient
     @TableField(exist = false)
     private Integer sold;

    }

  4. 编写监听器 Handler

    @CanalTable("tb_item") // 监听哪张表
    @Component
    public class ItemHandler implements EntryHandler {
    // 新增
    @Override
    public void insert(Item item) {
    // 新增数据写入Redis
    }
    // 更新:before修改前,after修改后
    @Override
    public void update(Item before, Item after) {
    // 更新Redis,同步本地缓存
    }
    // 删除
    @Override
    public void delete(Item item) {
    // 删除Redis,清理本地缓存
    }
    }

三、OpenResty Nginx 本地缓存(lua_shared_dict)

OpenResty 提供lua_shared_dict,在 Nginx 多个 worker 进程之间共享内存缓存,作为多级缓存最前端的本地缓存。

  1. nginx.conf http 块配置

    共享字典,缓存名称item_cache,大小150M

    lua_shared_dict item_cache 150m;

  2. Lua 脚本操作共享字典

    -- 获取缓存对象
    local item_cache = ngx.shared.item_cache
    -- 写入:key,value,过期时间(秒),0永不过期
    item_cache:set('key', 'value', 1000)
    -- 读取
    local val = item_cache:get('key')

多级缓存顺序:Nginx 本地共享字典缓存 → Redis 分布式缓存 → MySQL 数据库 当数据库变更,通过 Canal 监听 binlog,同时更新 Redis + 清理 Nginx 本地缓存。

相关推荐
禾小西3 小时前
06丨Redis 数据同步:主从库如何实现数据一致?
数据库·redis·php
我不会插花弄玉4 小时前
4.string类型【由浅入深-redis】
数据库·redis·缓存
范中勤8 小时前
LLM 动态加载与多用户缓存架构技术文档
redis·langchain·llm·缓存架构·多用户隔离
小小龙学IT9 小时前
Redis 源码深度解析:从常用命令到内部实现
redis·golang·开源
禾小西21 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
骉马代驾1 天前
代驾系统实战(三):抢单池的 Redis 锁 + RabbitMQ 异步消费怎么做
redis
行百里er1 天前
Redis Streams——有确认、能回溯的消息队列
redis
小马同学-1 天前
Redis消息队列与客户端编程
数据库·redis
fengkai45451 天前
十二、Redis -2
运维·数据库·redis·容器