Redis 面试题 缓存穿透 缓存击穿 缓存雪崩

Redis 菜鸟教程 
Redis 命令参考(红色)   
Redis 命令参考(蓝色)  
Redis数据库学习教程(快速入门版)  

1、缓存穿透
key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
总结:缓存、数据库中都没有的数据。
解决办法:
(1) 做好参数校验,对于不合法的参数请求直接抛出异常信息返回给客户端。
(2) 缓存无效 key,对于缓存和数据库都查不到某个 key 的数据,就写一个key-null的数据到缓存中,并设置过期时间,下次查询的时候只需要在缓存中查找一次就可以返回结果。这种方式可以解决请求的 key 变化不频繁的情况,如果黑客每次构建不同的请求 key,这种方法就不适用了。
(3) 布隆过滤器,把所有可能存在的值都存放在布隆过滤器中,当用户请求过来,先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户端,存在的话才会去查缓存和数据库。

2、缓存击穿
key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
总结:缓存中没有或过期,但数据库中有的数据。
解决方案:
1.将value的时效设置成永不过期
这种方式非常简单粗暴但是安全可靠。但是非常占用空间对内存消耗也是极大。个人并不建议使用该方法,应该根据具体业务逻辑来操作。
2.使用Timetask做一个定时任务
使用Timetask做定时,每隔一段时间对一些热点key进行数据库查询,将查询出的结果更新至redis中。前条件是不会给数据库过大的压力。
3.通过synchronized+双重检查机制
当发生reids穿透的时候,这时海量请求发送到数据库。这时我们的解决办法是只让只让一个线程去查询这个热点key,其它线程保持阻塞状态(可以让它们sleep几秒)。当这个进入数据库的线程查询出key对应的value时,我们再将其同步至redis的缓存当中,其它线程睡醒以后再重新去redis里边请求数据。

3、缓存雪崩
当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
总结:大量缓存数据过期,失效。
解决办法:
(1) 设置不同的失效时间,比如在原有的失效时间基础上增加一个随机值,降低过期时间的重复率
(2) 搭建的集群,增加缓存数量,当其中一台挂掉之后其他的还可以继续工作
(3) 本地缓存+限流

4、缓存穿透解决方案
1、布隆过滤器
2、查询返回的数据为空(不管是数据不存在,还是系统故障),仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
*
5、缓存预热 
缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
*
*
6、缓存更新 
*
*
7、缓存降级 
*
*
8、缓存热点key 
*
*
9、dis 分布式锁的问题
Redis 面试题 缓存穿透 缓存击穿 缓存雪崩_第1张图片

10、Redis 配置文件  Redis配置文件     Redis 配置 | 菜鸟教程 
在 Redis 的安装目录中有一个名为 redis.windows.conf 的配置文件,若在 Linux 中则为 redis.conf

# 查看配置信息
config get <配置项名称>

# 设置配置信息
config set <配置项名称> <值>

# 获取端口信息
config get port

# 取所有配置信息
config get *

# 设置日志记录级别
config set loglevel "notice"

11、Redis支持五种【九种】数据类型 
1、string(字符串)
2、hash(哈希)
3、list(列表)
4、set(集合:无序)
5、zset【sorted set】(集合:有序)  Redis五大数据类型之Zset(有序集合)命令操作 
6、BitMaps[布隆过滤器]是字符串类型的,是个位符的二进制组成的
7、HyperLogLoss[基准统计]提供一个不太准确的基数统计方法,set的升级版
8、GEO地理坐标
9、Streams流,kafka是借助于流服务开发

12、Redis 事务常用命令 
multi、exec、discard、watch、unwatch
multi:开启事务,开始一个事务;
exec:执行一个事务,这个命令总是在multi后面执行。此命令会释放所有watch的key
discard:取消事务,放弃事务,此命令会释放所有watch的key;
watch:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
unwatch:取消WATCH对所有key的监视,放弃监视的所有key;

13、过期 Key 的删除策略 
定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。对内存很友好,但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
惰性删除:当key被访问时检查该key的过期时间,若已过期则删除;已过期未被访问的数据仍保持在内存中。可以最大化地节省CPU资源,却对内存非常不友好
定期删除:每隔一段时间,会扫描一定数量设置了过期的key,并删除已过期的key。是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

