数据库和缓存的数据一致性 -20241124

问题描述

  • 一致性
    • 缓存中有数据,缓存的数据值=数据库中的值
    • 缓存中本没有数据,数据库中的值=最新值(有请求查询数据库时,会将数据写入缓存,则变为上面的"一致"状态)
  • "数据不一致":
    • 缓存的数据值≠数据库中的值;
    • 缓存或者数据库中存在旧值,导致其他线程读到旧数据。

应对策略

  • 把缓存分成读写缓存和只读缓存。
    • 只读缓存:只在缓存进行数据查找,即使用"更新数据库+删除缓存"策略。
      • 新增数据时,直接写入数据库;
      • 更新(修改/删除)数据时,先删除缓存。
      • 后续访问这些增删改的数据时,会发生缓存缺失,进而查询数据库,更新缓存
      • 文中提到无并发情况 下,若步骤二失败会有一致性问题。
        • 可以采用消息队列,异步重试。(多次失败后通知业务层)
        • 也可采用binlog变更日志,根据日志更新/删除缓存
      • 并发条件下
        • 先删除缓存,再更新数据库 (其他线程在缓存为空时访问数据库获得旧值,顺便将缓存更新了,造成缓存中的值在A线程完成更新数据库后也不再更新)
          • 设置缓存过期时间。淘汰缓存失败时,过期后,读请求从db中获取数据,并更新缓存。(?删除缓存可能会失败,设置超时时间就保证能成功了?)
          • 延迟双删:更新完数据库后,等待一段时间(使确保其他线程能读到修改后的值),再删除缓存
        • 先更新数据库,再删除缓存 (线程B读到旧值,?感觉问题不大;若有从库,会尝试去从库拿?,由于主从库的延迟,造成缓存中保存的是从库中的旧值)
          • 延迟消息:发送删除缓存的消息到队列,延迟处理。如有必要,考虑主从数据库延迟
          • 通过数据库的binlog来异步删除缓存
          • 先更新数据库再删除缓存,有可能导致请求因缓存缺失而访问数据库,给数据库带来压力,也就是缓存穿透的问题。针对缓存穿透问题,可以用缓存空结果、布隆过滤器进行解决
          • 加锁:更新数据时,加写锁;查询数据时,加读锁
    • 读写缓存 :需要在缓存中对数据进行增删改查,即使用"更新数据库+更新缓存"策略
      • 同步直写:使用事务,保证缓存和数据更新的原子性,并进行失败重试
      • 异步回写:写缓存时不同步写数据库,等到数据从缓存中淘汰时,再写回数据库
    • 重点考虑更新数据库和缓存的顺序,读写还是读读
      • 对于读写场景,延迟消息比较,发现不一致后,做业务补偿(加延迟时间?)
      • 对于,写写场景,配合分布式锁处理。对于同一资源的操作,需要获取分布式锁,未获得锁的放在队列中。

总结

  • 数据库和缓存存在不一致性,部分原因是因为数据库和缓存是独立的两部分。从设计上可能做了适配,但是总归有配合问题。如果数据库本身在设计上就考虑设计高并发缓存,我们在使用时就不用考虑一致性问题或者性能问题。
    • 如人为设置一个等待时间,在数据库应该能完成数据更新的时,进行缓存的删除。如果数据库与缓存是一体的,可能在内部就能完成,数据库完成删除后通知缓存更新。这样效率肯定比外界干预的两部效率要高
  • 性能和准确性的取舍在因场景而异,我们只能采用该架构下我们认知中,在该场景下,在有限的时间内能够完成的最优方案。

参考:https://cloud.tencent.com/developer/article/1888803

相关推荐
Olrookie6 分钟前
MySQL运维常用SQL
运维·数据库·sql·mysql·dba
数据库生产实战16 分钟前
ORACLE 19C ADG环境 如何快速删除1.8TB的分区表?有哪些注意事项?
数据库·oracle
blackorbird33 分钟前
使用 Overpass Turbo 查找监控摄像头
运维·服务器·数据库·windows
IT永勇37 分钟前
SQLite数据库基本操作
数据库·sqlite·嵌入式开发·增删改查·关系型数据库
洋不写bug39 分钟前
数据库的创建,查看,修改,删除,字符集编码和校验操作
android·数据库·adb
想ai抽1 小时前
吃透大数据算法-算法地图(备用)
大数据·数据库·spark
weixin_307779131 小时前
Clickhouse导出库的表、视图、用户和角色定义的SQL语句
开发语言·数据库·算法·clickhouse·自动化
流星白龙1 小时前
【Qt】7.信号和槽_connect函数用法(1)
开发语言·数据库·qt
码界奇点1 小时前
平替MongoDB金仓多模数据库在电子证照国产化中的实践与优势
数据库·mongodb·社交电子·里氏替代原则
optimistic_chen1 小时前
【Java EE进阶 --- SpringBoot】Mybatis操作数据库(基础二)
xml·数据库·spring boot·笔记·java-ee·mybatis