一、缓存穿透
缓存穿透是指查询一个根本不存在的数据,缓存层和持久层都不会命中。在日常工作中出于容错的考虑,如果从持久层查不到数据则不写入缓存层,缓存穿透将导致不存在的数据每次请求都要到持久层去查询,失去了缓存保护后端持久的意义
解决方案:
- 缓存空对象
- 布隆过滤器拦截
二、缓存雪崩
由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不可用(宕机)或者大量缓存由于超时时间相同在同一时间段失效(大批key失效/热点数据失效),大量请求直接到达存储层,存储层压力过大导致系统雪崩。
解决方案:
可以把缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务。利用sentinel或cluster实现。
采用多级缓存,本地进程作为一级缓存,redis作为二级缓存,不同级别的缓存设置的超时时间不同,即使某级缓存过期了,也有其他级别缓存兜底
缓存的过期时间用随机值,尽量让不同的key的过期时间不同(例如:定时任务新建大批量key,设置的过期时间相同)
三、缓存击穿
系统中存在以下两个问题时需要引起注意:
当前key是一个热点key(例如一个秒杀活动),并发量非常大。
重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的SQL、多次IO、多个依赖等。
在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。
解决方案:
- 分布式互斥锁
只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。set(key,value,timeout)
———————————————————————————————
Redis数据库持久化方式
AOF方式:是通过保存redis服务器所执行的写命令来记录数据库状态的AOF文件刷新方式,有三种:
1.appendfsync always – 每提交一个修改命令都调用fsync到AOF文件,非常慢,但是很安全;
2.appendfsync everysec – 每秒都调用fsyns刷新到AOF文件,很快但可能丢失一秒内的数据;
3.appendfsync no – 依靠OS进行刷新,redis不主动刷新AOF,这样最快但是安全性差;
AOF方式:有两个redis命令可以生成RDB文件,一个是SAVE,另一个是BGSAVE,SAVE命令会阻塞redis服务器进程,直到RDB文件
创建完毕为止,在服务器阻塞期间,服务器不能处理任何的进程,BGSAVE会派出一个子进程,然后由子进程负责创建RDB
———————————————————————————————