缓存整理
2020-12-01 11:11:38 20 举报
AI智能生成
缓存知识整理
作者其他创作
大纲/内容
缓存整理
存储
外存
持久化
硬盘,U盘,软盘等
获取数据慢,IO存取比较耗时
内存
机器重启,数据消失
数据读取速度快
定义
将外存的数据放到内存上的载体。通常使用map来进行缓存
是一种空间换时间的思想
示例
CPU的一级二级缓存
maven加载依赖的顺序,先本地仓库,然后本地服务器参考,最后去远程仓库查找
数据库的索引
京东仓储
指标
缓存命中率
从缓存读取数据的次数/总读取次数的比率,越高越好
总读取次数=从缓存读取次数+从慢速设备读取的次数
移除策略
在缓存满的时候,移除缓存的策略
策略
FIFO
先进先出,最先放入缓存的数据被移除
LRU
最久未使用,使用时间距离现在最久的数据被移除
LFU
最近最少使用,一定时间内使用次数最少的数据被移除
TTL
存活期,数据从缓存中创建的时间点到它到期的一个时间段
TTI
空闲期,一个数据多久没被访问则从缓存中删除的时间
Java中的实现
基于注解
Spring Cache 并非具体的缓存技术,而是基于各种缓存产品(如 Guava、EhCache、 Redis 等)共性进行的一层封装,让用户更加专注于应用层面。 具体的底层缓存技术究竟采用了 Guava、EhCache 还是 Redis,只需要简单的配置就 可以实现方便的切换。
主要接口
org.springframework.cache.Cache: 缓存本身
org.springframework.cache.CacheManager: 对缓存的处理和管理
使用
声明缓存
@Cacheable(\"books\")public Book findBook(ISBN isbn) {...}
用法很简单,在方法上添加@cacheable 等注解,表示缓存该方法的结果。 当方法有被调用时,先检查 cache 中有没有针对该方法相同参数的调用发生过,如果有, 从 cache 中查询并返回结果。如果没有,则执行具体的方法逻辑,并把结果缓存到 cache 中。当然这一系列逻辑对于调用者来说都是透明的。
开启Spring的Cache功能
<cache:annotatiion-drivenn />
@EnableCaching
后端配置
@Beanpublic CacheManager cacheManager(RedisConnectionFactory connectionFactory) { return RedisCacheManager.builder(connectionFactory) .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(20))) //缓存时间绝对过期时间20s .transactionAware().build(); }
缓存key的生成
其他操作
@CachePut(增加/修改)
应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存。
@CacheEvict(删除)
应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据
@Cacheable(查询)
应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有 再调用方法获取数据,然后把数据添加到缓存中
问题
缓存一致性问题
数据更新操作才会导致缓存一致性问题。
描述
数据库和缓存更新,容易出现数据库和缓存数据不一致的问题
问题:同时有一个请求 A 进行更新操作,一个请求 B 进行查询操作。可能出现:(1)请求 A 进行写操作(key = 1 value = 2),先删除缓存 key = 1 value = 1 (2)请求 B 查询发现缓存不存在(3)请求 B 去数据库查询得到旧值 key = 1 value = 1(4)请求 B 将旧值写入缓存 key = 1 value = 1(5)请求 A 将新值写入数据库 key = 1 value = 2
注意⚠️
上面的情况,缓存中的数据永远都是脏数据
建议
缓存双删,进行两次删除操作。先删除缓存,在更新数据库,再此删除缓存(第二次删除可异步)
第二次删除后,数据要从数据库获取,保证缓存和数据库的一致性。保证数据的最终一致性
伪代码
缓存同步方案
实时同步更新
每次更新数据库之后,都对缓存进行更新,通过编码实现
优点
数据实时更新,保证强一致性
缺点
代码耦合,对业务代码有侵入性
准实时更新
更新数据库后,不立刻更新缓存,而是异步更新缓存。可通过发布订阅/MQ实现。
与业务解耦
数据同步延迟较短
能保证最终一致性
实现复杂,架构较重
缓存失效机制
基于缓存本书的失效机制。跟缓存设置过期时间,过期后再去数据库获取数据存入缓存
实现简单
不需要引入额外的逻辑
数据同步延迟不好控制。存在缓存击穿/雪崩的情况
定时任务更新
采用任务调度框架,或者定时任务,定期的从数据库获取数据更新到缓存
不保证一致性
依赖定时任务
缓存雪崩
缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压 力过大甚至 down 机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩 是不同数据都过期了,很多数据都查不到从而查数据库。
解决办法
key设置不同的过期时间
加锁,控制对数据库的访问
缓存预热
使用集群
缓存击穿
缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于 并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力 瞬间增大,造成过大压力
加锁,控制对数据库访问的数量
设置数据用不过期,物理不过期,逻辑上写代码更新
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为 id 为“-1”的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导 致数据库压力过大。
布隆过滤器
redis中存储空结果,设置较短的过期时间
0 条评论
回复 删除
下一页