搜索
首页数据库mysql教程MySQL数据库和Redis缓存一致性的更新策略是什么

    一、更新策略

    1、如果Redis中有数据,需要和数据库中的值相同。

    2、如果Redis中无数据,数据库中的最新值要对Redis进行同步更新。

    二、读写缓存

    1、同步直写策略

    写入数据库也同步写Redis缓存,缓存和数据库中的数据一致;对于读写缓存来说,要保证缓存和数据库中的数据一致,就要保证同步直写策略。

    2、异步缓写策略

    某些业务运行中,MySQL数据更新之后,允许在一定时间后再进行Redis数据同步,比如物流系统。

    当出现异常情况时,不得不将失败的动作重新修补,需要借助rabbitmq或kafka进行重写。

    三、双检加锁策略

    多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。

    其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。

    后面的线程进来发现已经有缓存了,就直接走缓存。

    public String get(String key){
        // 从Redis缓存中读取
        String value = redisTemplate.get(key);
    
        if(value != null){
            return value;
        }
    
        synchronized (RedisTest.class){
            // 重新尝试从Redis缓存中读取
            value = redisTemplate.get(key);
            if(value != null){
                return value;
            }
    
            // 从MySQL数据库中查询
            value = studentDao.get(key);
            // 写入Redis缓存
            redisTemplate.setnx(key,value,time);
            return value;
        }
    }

    四、数据库和缓存一致性的更新策略

    1、先更新数据库,再更新Redis

    按照常理出牌的话,应该都是如此吧?那么,这种情况下,会有啥问题呢?

    如果更新数据库成功后,更新Redis之前异常了,会出现什么情况呢?

    数据库与Redis内缓存数据不一致。

    2、先更新缓存,再更新数据库

    多线程情况下,会有问题。

    比如

    • 线程1更新redis = 200;

    • 线程2更新redis = 100;

    • 线程2更新MySQL = 100;

    • 线程1更新MySQL = 200;

    结果呢,Redis=100、MySQL=200;我擦!

    3、先删除缓存,再更新数据库

    线程1删除了Redis的缓存数据,然后去更新MySQL数据库;
    还没等MySQL更新完毕,线程2杀来,读取缓存数据;
    但是,此时MySQL数据库还没更新,线程2读取了MySQL中的旧值,然后线程2,还会将旧值写入Redis作为数据缓存;
    线程1更新完MySQL数据后,发现Redis中已经有数据了,之前都删过了,那我就不更新了;
    完蛋了。。

    延时双删

    延时双删可以解决上面的问题,只要sleep的时间大于线程2读取数据再写入缓存的时间就可以了,也就是线程1的二次清缓存操作要在线程2写入缓存之后,这样才能保证Redis缓存中的数据是最新的。

    /**
     * 延时双删
     * @autor 哪吒编程
     */
    public void deleteRedisData(Student stu){
        // 删除Redis中的缓存数据
        jedis.del(stu);
    
        // 更新MySQL数据库数据
        studentDao.update(stu);
    
        // 休息两秒
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        // 删除Redis中的缓存数据
        jedis.del(stu);
    }

    延迟双删最大的问题就是sleep,在效率为王的今天,sleep能不用还是不用为好。

    你不睡我都嫌你慢,你还睡上了…

    4、先更新数据库,再删除缓存

    1. 线程1先更新数据库,再删除Redis缓存;

    2. 线程2在线程1删除Redis缓存之前发起请求,得到了未删除的Redis缓存;

    3. 线程1此时才删除Redis缓存数据;

    问题还是有,这翻来覆去的,没完没了了。

    这种情况如何解决呢?

    引入消息中间件解决战斗,再一次详细的复盘一下。

    1. 更新数据库;

    2. 数据库将操作信息写入binlog日志;

    3. 订阅程序提取出key和数据;

    4. 尝试删除缓存操作,发现删除失败;

    5. 将这些数据信息发送到消息中间件中;

    6. 从消息中间件中获取该数据,重新操作;

    5、总结

    哪吒推荐使用第四种方式,先更新数据库,再删除缓存。

    方式①和方式②缺点太过明显,不考虑;
    方式③中的sleep,总是让人头疼;
    方式④是一个比较全面的方案,但是增加了学习成本、维护成本,因为增加了消息中间件。

    五、MySQL主从复制工作原理

    MySQL数据库和Redis缓存一致性的更新策略是什么

    1、当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中;

    2、salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测,探测其是否发生过改变,

    如果探测到 master 主服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志;

    3、同时 master 主服务器为每个 I/O Thread 启动一个dump Thread,用于向其发送二进制事件日志;

    4、slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中;

    5、salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;

    6、最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒。

    以上是MySQL数据库和Redis缓存一致性的更新策略是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

    声明
    本文转载于:亿速云。如有侵权,请联系admin@php.cn删除
    图文详解mysql架构原理图文详解mysql架构原理May 17, 2022 pm 05:54 PM

    本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于架构原理的相关内容,MySQL Server架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层,下面一起来看一下,希望对大家有帮助。

    mysql怎么替换换行符mysql怎么替换换行符Apr 18, 2022 pm 03:14 PM

    在mysql中,可以利用char()和REPLACE()函数来替换换行符;REPLACE()函数可以用新字符串替换列中的换行符,而换行符可使用“char(13)”来表示,语法为“replace(字段名,char(13),'新字符串') ”。

    mysql的msi与zip版本有什么区别mysql的msi与zip版本有什么区别May 16, 2022 pm 04:33 PM

    mysql的msi与zip版本的区别:1、zip包含的安装程序是一种主动安装,而msi包含的是被installer所用的安装文件以提交请求的方式安装;2、zip是一种数据压缩和文档存储的文件格式,msi是微软格式的安装包。

    mysql怎么去掉第一个字符mysql怎么去掉第一个字符May 19, 2022 am 10:21 AM

    方法:1、利用right函数,语法为“update 表名 set 指定字段 = right(指定字段, length(指定字段)-1)...”;2、利用substring函数,语法为“select substring(指定字段,2)..”。

    mysql怎么将varchar转换为int类型mysql怎么将varchar转换为int类型May 12, 2022 pm 04:51 PM

    转换方法:1、利用cast函数,语法“select * from 表名 order by cast(字段名 as SIGNED)”;2、利用“select * from 表名 order by CONVERT(字段名,SIGNED)”语句。

    MySQL复制技术之异步复制和半同步复制MySQL复制技术之异步复制和半同步复制Apr 25, 2022 pm 07:21 PM

    本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于MySQL复制技术的相关问题,包括了异步复制、半同步复制等等内容,下面一起来看一下,希望对大家有帮助。

    带你把MySQL索引吃透了带你把MySQL索引吃透了Apr 22, 2022 am 11:48 AM

    本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了mysql高级篇的一些问题,包括了索引是什么、索引底层实现等等问题,下面一起来看一下,希望对大家有帮助。

    mysql怎么判断是否是数字类型mysql怎么判断是否是数字类型May 16, 2022 am 10:09 AM

    在mysql中,可以利用REGEXP运算符判断数据是否是数字类型,语法为“String REGEXP '[^0-9.]'”;该运算符是正则表达式的缩写,若数据字符中含有数字时,返回的结果是true,反之返回的结果是false。

    See all articles

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    2 周前By尊渡假赌尊渡假赌尊渡假赌
    仓库:如何复兴队友
    4 周前By尊渡假赌尊渡假赌尊渡假赌
    Hello Kitty Island冒险:如何获得巨型种子
    4 周前By尊渡假赌尊渡假赌尊渡假赌

    热工具

    螳螂BT

    螳螂BT

    Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

    DVWA

    DVWA

    Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

    SublimeText3 英文版

    SublimeText3 英文版

    推荐:为Win版本,支持代码提示!

    适用于 Eclipse 的 SAP NetWeaver 服务器适配器

    适用于 Eclipse 的 SAP NetWeaver 服务器适配器

    将Eclipse与SAP NetWeaver应用服务器集成。

    Dreamweaver Mac版

    Dreamweaver Mac版

    视觉化网页开发工具