缓存设计的典型方案

缓存设计的典型方案

在使用缓存系统的时候,还需要考虑缓存设计的问题,重点在于缓存失效时的处理和如何更新缓存。

缓存失效是在使用缓存时不得不面对的问题。在业务开发中,缓存失效时由于找不到整个数据,一般会出于容错考虑,从存储层再进行查询,如果有则放入缓存。如果查找的数据在存储层根本就不存在,缓存失去意义,还会给后端服务带来巨大的请求压力,会进一步引起雪崩效应。这种现象又被称为缓存穿透。

目前常用的解决缓存穿透问题的方案如下。

1)在底层存储系统之上加一层布隆过滤器,将所有可能存在的数据哈希到一个足够大的BitMap中,一个一定不存在的数据会被这个BitMap拦截掉,从而避免了对底层存储系统的查询压力。

2)如果数据在存储层查询也为空,那么对此空结果也进行缓存,但要设置合适的失效时间。

更进一步地,解决缓存穿透问题其实和缓存的更新机制是相关的。缓存更新的常用3种模式如下。

Cache Aside Pattern:应用程序以数据库为准,失效则从底层存储更新,更新数据先

写入数据库再更新缓存。这是最常用的缓存更新模式。

Read/Write Through Pattern:以缓存为准,应用只读/写缓存,但是需要保证数据

同步更新到数据库中。

Write Behind Caching Pattern:以缓存为准,应用只读/写缓存,数据异步更新到数据库,不保证数据正确写回,会丢数据。可以采用Write Ahead Logging等机制避免丢数据。

如上,在缓存失效时采用何种策略去更新缓存,直接决定了能否解决缓存穿透的问题。Cache Aside Pattern 中缓存失效从底层存储更新,无法避免缓存穿透的问题。基于以上3种模式,采用下面更为细化的更新机制可以在一定程度上避免缓存穿透的问题。

缓存失效时,用加锁或者队列的方式单线程/进程去更新缓存并等待结果。

。缓存失效时,先使用旧值,同时异步(控制为同时只有一个线程/进程)更新缓存.

缓存更新失败则抛出异常。

.缓存失效时,先使用旧值,同时异步(控制为同时只有一个线程/进程)更新缓存,

缓存更新失败则延续旧值的有效期。

.数据写入或者修改时,更新数据存储后再更新缓存。缓存失效时即认为数据不存在。.数据写人或者修改时,只更新缓存,使用单独线程周期批量刷新缓存到底层存储。缓存失效时即认为数据不存在。这种方案不能保障数据的安全性,有可能会丢数据。、采用单独线程/ 进程周期将数据从底层存储放到缓存中。缓存失效时即认为数据不存在。这种方案无法保证缓存数据和底层存储的数据强一致性。

如果一开始设计缓存结构的时候注意切分粒度,把缓存力度划分得细一点,那么缓存

命中率相对会高,也能在一定程度上避免缓存穿透的问题。

此外,还可以在后端做流量控制、服务降级或者动态扩展,以应对缓存穿透带来的访

问压力。

相关推荐
大猫子的技术日记14 小时前
[百题重刷]前缀和 + Hash 表:缓存思想, 消除重复计算
java·缓存·哈希算法
愤怒的山羊15 小时前
jetcache List 缓存, json 序列化 泛型解析成了 JsonObject 处理
缓存·json·list
树在风中摇曳15 小时前
带哨兵位的双向循环链表详解(含 C 代码)+ LeetCode138 深度解析 + 顺序表 vs 链表缓存机制对比(图解 CPU 层级)
c语言·链表·缓存
斯文~19 小时前
「玩透ESA」站点配置阿里云ESA全站加速+自定义规则缓存
阿里云·缓存·云计算·cdn·esa
S***t71419 小时前
Python装饰器实现缓存
缓存
天硕国产存储技术站20 小时前
3000次零失误验证,天硕工业级SSD筑牢国产SSD安全存储方案
缓存·固态硬盘·国产ssd
前端炒粉1 天前
35.LRU 缓存
开发语言·javascript·数据结构·算法·缓存·js
努力发光的程序员1 天前
互联网大厂Java面试:从Spring Boot到微服务架构
spring boot·缓存·微服务·消息队列·rabbitmq·spring security·安全框架
zero13_小葵司1 天前
JavaScript性能优化系列(八)弱网环境体验优化 - 8.3 数据预加载与缓存:提前缓存关键数据
javascript·缓存·性能优化
CS_浮鱼1 天前
【Linux进阶】mmap实战:文件映射、进程通信与LRU缓存
linux·运维·c++·缓存