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 本地缓存。

相关推荐
m0_639906946 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
IT规划师12 小时前
Redis 数据类型全解 - String 不只是 get set:90% 开发者忽略的 8 个高阶用法与内存陷阱(一)
redis·.net core
Flynn Liang13 小时前
内存/Redis/PGVector/Milvus/ES 怎么选?Spring AI VectorStore 抽象与向量库选型对照表
redis·elasticsearch·milvus·rag·springai·pgvector·向量库
hweiyu0015 小时前
Redis命令:SUNIONSTORE
redis·缓存
麻瓜code15 小时前
秒杀优化三连:Lua + 阻塞队列 + Redis Stream,响应从 3.4 秒到毫秒级
redis·junit·lua
没有气的汽水19 小时前
一次生产 Redis 内存打满的排查、清理和复盘
redis
hey you~19 小时前
云呼叫中心坐席自动分配实战:ACD 策略、Redis+Lua 实现与排查清单
数据库·redis·lua·云呼叫中心·acd·坐席分配·坐席状态机
我不会起名字32221 小时前
Redis pipeline 用了反而更慢:3 类误用与正确的批量姿势
redis·pipeline·lua·rtt·批量
Tsuki_tl21 小时前
【总结】Redis五大数据类型应用场景及基本命令
数据库·redis·后端·缓存·缓存中间件·redis命令·redis 五大数据类型