解决数据库和缓存数据不一致情况:延迟双删
2021-07-19 13:45
459 查看
在高并发的场景下,数据库处理数据增删改查很是薄弱。有一些数据查询的频率远大于修改频率,就需要使用缓存技术,让先去请求redis,redis存在返回缓存数据,redis不存在就查询数据库,返回数据的同时将数据缓存到redis中。
问题
读取缓存一般没有什么问题,一旦涉及到数据更新:数据库或者缓存更新,就容易出现缓存和数据库数据不一致情况。首先,数据“一致性”包含两种情况:
- 缓存有数据,那么缓存的值和数据库中的值相同。
- 缓存没有数据,那么,数据库中的值必须是最新值。
在高并发的情况下,不管是先写数据库,再删缓存;还是先删缓存,再写数据库,都有可能出现数据不一致的情况,比如:
- 如果删除了缓存redis,还没来得及写库mysql,另一个线程就读取,发现缓存为空,则去数据库读取数据写入缓存,此时缓存中的数据为脏数据。
- 如果写了库,在删除缓存前,写库的线程宕机了,也会出现数据不一致的情况。
解决办法
延迟双删策略
1、先删除缓存 2、再写数据库 3、休眠500ms(根据统计线程读取数据和写缓存的时间) (休眠的作用是当前线程等其他线程读完了数据后写入缓存后,删除缓存) 4、再删除缓存
设置缓存过期时间
总结
先清除缓存,然后再写入数据库。有可能存在删除缓存以后,另一个线程读取数据,发现没有数据,就去数据读取数据,然后写入缓存中,此时缓存中的数据为脏数据; 解决办法:
- 先删除缓存
- 再写入数据库
- 休眠500ms
- 删除缓存 其中第三步骤的500ms,是根据业务读取数据平均耗时,这样做的目的是确保读请求可以结束,写请求可以删除读请求造成的脏数据的问题。
相关文章推荐
- 解决主从复制数据不一致的情况
- 并发情况下修改数据对缓存的影响及解决办法
- C#解决串口通信中接收数据时延迟处理与缓存处理的方法
- 淘宝TOP API 缓存实战 解决API频率过高,页面空白,调用不到数据等情况
- 数据库数据不一致解决思路
- 解决Hibernate自动创建数据库时出现“创建不了数据库的表和向其中插入数据的情况”
- Hibernate spring 整合数据只存在缓存而没有提交给数据库的解决办法
- 备份SQLserver数据时候出现还原数据库和“XX”数据库不一致解决
- 如果缓存中的数据和数据库中的数据不同步的情况下,怎么样把缓存中的数据同步到数据库中?
- Vue中解决数组在被清空的情况下,页面仍会存在缓存数据的问题
- C#解决串口通信中接收数据时延迟处理与缓存处理的方法
- 使用Sqoop,最终导入到hive中的数据和原数据库中数据不一致解决办法
- 多线程模拟高并发情况redis 与数据库缓存不一致
- php中,从数据库中读取数据后,出现乱码的情况及解决方法
- 解决项目中由于前端页面数据类型跟数据库类型不一致,导致获取数据为空引起问题
- 为什么要引入锁(无论什么数据库软件引入锁的目的都是因数据不一致的三种情况,这里介绍的是MS-SQLSERVER )
- 在Oracle中IMP导入数据时,如何解决目标数据库字符不一致问题
- 用oralce连接.net客户端出现问题:“数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位Oracle客户端组件的情况下以64位模式运行,”的解决办法
- 并发数据库事务缺锁导致的数据不一致情况:丢失更新,脏读,不可重复读,幻读
- 数据泵导入导出,解决数据库版本不一致,导致一些空表导入不了