Redis的缓存更新策略

1.定期生成:

核心逻辑:

按照固定的时间间隔(比如每个小时,每天)批量生成或者更新缓存,而非依赖实时数据变更触发。

实现方式:

定期任务触发:

写一套离线流程(使用shell,python写脚本代码),然后定期缓存更新。

全量/增量更新:

全量:每次生成所有的缓存数据,覆盖原来的数据。

增量:仅更新上次更新后发生变化的缓存数据。

优点和缺点:

优点:实现简单,过程可控,方便排查问题。

缺点:实时性差,因为是定期更新,会有无效更新的情况,比如缓存数据没有变化还是会更新。

2.实时生成:

核心逻辑:

数据一旦发生变化(数据库更新),缓存数据就会更新或者失效,确保了缓存和数据源的一致性。

一段时间后,redis的key都会是一些热点数据。这样不停地写会导致redis的内存占用越来越多。(逐渐达到内存上限,不一定是机器内存上限,可能是redis配置的内存上限)

然后就有了内存淘汰策略。(经典面试题)

内存淘汰策略:

FIFO(First In First Out)先进先出:

把缓存中存在时间最久的(也就是先来的数据)淘汰掉。

LRU(Least Recently Userd)淘汰最久未使用的:

记录每个key最近访问的时间,把最近访问时间最久 的key淘汰掉。

LFU(Least Frequently Userd)淘汰访问次数最少的:

记录每个key最近一段时间的访问次数,把访问次数最少的淘汰掉。

Random随机淘汰:

从所有的key中随机抽取进行淘汰。

缓存预热:

服务启动或者缓存重新启动时,缓存中可能没有数据,此时所有用户请求会直接穿透到数据库。

数据库可能因为瞬间高并发导致被压垮(特别是一些量大的系统)。

用户体验极差(请求响应时间从毫秒级到秒级别)

缓存预热是通过"提前在缓存中加载一些热点数据",让服务启动后缓存命中率迅速提高,数据库承担的请求压力就会变小。

缓存穿透:

缓存穿透是指:查询某个key时,这个key既没有在redis中,也没有在MySQL中,导致每次请求都会直接穿透缓存,直接访问数据库,如果查询大量这样的key(如黑客的恶意攻击),就会导致数据库压力骤增,甚至导致数据库宕机。

缓存穿透的核心原因:

1.业务逻辑导致无效请求:比如代码中缺少参数校验环节,到时非法的key也能进行查询。

2.黑客的恶意攻击。

3.比如运维和开发误操作:不小心把部分数据从数据库中删除了。

缓存穿透的解决方案:

方案一:缓存空值:

当我们查询一个key时,这个key如果在redis和mysql中都不存在,那么就把它存入redis中并设置一个ttl(过期时间),value设为null。后续相同的请求就会返回null,无需访问数据库。

**优点:**实现简单,无需外部依赖,可以快速拦截非法请求。

缺点:

1.占用缓存空间。(大量空的key会浪费内存)

2.在ttl时间内,如果当前key重新存在了,但仍然返回null,那么就需要等到ttl到了,才能继续设置。(比如商品下架但是又上架了);解决方法:可以ttl为5-30s(平衡内存使用和数据实时性),还可以给空值key加上一个特定的前缀。

方法二:布隆过滤器:

在缓存前加一个布隆过滤器,提前过滤"一定不存在的数据",布隆过滤器是一种空间效率极高的概率性数据结构,能判断一个key是否可能存在于数据源中(存在误判,但不存在漏判)

实现步骤:

需要提前初始化布隆过滤器:将数据中有效的数据key提前导入到布隆过滤器中。

拦截请求:先要通过布隆过滤器,如果布隆过滤器判断这个key不存在,直接返回空结果,不会访问缓存和数据库;但是布隆过滤器判断这个key可能存在,就需要再次访问缓存和数据库。

**优点:**内存占用率极低,查询速度也很快

**缺点:**存在误判,当新增数据时,需要更新布隆过滤器,实现难度较大。

缓存雪崩:

缓存雪崩:在某一时刻,Redis中大量缓存的key同时过期或者Redis集群整体不可用,导致缓存的命中率陡然下降,数据库的压力陡然上升,甚至直接宕机。

核心原因:

1.大量的key同时过期。因为设置了相同的过期时间。一旦到期会同时失效,请求全部打向数据库。

2.Redis的集群故障:因网络中断、服务器宕机、内存耗尽等原因,Redis 集群整体不可用,所有请求被迫直接访问数据库。

解决方案:

1.避免key集中过期,为缓存key设置随机过期时间(base_ttl+random(0-300ms)),避免集中过期。

2.部署哨兵+主从模式,确保单点故障后自动切换。

3.服务降级和熔断:当数据库压力超过阈值时,暂时拒绝部分请求(返回空或者返回错误提示)

4.多级缓存兜底:增加本地缓存,作为Redis的二级缓存,减少数据库访问。

缓存击穿:

缓存击穿:某一个热点的key突然过期了,恰好有大量并发请求访问这个key,导致所有请求穿透到数据库,导致数据库压力骤增,甚至宕机。

解决办法:

1.基于统计的方式,设置热点key永不过期。

2.当缓存未命中时,先尝试获取分布式锁,然后只有获取到锁的请求才能查询数据库,其他请求等待重试,限制同时请求数据库的并发数。

3.提前预热+扩咱过期时间。

相关推荐
需要826几秒前
缓存与数据库一致性:延迟双删与订阅 binlog 的取舍
数据库·缓存
CV工程师丁Sir4 小时前
ArkWeb 手记 04|DevTools 调试与缓存清理
java·spring·缓存·harmonyos
志尊宝11 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
禾小西12 小时前
Redis:从两大维度和三大主线建立知识体系
数据库·redis·缓存
进击的横打19 小时前
【人工智能】缓存命中率:从原理到业务场景的全面解读
人工智能·缓存
change_fate21 小时前
升级依赖后,vite会自动重建缓存吗
缓存
饺子大魔王的男人21 小时前
LitePan多网盘影音中枢:WebDAV挂载、STRM生成与缓存管理
缓存·dubbo
我不会起名字3221 天前
Redis 缓存与数据库一致性:先删缓存还是先更新库的 4 种方案
数据库·redis·缓存·一致性·延迟双删
@#¥&~是乱码鱼啦1 天前
ArkWeb开发手记02|权限、网络白名单与页面缓存控制
网络·缓存
拾贰_C2 天前
【English | conversation 】call | 抖音AI短句情景:打电话---come over
数据库·redis·缓存