您的位置:首页 > 数据库 > Redis

《架构师36项修炼》 Redis常见面试题之缓存雪崩,缓存穿透,缓存并发,缓存预热,缓存算法详解

2020-03-05 08:32 603 查看

概述

首先大家看一下redis需要掌握的知识图谱

 

 

相信大家之前或多或少听过面试中,面试官提到雪崩,穿透之类的场景,今天大概讲一下缓存雪崩,缓存穿透,缓存并发,缓存预热,缓存算法这几个概念和解决思路。

1、缓存雪崩

可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

解决思路:

1.1、加锁计数(即限制并发的数量)或者起一定数量的队列来避免缓存失效时大量请求并发到数据库。但这种方式会降低吞吐量。

1.2、分析用户行为,然后失效时间均匀分布。或者在时间的基础上再加1~5分钟的随机数。

超时机制设计

(1)超时分两种,一种是请求的等待超时,一种是请求运行超时。

(2)等待超时:在任务入队列时设置任务入队列时间,并判断队头的任务入队列时间是否大于超时时间,超过则丢弃任务。

(3)运行超时:直接可使用线程池提供的get方法。

1.3、如果是某台缓存服务器宕机,则考虑做主备。

2、缓存穿透

指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库中查询。

解决思路:

2.1、如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。

可以给key设置一些格式规则,将无效 key 保存到 Redis 中 ,然后查询之前先过滤掉不符合规则的Key。

2.2、布隆过滤器

布隆过滤器(Bloom Filter)的原理解释起来很复杂,用白话概括一下它的特点:它说某个 key 不存在,那么就一定不存在,它说某个 key 存在,那么很大可能是存在(存在一定的误判率)。

使用布隆过滤器,挡回无效请求,流程大概是这样的:

 

3、缓存并发

如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

解决思路:

对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。

4、缓存预热

目的就是在系统上线前,将数据加载到缓存中。

解决思路:

4.1、数据量不大的话,在系统启动的时候直接加载。

4.2、自己写个简单的缓存预热程序。

5、缓存算法

FIFO算法:First in First out,先进先出。原则:一个数据最先进入缓存中,则应该最早淘汰掉。也就是说,当缓存满的时候,应当把最先进入缓存的数据给淘汰掉。

LFU算法:Least Frequently Used,最不经常使用算法。

LRU算法:Least Recently Used,近期最少使用算法。

LRU和LFU的区别。LFU算法是根据在一段时间里数据项被使用的次数选择出最少使用的数据项,即根据使用次数的差异来决定。而LRU是根据使用时间的差异来决定的。

noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)

allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。

volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。

allkeys-random: 回收随机的键使得新添加的数据有空间存放。

volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。

volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

上面的内容是优化需要了解的,对大家以后优化还是有一定帮助的。

后期会分享更多关于系统优化方面的内容,有兴趣的朋友可以关注下!

  • 点赞
  • 收藏
  • 分享
  • 文章举报
牛路 发布了16 篇原创文章 · 获赞 0 · 访问量 517 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: