Redis双写一致性
缓存和数据库数据同步
正常流程:
读操作:
查询缓存,查询命中直接返回,没命中查询数据库将查询到的数据写入缓存,并设定超时时间
写操作:
删除缓存,修改数据库,在延时一段时间后再删除缓存
(延迟双删)延迟:等待数据库的主节点同步到从节点
因为如果先删除缓存
在更新数据库之前有另一个线程对数据库做了查询,就会将还未更新的数据写入缓存,导致与数据库的不一致性
如果先更新数据库
在一个线程查询缓存未命中准备写入缓存的过程中,另一个线程对数据库做更新并删除缓存,原本那个线程继续完成的写入缓存数据会和数据库不一致
一致性要求高的情况
使用分布式锁(性能低)
共享锁:
读锁readlock,加锁后,线程可以共享读操作但不能共享写操作
排它锁:
独占锁writelock,加锁后,线程会阻塞其他线程的读写操作
允许延迟一致
异步通知保证数据一致
通过mq来进行缓存和数据库之间的数据通知
或者使用Canal来实现异步通知
基于mysql的主从同步实现,将mysql的DDL和DML操作记录到文件中,canal伪装成mysql的一个从节点对文件进行监听和对缓存进行通知