redis和mysql双写一致的问题?
作者:互联网
一致性分为数据一致性和事务一致性的情况:
现在说的是数据一致性的情况
复制是导致出现数据一致性问题的唯一元婴
强一致性:也叫线性一致性,除此之外其他的一致性都是弱一致性的特殊情况,所谓强一致性,即复制是同步的,弱一致性即复制异步的
在实践中通常是使得从库是同步的,而其他的则是异步的,但是如果这个同步的从库出现问题,则使另一个异步从从库中同步,这可以确保永远有两个节点拥有完整的数据:主库和同步从库,这种配置叫半同步
最终一致性:
容忍节点故障只是需要复制的一个原因,另外的两个原因是可扩展性和降低延续。
当用户异步从库读取时,如果此异步从库落后,他可能会看到过时的信息,这种不一致只是一个状态如果等待一段时间,从库最终会赶上并与主库保持一致,这被称作最终一致性
强一致性:这种一致性级别是最符合用户直觉的,他要求系统写入什么,读出来的也会是什么,
弱一致性:是指不承诺立即可以读写入的值,也不承诺多久之后数据能够达到一致的状态,但会尽可能地保证到某个时间级别后,数据能够达到一致性地状态
最终一致性:是弱一致性的特列,系统会保证在一定时间内,能够达到一个数据的一致性状态,所以在这里将最终一致性提出来。
三个经典的缓存模式
cache-aside-pattern:旁路缓存模式
读操作按照上面
写操作
写操作可能会出现数据不一致的情况在高并发下
Read-Through/Writer-Through(读写穿透)模式中,服务端把缓存作为主要数据存储,应用程序跟数据库缓存交互,都是通过抽象缓存层完成的
Read-Through模式下,当发生写请求时,也是由抽象层完成数据源和缓存数据的更新,流程如下
Writer behind(异步缓存写入):与上面的两者有相似的地方,都是由cache provider来负责缓存和数据库读写,但是与上面的Read/Writer Through时同步更新缓存和数据的,Write Behind则只是更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库
这种方式下,缓存和数据库的一致性不强,对一致性高的系统要谨慎使用,但是他适合频繁写的操作,比如Mysql的InnoDB buffer pool机制
操作缓存的时候,是删除缓存还是先更新缓存呢,
使用更新缓存会出现数据不一致的情况
为什么是先操作数据库,后操作缓存呢
如果一定要操作缓存可以采用延迟双删的策略
1、先删除缓存
2、更新数据库
2.1、休眠一下(时间由具体业务场景来定)
3、再删除缓存
为什么需要延迟双删?
一、只先删除缓存
先删除缓存,在改库之前,其他事务又把旧的数据放到缓存中去了
二、只后删除缓存
改了库,清理缓存之前,有部分事务还是会拿到旧的数据
三、普通双删:
第一次清空缓存后、更新数据库之前:其他事务查询了数据库
第二次清空缓存后:其他事务更新缓存,此时又会把旧数据更新到缓存
四、为什么需要延迟双删?
是为了确保修改数据库->清空缓存前,其他事务的更改缓存操作已经执行完毕了
五、但是依然存在问题
采用延迟双删最后一次缓存,但是这其中难免还是会大量的查询到旧缓存的数据
这个时候可以通过加锁来解决这个问题
之后再详细说
标签:异步,缓存,数据库,redis,更新,mysql,一致性,从库,双写 来源: https://www.cnblogs.com/stored/p/15361002.html