Redis缓存更新策略

2022/6/16 2:20:17

本文主要是介绍Redis缓存更新策略,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

为什么需要缓存更新?

使用缓存后,数据可能同时保存在数据库与缓存当中。如果数据库的数据改变,而缓存中的数据没有改变,就会导致数据不一致的问题。

常见的缓存更新策略

内存淘汰 超时剔除 主动更新
概述 redis自带的内存淘汰机制,当内存不足时自动淘汰部分数据 手动给缓存的数据添加TTL时间,到期后自动删除 编写业务逻辑,更新数据库数据后同步更新缓存
解决数据一致性的问题 一般
使用成本

关于内存淘汰机制解决数据一致性:
若只依靠内存淘汰机制,可能会出现这种问题:内存淘汰机制一直未执行,所以缓存中的数据一直未更新,而数据库中的数据已经改变。

不同策略合适的业务场景:

  • 低一致性需求:就是数据长久不会发生变化的情况下,使用内存淘汰机制。例如查询店铺类型缓存。
  • 高一致性需求:使用主动更新策略,并使用超时剔除作为兜底方案。例如查询店铺详情。

主动更新

 主动更新目前我了解的三种实现方法:

  1. 由缓存的调用者,在更新数据库时同时更新缓存
  2. 将缓存与数据库整合为一个服务,由服务来维护一致性,调用者无需关心缓存一致性问题
  3. crud在缓存中进行,由其他线程异步的将缓存数据持久化到数据库。

三种方法中,个人认为最好的就是第一种,实现简单且能较好的解决数据一致性问题。但是在同时操作数据库和缓存时,有以下三个问题

  • 删除缓存还是更新缓存?

    更新缓存:每次更新数据库都要更新缓存,会增加写操作,很可能会写多读少,消耗资源来进行无效写操作。

    删除缓存:更新数据库时,让缓存失效,当再次查询时再更新缓存。

  • 如何保证缓存与数据库的操作同时成功或失败?(原子性问题)

    单体系统:将缓存和数据库放在同一个事务中

    分布式系统:利用TTC等分布式事务方案

  • 先操作缓存还是先操作数据库?(线程安全问题)

假设缓存中有数据v=10,现在修改了v=20。分别以两种操作方式来讨论:


先删缓存再操作数据库:

理想情况:

 1. 线程1删除缓存

 2. 线程1数据库更新数据v=20

 3. 线程2查询数据,缓存未命中

 4. 线程2将数据库中的v=20写入缓存

异常情况:

 1. 线程1删除缓存,线程1结束

 2. 线程2查询数据未命中

 3. 线程2从数据库读取v=10写入缓存

 4. 线程1更新数据库数据v=20

image-20220609213929170

数据库数据和缓存数据不一致,发生概率高,因为redis操作数据库快,而数据库操作慢


先操作数据库再删除缓存:

理想情况:

image-20220609214856891

异常情况:

 1. 缓存中的数据失效

 2. 线程1查询缓存未命中,查询数据库,将v=10传递给用户,线程1结束

 3. 线程2更新数据库,v=20写入数据库

 4. 线程2删除缓存,但是这个缓存已经是失效的了,线程2结束

 5. 线程2写入缓存v=20

image-20220609215204164

这种情况发送的较少,需要以下条件:

  • 两个线程并行执行
  • 线程1查询时,恰好缓存失效
  • 线程1写缓存时,恰好切换到了线程2
  • 线程2恰好更新数据库

两种情况都可能会发生线程安全问题,但是先操作数据库再操作缓存这种方案发生线程安全的可能性更小。

总结:

image-20220609220731446



这篇关于Redis缓存更新策略的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程