14、Redis 内存淘汰策略 8种
noeviction:永不回收,当内存使用超过配置的时候会返回错误,不会驱逐任何键。
volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键(挑选最近最少使用的数据淘汰)。
volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键(挑选即将要过期的数据淘汰)。
volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐(随机挑选数据淘汰)。
volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键(使用LFU算法对数据淘汰)。
allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键(挑选最近最少使用的数据淘汰)。
allkeys-random:加入键的时候如果过限,从所有key随机删除(随机挑选数据淘汰)。
allkeys-lfu:从所有键中驱逐使用频率最少的键(使用LFU算法对数据淘汰)。
*
这八种大体上可以分为4种,lru、lfu、random、ttl。
lru:Least Recently Used),最近最少使用。
lfu:Least Frequently Used,最不经常使用法。
ttl:Time To Live,生存时间。
random:随机。

15、Redis 对 ACID 的支持性理解 
原子性 atomicity 
Redis的事务是原子性的:所有的命令,要么全部执行,要么全部不执行。而不是完全成功。
一致性 consistency 
redis事务可以保证命令失败的情况下得以回滚,数据能恢复到没有执行之前的样子,是保证一致性的,除非redis进程意外终结。
隔离性 Isolation 
redis事务是严格遵守隔离性的,原因是redis是单进程单线程模式(v6.0之前),可以保证命令执行过程中不会被其他客户端命令打断。但是,Redis不像其它结构化数据库有隔离级别这种设计。
持久性 Durability 
redis事务是不保证持久性的,这是因为redis持久化策略中不管是RDB还是AOF都是异步执行的,不保证持久性是出于对性能的考虑。

16、Redis 持久化 
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供两种持久化的方式,分别是RDB(Redis DataBase,默认)和 AOF(Append Only File)。
RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.db。通过配置设置自动做快照持久化的方式。
AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

17、Redis 集群最大节点个数是多少? 
16384个

18、Memcache 与 Redis 的区别都有哪些 
memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
redis的速度比memcached快很多
memcached把数据全部存在内存之中,redis可以持久化数据,可以将内存中的数据保持在磁盘中。

19、Redis 和 MongoDB 的区别 
● 两者的共性 
都是非关系型数据库,支持键值对和复杂数据类型的存储。
都支持高并发和高可用性的数据访问,可以应对大量数据和请求的场景。
都提供了多种扩展和副本机制,保证数据的可靠性和可扩展性。
● 两者的区别 
数据模型不同:MongoDB是文档数据库,Redis是键值对存储数据库。
查询和索引机制不同:MongoDB支持丰富的查询语言和索引机制,Redis仅支持简单的查询和索引。
存储容量不同:MongoDB可存储大量数据,支持分片,可横向扩展,适用于海量数据存储和分析,Redis适用于缓存和高速数据访问。
数据持久化方式不同:MongoDB提供多种数据持久化方式,Redis提供多种持久化方式来保护数据可靠性。
● 应用场景 
MongoDB 更适合存储大量的非结构化数据,比如文档、图片、音频、视频等等。它适用于需要高可用性、高扩展性、事务支持和丰富查询功能的应用程序。
Redis 更适合存储小型的键值对、缓存数据、消息队列等等。它适用于需要快速读写、高并发、轻量级存储的应用程序。

20、Redis 发布订阅  
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
订阅者(subscriber):如客户端
发布者(publisher):如服务器
频道(channel):频道

21、Redis 四种模式 
单机
主从复制模式
哨兵(Sentinel)模式
集群模式

22、Redis 版本 
1. Redis 0.x:这是Redis最早的版本,在2009年2月,Salvatore Sanfilippo发布了这个版本,支持基础的数据类型,以及一些基本的操作,比如排序,搜索,集合等。
2. Redis 1.x:2010年4月,Redis发布了第一个正式版本和源码,这一版本新增了管道、事务、持久化、格式化输出等特性。
3. Redis 2.x:2011年8月,
4. Redis 2.6:2012年08月,
5. Redis 2.8:2014年04月,
6. Redis 3.x:2015年04月,
7. Redis 4.x:2018年08月,
8. Redis 5.x:2018年10月,
9. Redis 6.0:2020年04月,
10. Redis 7.x:2022年01月,
11. Redis 7.0.5 2022年09月21日 星期三 20:00:00 发布。
*
*
*
*
*
*

你可能感兴趣的:(Redis,缓存,redis)