Redis 常见面试题
1. Redis 五种数据类型及使用场景?
String(字符串)、hash(哈希)、list(列表)、set(集合) 及zset(sorted set: 有序集合)。
-
String(字符串)
-
特点:
字符串类型是 redis 最基础的数据结构,而且其他几种结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习奠定基础。 字符串类型实际上可以是字符串(简单字符串、复杂的字符串 (xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频)),最大不能超过 512M
-
应用场景:
缓存功能:字符串最经典的使用场景,redis 作为缓存层,Mysql 作为存储层,绝大部分请求的数据都是在 redis 中获取,因为 redis 支持高并发,所以缓存通常起到加速读写和降低后端服务器压力的作用。 计数器:使用 redis 作为技术的基础工具,他可以实现快速计数、查询缓存的功能,同时数据可以一步落地到其他的数据源。如:视频播放数系统就是使用 Redis 作为视频播放技术的基础组件。 共享 Session: 分布式系统中,用户每次登陆可能访问的是不同的服务器,比如 第一次访问 A 服务器,session 保存在 A 服务器,第二次登陆访问 B 服务器,该服务器未保存登陆 session,用户需要重新登陆。为避免这个问题,可以使用 redis 将用户的 session 集中管理,在这种模式下只要保证 redis 的高可用和拓展性,每次获取用户更新或查询登陆信息都直接从 redis 中集中获取。 限速: 出于安全考虑,每次进行登录时让用户输入手机验证码,为了短信接口部分频繁访问,会限制用户每分钟获取验证码的频率。
-
-
hash(哈希)
-
特点:
在 redis 哈希类型是指 value 本身又是一种键值对结构
-
应用场景:
哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷,所以常常用于用户信息等管理
-
-
list(列表)
-
特点:
列表类型是用来存储多个有序的字符串,类表中的每个字符串成为元素,一个列表最多可以存储 2 的 32 次方 -1 个元素,在 redis 中,可以从列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等等,列表是一种比较灵活的数据结构,他可以充当栈和队列的角色,在实际开发中有很多应用场景。 优点: 1.类表的元素是有序的,就可以通过索引下标获取某个后某个范围内的元素列表 2.列表的元素是可以重复的。
-
应用场景:
消息队列:redis 的 lpush + brpom 命令组合即可实现阻塞队列,生产者客户端是用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpom 命令阻塞时的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
-
-
set(集合)
-
特点:
集合类型也是用来保存多个字符串的元素,但和列表不同的是集合中不允许有重复的元素,并且集合中的元素是无序的,不能通过索引下标获取元素,redis 除了支持集合内的增删改查,同时还支持多个集合取交集、丙级、差集,并合理地使用好集合类型,能在实际开发中解决很多实际的问题。
-
应用场景:
集合类型比较典型的使用场景,如一个用户对娱乐、体育比较感兴趣,另一个可能对新闻感兴趣,这些兴趣就是标签,有了这些数据就可以得到统一标签的人,以及用户的共同爱好的标签,这些数据对于用户体验以及增强用户粘度比较重要。
-
-
zset(sorted set: 有序集合)
-
特点:
有序集合和集合有着必然的联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中元素是可以排序的,但是它和列表的使用索引下标作为排序依据不同的是,他给每个元素设置一个分数,作为排序的依据。(有序集合中元素不可以重复,但是 score 可以重复,就和一个班里的同学学号不能重复,但考试成绩可以相同)。
-
应用场景:
排行榜:有序集合经典使用场景,例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面;按照时间、按照播放量、按照获得的点赞数等。
-
2. Redis 过期键的删除策略都有哪些?
- 定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除改建,如果没有过期,就返回该键。
- 定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
3. Redis 的持久化机制有哪些?各自的优缺点?
Redis 提供两种持久化机制 RDB 和 AOF 机制。
-
RDB(Redis DataBase)持久化方式
是指数据集快照的方式(半持久化模式)记录 redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。 优点: 1. 只有一个文件 dump.rdb,方便持久化。 2. 容灾性好,一个文件可以保存到安全的磁盘。 3. 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。(使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能。 缺点: 数据安全性低。(RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
-
AOF(Append-only file)持久化方式
是指所有的命令行记录以 redis 命令请求协议的格式(完全持久化存储)保存为 aof 文件。 优点: 1. 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。 2. 通过 append 模式写文件,即使中途服务宕机,可以通过 redis-check-aof 工具解决数据一致性问题。 缺点: 1. AOF 文件比 RDB 文件大,且恢复速度慢。 2. 数据集大的时候,比 rdb 启动效率低。
4. AOF 数据体量大,可以对其优化吗?
redis 中引入 AOF 重写机制,可以压缩文件体积——执行压缩命令即可。
AOF 重写可以降低磁盘占用量,也能提高数据恢复效率,他会对同一数据的多条写命令合并为一条命令,且为了防止数据量过大造成缓冲区溢出,每条指令最多为 64 个元素。
AOF 重写是一个同步开启的子进程,Redis 执行指令时,子进程也会开启重写,主进程会将写入的数据同步到子进程,子进程则开始重写 AOF 文件,写完后再返回给主进程,完成 AOF 重写。
如果对数据非常敏感使用 AOF ;如果追求大数据集的恢复速度选 RDB
5. 什么是缓存穿透、缓存雪崩、缓存击穿?
**缓存穿透:**指反复查询一个数据库一定不存在的数据,导致数据库压力过大,这种情况一般只有恶意攻击才会出现。
解决办法:
- 把查询的对象设为空值,也放入缓存,并设定较短的缓存过期时间,用户下次访问就会查询到 null 值,如果还是频繁查询这个 null 值。
- 布隆过滤器
**缓存雪崩:**指某个时间段内,缓存集中的过期失效,导致大量请求过来,压力都集中到数据库。
解决办法:
- 设置缓存的失效时间尽量错开,热门数据时间长点,不热门的时间短点
- 设置多级缓存。nginx 缓存 + redis 缓存 + ehcache 缓存…每一个缓存都是一个集群,相同的数据会在多种服务器进行缓存,可以百分百解决缓存雪崩。
- 侧面解决。优化数据库,提升效率,使用页面静态技术代替从 redis 中取值。
**缓存击穿:**一个热点 key 的 redis 缓存失效,导致大量请求瞬间集中到数据库。
缓存 + redis 缓存 + ehcache 缓存…每一个缓存都是一个集群,相同的数据会在多种服务器进行缓存,可以百分百解决缓存雪崩。
3. 侧面解决。优化数据库,提升效率,使用页面静态技术代替从 redis 中取值。
**缓存击穿:**一个热点 key 的 redis 缓存失效,导致大量请求瞬间集中到数据库。
解决办法:将热点数据设置长时间的缓存即可。一般只在特殊时期设置热门产品是用。