数据库与缓存最终一致性方案——延迟双删技术

在实际开发中,我们常常会遇到这样的问题:数据库更新后,Redis 缓存数据与之不一致。虽然有多种解决方案,但并没有一种完美适配所有场景的方案。今天,我们就来深入探讨一种实用性较强的方案 —— 延迟双删。

常用缓存策略

在说正题之前,先介绍一下前置依赖,也就是缓存策略。

以下是一些常用的缓存策略:

缓存旁置(Cache-Aside)

  • 基本思想 :在查询数据时,先查询缓存,如果缓存中有数据(缓存命中),直接返回缓存数据;如果缓存中没有数据(缓存未命中),则从数据库查询数据,将查询结果写入缓存,再返回数据。
  • 优点 :缓存和数据库解耦,缓存系统和数据库系统相互独立,一个系统挂掉不影响另一个系统的使用。
  • 缺点 :可能出现缓存与数据库数据不一致的情况,如在写数据库后删除缓存的过程中,有请求查询缓存,此时缓存还没有更新,就会读取到旧数据。

缓存贯穿(Read-Through)

  • 基本思想 :查询缓存未命中时,由缓存服务器自动从数据库加载数据,并将数据缓存起来,之后的请求可以直接命中缓存。
  • 优点 :对调用方来说,查询逻辑简单,直接查询缓存即可,无需关心数据加载逻辑。
  • 缺点 :缓存服务器与数据库耦合度高,缓存系统复杂度增加;数据更新时需要考虑缓存更新策略,避免缓存污染。

写直达(Write-Through)

  • 基本思想 :写数据时,数据同时写入缓存和数据库,确保缓存和数据库的数据一致性。
  • 优点 :能确保缓存和数据库的数据一致性。
  • 缺点 :写操作的性能会受到影响,因为需要同时写两个系统;缓存和数据库的写操作任何一个失败,都会导致数据不一致。

缓存更新策略

  • 覆盖更新 :在缓存中更新数据,直接覆盖旧数据。
  • 回写更新 :先在缓存中记录更新操作,待数据操作完成后再写回数据库,异步更新缓存。
  • 写入数据库后删除缓存(延迟双删) :更新数据库后,先删除缓存,等待短暂时间后再次删除缓存,防止缓存污染。

缓存数据失效策略(TTL)

  • 基本思想 :设置缓存数据的过期时间,当缓存数据超过设定的过期时间后,缓存数据失效。
  • 优点 :简单易行,能有效避免缓存数据长期未更新导致的数据不一致。
  • 缺点 :需要合理设置过期时间,过短的过期时间会导致缓存命中率低,过长的过期时间可能导致数据不及时。

延迟双删的技术方案,实际是采用缓存旁置(Cache-Aside)策略前提下,来提升数据一致性的技术方案。

延迟双删的背景

在高并发的业务场景下,缓存击穿、缓存雪崩等问题频发。此时,若按照传统的 “先更新数据库,再删除缓存” 或 “先删除缓存,再更新数据库” 的方式,很容易出现缓存与数据库数据不一致的情况。

例如,当一个请求先删除了缓存,再更新数据库,但在这两个操作之间,有另一个请求查询缓存,发现缓存不存在,就会从数据库读取旧数据并重新写入缓存,这样就导致了缓存数据与数据库更新后的数据不一致。

延迟双删的原理

延迟双删的核心思想是在更新数据库后,先删除一次缓存,然后等待一定时间,再次删除缓存,以确保缓存在数据库更新期间不会被旧数据污染。

具体操作步骤如下:

  1. 删除 Redis 缓存中的对应数据。
  2. 更新 数据库中的数据。
  3. 等待预设的短暂时间(例如 500 毫秒)。
  4. 再次删除 Redis 缓存中的对应数据。

通过这种方式,可以最大限度地保证缓存数据与数据库数据的一致性。

延迟双删的实现

以下是延迟双删的伪代码示例:

// 删除缓存
redis.delKey(key);
// 更新数据库
db.update(key, value);
// 等待一段时间,让数据库操作完成
Thread.sleep(500);
// 再次删除缓存
redis.delKey(key);

延迟双删的优缺点

优点

  1. 提高数据一致性 :通过两次删除缓存的操作,有效降低了缓存与数据库数据不一致的风险。
  2. 实现简单 :相较于其他复杂的数据一致解决方案,延迟双删的实现相对简单,易于理解和维护。

缺点

  1. 延时时间难以确定 :延时时间的设置需要根据具体业务场景进行调整,如果设置过短,可能无法有效避免数据不一致;如果设置过长,又会增加系统的延迟。
  2. 并发问题 :在高并发环境下,延迟双删可能无法完全避免数据不一致的问题。例如,在延时期间可能会有新的请求写入缓存,导致第二次删除缓存时将新数据删除。
  3. 实现复杂度增加 :需要额外的线程或定时任务来处理延时操作,这增加了系统的复杂度。

延迟双删的适用场景

延迟双删适用于对最终一致性要求较高但能容忍一定延迟的场景。例如,在一些对实时性要求不高的业务系统中,如电商的商品详情页缓存、新闻资讯类应用的内容缓存等,都可以考虑使用延迟双删策略来保证数据的一致性。

其他解决方案对比

  1. 先更新数据库,再删除缓存 :这种方式在读操作较少的场景下效果较好,但如果读操作频繁,仍然可能出现缓存与数据库数据不一致的情况。
  2. 先删除缓存,再更新数据库 :这种方式容易导致在缓存删除后、数据库更新前,其他请求将旧数据写入缓存的问题。
  3. 消息队列异步更新 :通过消息队列来解耦数据库和缓存的更新操作,也可以保证数据的最终一致性,但会增加系统的复杂度和延迟。
  4. Canal 监控 Binlog :利用 Canal 监控 的 Binlog 日志,实现准实时更新 Redis 缓存,保证数据一致性,但需要额外的运维成本和资源消耗。

总结

延迟双删策略是一种简单有效的缓存与数据库数据一致性解决方案。虽然它存在一些局限性,但在特定场景下仍然具有较高的实用价值。在实际应用中,我们可以根据业务需求和系统特点,灵活选择和组合不同的解决方案,以达到最佳的效果。

以上就是业务数据缓存延迟双删技术方案的全部内容。希望通过本文的介绍,能够帮助你更好地理解和应用这一技术方案。

注意,这是一个被面试玩坏了的问题,实际上,如果要保持强一致性,则必须采用锁机制,不可能避免的影响并发和系统的可用性。延迟双删技术方案相对简单,实用性强,但并不是完美的解决方案,最大程度上保证缓存与数据库中的数据一致,并且业务上可以接受最终一致性。

如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~

请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行者无疆1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值