Redis-八股文
1. 什么是 Redis?
Redis 是基于内存的 Key-Value 非关系型数据库。开源,并且遵循 BSD 协议。
- Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis 不仅仅支持简单的 key – value 类型的数据,同时还提供 list、set、zset、hash 等数据结构的存储。
- Redis 支持数据的备份,即 master–slave 模式(主从模式)的数据备份。
- 主从模式介绍:Redis 的主从模式跟 MySQL 主从复制原理差不多,主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。
- 主数据库可以进行读写操作,从库只能进行读操作(可以配置从库支持读写操作,不建议)。
- 当主数据库的读写操作导致数据库变化时会自动将数据同步从数据库。
- 主从数据库可以是一主多从,即一个 master 可以拥有多个 slave,但只能一从一主,即一个 slave 只能对应一个 master。
- slave 挂了之后,不影响其它 slave 和 master 读写,重新启动 slave 之后会自动从 master 同步数据过来。
- master 挂了之后,不影响 slave 读,但 Redis 不再提供写服务,master 重启后 Redis 将重新对外提供写服务。
- master 挂了之后,不会在 slave 节点中重新选一个 master。
- 主从模式介绍:Redis 的主从模式跟 MySQL 主从复制原理差不多,主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。
-
Redis 优势
2. Redis 的数据类型?
Redis 支持五种数据结构:string (字符串)、hash(哈希)、list(列表)、set(集合) 及 zset sorted set (有序集合)。
我们实际项目中比较常用的是 string、hash。如果你是 Redis 中高级用户,还需要加上下面几种数据结构 HyperLogLog、Geo、Pub/Sub。
3. 使用 Redis 有哪些好处?
- 速度快 – 因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是 O1。
- 支持丰富数据类型,支持 string、list、set、Zset、hash 等。
- 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行。
- 丰富的特性:可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除。
4. Redis 相比 Memcached 有哪些优势?
5. Memcached 于 Redis 有哪些区别?
- 存储方式 Memcached 把数据全部存储在内存中,断电后会挂掉,数据不能超过内存大小。Redis 有部分存在硬盘上,这样能保存数据的持久性。
- 数据支持类型 Memcache 对数据类型支持相对简单,Redis 有复杂的数据类型。
- 使用底层模型不同,它们之间底层实现方式,以及与客户端之间通信的应用协议不一样。Redis 直接构建了 VM 机制。因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
6. Redis 是单进程单线程的?
Redis 是单进程单线程的,Redis 利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
7. 一个字符串的值能存储最大容量是多少?
512M
8. Redis 的持久化机制是什么?各自的优缺点?
- RDB (Redis DataBase)持久化方式:是指用数据集快照的方式半持久化模式,记录 Redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
- AOF (Append–only–file)持久化方式:是指所有的命令行记录以 Redis 命令请求协议的格式完全持久化存储,保存为 aof 文件。
9. Redis 常见性能问题和解决方案
- Master 最好不要写内存快照,如果 Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程的工作,当快照比较大的时候对性能影响是非常大的,会间断暂停服务。
- 如果数据比较重要,某个 slave 开启 AOF 备份数据,策略设置为每秒同步一次。
- 为了主从复制的速度和连接的稳定性,Master 和 Slave 最好在同一个局域网。
- 尽量避免在压力很大的主库上增加从库
- 为了 Master 的稳定性,主从复制不要用图状结构,用单向链表更稳定,即主从关系为: Master <— Slave1 <— Slave2 <— Slave3这样的结构也方便解决单点故障,实现 Slave 对 Master 的替换,如果 Master 挂了,可以马上启用 Slave1 做 Master,其他不变。
10. Redis 过期键的删除策略?
- 定时删除:在设置键的过期时间的同时,创建一个定时器(timer)。让定时器在键的过期时间来临时,立即执行对键的删除操作。
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
- 定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至少要删除多少过期键,以及要检查多少个数据库,则由算法决定。
11. Redis 的回收策略(淘汰策略)?
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最少使用的数据淘汰。
- volatile-ttl:从已过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据(永不回收)
注意这里的6种机制,volatile 和 allkeys 规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的 lru 、ttl 以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略。
12. 为什么 Redis 需要把所有数据放到内存中?
Redis 为了达到最快的读写速度将数据读到内存中,并通过异步的方式将数据写入磁盘,所以 Redis 具有快速和数据持久化的特性,如果不将数据放在内存中,磁盘 I/O 速度会严重影响 Redis 的性能,在内存越来越便宜的今天,Redis 会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值
13. Redis 的同步机制了解吗?
Redis 可以使用主从同步、从从同步。
- 第一次同步时,主节点做一次 bgsave,并同时将后续操作记录到内存 buffer
- 待完成后将 rdb 文件全量同步到复制节点,复制节点接受完成后将 rdb 镜像加载到内存中。
- 加载完毕后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
14. Pipeline 有什么好处?为什么要用 pipeline?
可以将多次 IO 往返的时间缩减为一次, 减少多次 IO 延迟的开销。前提是 pipeline 执行的指令之间没有因果相关性。使用 redis–benchmark 进行压测的时候可以发现影响 Redis 的 QPS 峰值的一个重要因素时 pipeline 批次指令的数目。
15. 是否使用过 Redis 集群?集群的原理是什么?
- Redis Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为 master,继续提供服务。
- Redis Cluster 着眼于扩展性,在单个 Redis 内存不足时,使用 Cluster 进行分片存储。
16. Redis 集群方案什么情况下会导致整个集群不可用?
有 A、B、C 三个节点的集群,在没有复制模型的情况下,如果节点 B 失败了,那么整个集群就会以为缺少 5501 ~ 11000 这个范围的槽而不可用。
-
Redis 集群最大节点的个数是多少?
16384 个
17. Redis 支持的 Java 客户端都有哪些?官方推荐使用哪个?
Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson
18. Jedis 于 Redisson 对比有什么优缺点?
-
Redisson 实现了分布式和可扩展性的 Java 数据结构,和 Jedis 相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等 Redis 特性。Redisson 的宗旨是促进使用者对 Redis 的关注分离,从而让使用者能够将精力更集中的放在处理业务逻辑上。
19. Redis 如何设置密码及验证密码?
设置密码:
config set requirepass 123456
auth 123456
20. 说说 Redis 哈希槽的概念?
21. Redis 集群的主从复制模型是怎么来的?
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品。
22. Redis 集群会有写操作丢失吗?为什么?
Redis 并不能保证数据的强一致性,这意味着在实际中集群在特定的条件下可能会丢失写操作。
以下情况可能导致 写操作丢失 :
23. Redis 集群之间是如何复制的?
异步复制。
24. Redis 集群最大节点个数是多少?
16284 个
25. Redis 集群如何选择数据库?
26. 怎么测试 Redis 的连通性?
使用 ping 命令
27. 怎么理解 Redis 事务?
28. Redis 事务相关的命令有哪几个?
29. Redis key 的过期时间和永久有效分别怎么设置?
- expire 命令用于设置 key 的过期时间,key 过期后将不再可用。单位以秒计
- persist 命令用于移除给定 key 的过期时间,使得 key 永不过期
- ttl 命令以秒为单位返回 key 的剩余过期时间
30. Redis 如何做内存优化?
散列表:
- 尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称、姓氏、邮箱、密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。
31. Redis 回收进程如何工作的?
- 一个客户端运行了新的命令,添加了新的数据。Redis 检查内存使用情况,如果大于 maxmemory 的限制,则根据设定好的策略进行回收。一个新的命令被执行,等等。
- 所以我们不断地穿越内存限制的便捷,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量的内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
32. 都有哪些办法可以降低 Redis 的内存使用情况?
如果你使用的是 32 位的 Redis 实例,可以好好利用 hash、list、sorted set、set 等集合类型数据,因为通常情况下小的 key-value 可以用更紧凑的方式存储。
33. Redis 的内存用完了会发生什么?
如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回),或者你可以将 Redis 当缓存来使用配置淘汰机制,当 Redis 达到内存上限时会冲刷掉旧的内容。
这个跟 Redis 的内存回收策略有关。
Redis 的默认回收策略是 noenviction,当内存用完之后,写数据会报错。
34. 一个 Redis 实例最多能存放多少 keys、List、Set、Sorted Set 他们能存放多少元素?
理论上 Redis 可以处理多达 2^32 的 keys,并且在实际中进行了测试,每个实力至少存放了 2 亿 5 千万个 keys,任何 list、set 和 sorted set 都可以存放 2 ^ 32 个元素。换句话说,Redis 的存储极限是系统中的可用内存值。
35. MySQL 里面有 2000W 数据 Redis 中只存 20W 的数据,如何保证 Redis 中的数据都是热点数据?
Redis 内存数据集大小上升到一定大小的时候,就会施行数据的淘汰策略。
volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据集淘汰
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
36. Redis 最合适的场景?
37. 假如 Redis 里面有 1 亿个 key,其中有 10W 个 key 是以某个固定的已知的前缀开头的,如何将它们全部找出来?
38. 如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,Redis 可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值。使得过期时间分散一些。
39. 使用过 Redis 做异步队列么,你是怎么用的?
一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候,要适当 sleep 一会再重试。不但客户端的 CPU 能降下来,Redis 的 QPS 也降下来了。
如果对方追问可不可以不用 sleep 呢?
如果对方追问能不能生产一次消费多次呢?
- 延时队列可以通过 Redis 的 zset(有序列表) 来实现。我们将消息序列化成一个字符串作为 zset 的 value,这个消息的到期处理时间作为 score,然后用多个线程轮询 zset 获取到期的任务进行处理,多个线程是为了保障可用性,万一挂了一个线程还有其它线程可以继续处理。
40. 使用过 Redis 分布式锁吗?
先拿 setnx 来争取锁,抢到之后,再用 expire 给锁加一个过期时间方式锁忘记释放。
如果在 setnx 之后执行 expire 之前线程意外 crash 或者重启维护了,那么会怎么样?
在 set 指令的参数中,可以把 setnx expire 合成一条指令使用
redis 分布式锁的七种实现方式:
https://blog.csdn.net/new_baibai/article/details/130763776?spm=1001.2014.3001.5501
原文地址:https://blog.csdn.net/new_baibai/article/details/130763730
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_25878.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!