• 面试官:你是如何保障MySQL数据库与Redis缓存的数据一致性?


    什么是数据库与缓存的一致性?

    数据一致性?

    数据一致性是值:

    1)缓存中存有数据,并且该数据在缓存中的数据值=数据库中的数据值。

    2)缓存中没有该数据,那么数据库中的值=最新值。

    为什么会有一致性问题?

    在我们把Redis作为缓存的时候,如果数据需要更改,我们就得经过双写来保证缓存与数据库的数据一致性

    如果要保证强一致性的话,势必要引入2PC等分布式一致性协议,或者引入分布式锁等技术,但是这肯定也会对性能有影响,这也违背了我们使用Redis缓存的目的 -- 提高性能

    所以我们现在谈的数据库与缓存的一致性问题,该一致性其实指的就是最终一致性

    具体策略是什么?

    旁路缓存模式

    在使用缓存时,现在业务系统最常用的缓存策略是 Cache-Aside 模式(旁路缓存)。下面简单说一下该模式下的读写缓存实践。

    读缓存实践

    1)先读缓存,命中则返回;未命中则读数据库,然后再将该数据写入缓存。

    写缓存实践

    1)先写数据库,再操作缓存。

    2)直接删除缓存,而不是修改。

    值得注意的是,如果缓存的更新成本很高(如涉及访问多张表联合计算),建议直接删除缓存,而不是更新。当然也推荐直接删除缓存

    策略提升 -- 延迟双删

    在旁路缓存模式下,为了尽可能保证缓存与数据库的最终一致性,我们可以采用延迟双删策略

    延迟双删

    1)先删除缓存

    2)写数据

    3)休眠查询一次数据库的时间,再删除缓存。

    为什么要两次删除缓存?

    在进行第二步写数据的时候,在高并发场景下,很有可能有另一个线程此时在数据库中读取将要删除的数据,而我们第一步已经把缓存删掉了,所以该线程会将读取的脏数据写入缓存,以致于缓存中存入的是脏数据。

    第二次删除缓存失败咋办?

    为了保证第二次删除缓存成功,我们可以采用重试机制,比如重试3次,如果3次都失败的话则记录日志到数据库并通知人工介入。如果在高并发场景下,重试最好采用异步方式,比如发送消息到MQ中间件,实现异步解藕。

    但是引入中间件的话就会对业务代码造成侵入。于是可以采用下一个方案 -- 启动一个专门订阅数据库binlog的服务,用来读取需要删除的数据,然后进行缓存删除操作。

    读取binlog异步删除

    该方案步骤:

    1)更新数据库

    2)数据库会把操作信息记录在binlog日志中

    3)使用canal订阅binlog日志来获取目标数据

    4)缓存删除系统获取canal里的数据,解析目标数据,尝试删除缓存

    5)如果缓存删除系统尝试删除缓存失败,则将消息发送到消息队列

    6)缓存删除系统重新从消息队列获取数据,再次执行删除操作。

    总结

    为了尽可能保证数据库与缓存的一致性,我们可以采用延迟双删策略,同时采用异步重试机制来防止第二次删除缓存失败。异步机制我们可以利用MQ消息中间件,或者利用canal订阅数据库binlog日志来监听写请求,然后删除对应数据缓存。

    我们没有办法做到强一致性,因为这是由CAP理论决定的,缓存系统适用的场景就是非强一致性的场景,所以它属于CAP中的AP。但是我们可以做到最终一致性。

    CAP:C是Consistency(强一致性),A是Availability(可用性),P是Partition tolerance(分区容错性)。在分布式系统中,该系统要么满足AP,要么满足CP,而满足CP的系统的性能一般不是很高。

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    leetcode 5229: 拼接数组的最大分数
    Golang 协程池 Ants 实现原理,附详细的图文说明和代码
    四.数组与切片
    如何建立用户关注与青睐的产品设计?
    小黑跟中老黑和阿黄吃了烤蚕蛹知了,喝了阿黄带来的茅台,耳机又莫名其妙第丢了逐渐减少内耗的leetcode之旅:714. 买卖股票的最佳时机含手续费
    QT 小知识随记
    免费文字转语音软件有哪些?这几款宝藏工具你值得拥有
    理解CSS的层叠性和继承性
    第5章-宏观业务分析方法-5.4-因子分析
    基于python tornado实现的简易图床
  • 原文地址:https://blog.csdn.net/NoviceZ/article/details/126505412