Redis双写一致

一、双写一致

双写一致性:当修改了数据库的数据也要同步更新缓存的数据,缓存和数据库的数据要保持一致。

在这里插入图片描述

  • 读操作:缓存命中,直接返回;缓存未命中,直接读取数据库,然后写入缓存,设定超时时间。
  • 写操作:延迟双删
    在这里插入图片描述

1.1 先删除缓存,在删除数据库

正常流程:线程1删除缓存,更新数据库,更新缓存,线程2直接查询缓存。

在这里插入图片描述

异常流程:线程1删除缓存,更新数据库的时候,线程2直接访问数据库,更新缓存,导致数据库数据和缓存数据不一致。数据库中存在旧数据。

在这里插入图片描述

1.2 先删除数据库,在删除缓存

正常流程:线程2删除数据库,更新数据库数据,删除缓存;线程1查询缓存不存在,然后查询数据库,更新缓存

在这里插入图片描述

异常流程:线程2在更新数据库,删除缓存的时候,线程1此时访问缓存未命中,然后从数据库中拿到旧数据,然后更新缓存,导致缓存中存在旧数据

在这里插入图片描述

1.3 延时双删

理由:
	主要是降低数据库和缓存的不一致的概率;
	mysql数据库是主从复制,延时一会;
缺点:
	延时时间不好控制,可能回存在脏数据。

在这里插入图片描述

1.4 分布式锁

- 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作。
- 排他锁:独占锁writeLock,加锁之后,阻塞其他线程读写操作。

在读的时候使用共享锁,在写入数据的时候使用排他锁,保证数据的强一致性,性能低。

在这里插入图片描述
首先,添加Redisson的依赖到你的项目中

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.XX.X</version> <!-- 使用最新的稳定版本 -->
</dependency>

代码实现:

import org.redisson.Redisson;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
/**
 * @Author cxc
 * @Date 2024/8/20 11:02
 * @Version 1.0
 * @Email cxc_work@163.com
 */
public class RedisTest
{
    public static void main(String[] args) {
        // 配置RedissonClient,可写成工具类
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        //config.useSentinelServers().setUsername("用户名");
        //config.useSentinelServers().setPassword("密码");
        RedissonClient redisson = Redisson.create(config);

        // 获取读写锁
        RReadWriteLock rwLock = redisson.getReadWriteLock("anyRWLock");

        // 获取读锁部分
        rwLock.readLock().lock();
        try {
            // 业务逻辑
            // 查询等操作
            System.out.println("查询100");
        } finally {
            // 释放读锁
            rwLock.readLock().unlock();
        }

        // 获取写锁部分
        rwLock.writeLock().lock();
        try {
            // 业务逻辑
            //添加修改灯操作
            System.out.println("修改50");
        } finally {
            // 释放写锁
            rwLock.writeLock().unlock();
        }

        // 关闭RedissonClient
        redisson.shutdown();
    }
}

1.5 异步通知

mq消息中间件通知

在这里插入图片描述

基于cannl中间件的通知

基于mysql的主从同步来实现的
binlog二进制文件记录了所有的DDL(数据定义语言)和DML(数据操纵语言),不包括数据查询语句select和show。

在这里插入图片描述

二、总结

允许延时一致的业务,采用异步通知:

1. 使用MQ消息中间件,更新数据后,通知缓存删除。
2. 使用canal中间件,不需要修改业务代码,伪装成mysql的一个从节点,cannal读取binlog文件修改更新缓存

强一致性的业务,采用redission的读写锁

1. 共享锁
2. 排他锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值