网站建设运营维护合同,做任务的设计网站,私人制定网站,作业网站的设计制作案例Redis作为缓存#xff0c;mysql的数据如何与redis进行同步#xff1f;
一定要设置前提#xff0c;先介绍业务背景
延时双删
双写一致性:当修改了数据库的数据也要同时更新缓存的数据#xff0c;缓存和数据库的数据要保持一致 读操作:缓存命中#xff0c;直接返回;缓存未…Redis作为缓存mysql的数据如何与redis进行同步
一定要设置前提先介绍业务背景
延时双删
双写一致性:当修改了数据库的数据也要同时更新缓存的数据缓存和数据库的数据要保持一致 读操作:缓存命中直接返回;缓存未命中查询数据库写入缓存设定超时时间写操作:延时双删
问题来了那么先删除数据库还是先删除缓存呢我们都分析一下这里只分析异常情况 先删除缓存再删除数据库。假设我们有缓存数据A10和数据库数据A10 线程1先删除缓存此时线程2查询缓存未命中查询数据库A10然后写入缓存线程1然后更新数据库A20此时数据不一致了缓存A10数据库A20 先操作数据库再删除缓存假设我们有缓存数据已经过期和数据库数据A10 线程1先查询缓存此时因为我们假设的缓存数据已经过期查询数据库A10还没来得及写入缓存线程2更新数据库A20然后删除缓存此时没有缓存删不删没关系线程1写入缓存此时数据不一致了缓存A10数据库A20
我们发现这两种都会导致脏数据的出现所以删除两次缓存就出现了。这就是延时双删删除缓存-修改数据库-延迟一会删除缓存就是为了降低脏数据的出现那为什么要延时呢因为一般情况下数据库是主从模式我们要延时一会让数据库主节点同步到从节点再删除缓存。但是也会有小问题因为延时的时间不好把控。所以做不到绝对的强一致。
分布式锁
那有更好的办法吗我们可以使用分布式锁来解决这个问题 但是这个显然效率有点太低了我们可以优化一下
一般缓存数据都是读多写少我们可以使用读写锁控制
共享锁:读锁readLock加锁之后其他线程可以共享读操作排他锁独占锁writeLock也叫加锁之后阻塞其他线程读写操作
这样性能就得到了提升虽然实现了强一致但是性能还是有点低
异步通知保证数据最终一致 最终一致性的保证主要取决于MQ的可靠性
基于Canal的异步通知 canal是阿里开发的中间件主要是基于mysql的主从同步实现的
二进制日志(BNLOG)记录了所有的DDL (数据定义语言)语句和DML(数据操纵语言)语句但不包括数据查询(SELECT、SHOW语句。
优点无代码侵入
总结
允许延时一致的业务采用异步通知 使用MQ中间中间件更新数据之后通知缓存删除利用canal中间件不需要修改业务代码伪装为mysql的一个从节点,canal通过读取binlog数据更新缓 存强一致性的采用Redisson提供的读写锁 共享锁:读锁readLock加锁之后其他线程可以共享读操作排他锁 存强一致性的采用Redisson提供的读写锁 共享锁:读锁readLock加锁之后其他线程可以共享读操作排他锁独占锁writeLock也叫加锁之后阻塞其他线程读写操作