本帖最后由 javahm 于 2019-9-12 12:21 编辑
1. 什么是 Redis?
Redis 本质上是一个 Key-Value 类型的内存数据库,很像 memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘上进行保存。因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的 Key-Value DB。 Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构,此外单个 value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的数据,因此 Redis 可以用来实现很多有用的功能,比方说用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性 能消息队列服务,用他的 Set 可以做高性能的 tag 系统等等。另外 Redis 也可以对存入的 Key-Value 设置 expire 时间,因此也可以被当作一 个功能加强版的 memcached 来用。 Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上。
2. Redis 有哪些数据结构?
字符串 String、字典 Hash、列表 List、集合 Set、有序集合 SortedSet。
如果你是 Redis 中高级用户,还需要加上下面几种数据结构 HyperLogLog、Geo、Pub/Sub。
如果你说还玩过 Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
3. Redis 为什么是单线程的?
因为 CPU 不是 Redis 的瓶颈。Redis 的瓶颈最有可能是机器内存或者网络带宽。(以上主要来自官方 FAQ)既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于 redis 的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求,
4. 使用 Redis 有哪些好处?
(1) 速度快,因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是 O (1)
(2) 支持丰富数据类型,支持 string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除
5. Redis 相比 memcached 有哪些优势?
(1) memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型
(2) redis 的速度比 memcached 快很多
(3) redis 可以持久化其数据
(4) Redis 支持数据的备份,即 master-slave 模式的数据备份。
(5) 使用底层模型不同
它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。
Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
(6)value 大小:redis 最大可以达到 1GB,而 memcache 只有 1MB
6.使用过 Redis 分布式锁么,它是什么回事?
先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。
如果在 setnx 之后执行 expire 之前进程意外 crash 或者要重启维护了,那会怎么样?
这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得 set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和 expire 合成一条指令来用的!
7. Redis 如何做持久化的?
bgsave 做镜像全量持久化,aof 做增量持久化。因为 bgsave 会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要 aof 来配合使用。在 redis 实例重启时,会使用 bgsave 持久化文件重新构建内存,再使用 aof 重放近期的操作指令来实现完整恢复重启之前的状态。
那如果突然机器掉电会怎样?
取决于 aof 日志 sync 属性的配置,如果不要求性能,在每条写指令时都 sync 一下磁盘,就不会丢失数据。但是在高性能的要求下每次都 sync 是不现实的,一般都使用定时 sync,比如 1s1 次,这个时候最多就会丢失 1s 的数据。
bgsave 的原理是什么?
fork 和 cow。fork 是指 redis 通过创建子进程来进行 bgsave 操作,cow 指的是 copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
8.假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?
使用 keys 指令可以扫出指定模式的 key 列表。
如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?
redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。
9.如果有大量的 key 需要设置同一时间过期,一般需要注意什么?
如果大量的 key 过期时间设置的过于集中,到过期的那个时间点,redis 可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。
10. Redis 的同步机制了解么?
Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次 bgsave,并同时将后续修改操作记录到内存 buffer,待完成后将 rdb 文件全量同步到复制节点,复制节点接受完成后将 rdb 镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
11. Redis 为什么这么快?
纯内存数据库,避免了磁盘 I/O 的瓶颈。
单进程单线程,减少了线程上下文切换的开销。
利用队列技术将并行访问变为串行访问,消除了传统数据库并发访问控制锁的开销。
Redis 全程使用 hash 结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
使用多路 I/O 复用模型,非阻塞 I/O。
12.多路 I/O 复用模型:
多路 I/O 复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里 “多路” 指的是多个网络连接,“复用” 指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响 Redis 性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。
13.Redis 持久化方式
RDB 持久化:redis 提供了 RDB 持久化的功能,这个功能可以将 redis 在内存中的的状态保存到硬盘中,它可以手动执行,也可以再 redis.conf 中配置,定期执行。RDB 持久化产生的 RDB 文件是一个经过压缩的二进制文件,这个文件被保存在硬盘中,redis 可以通过这个文件还原数据库当时的状态。
AOF 持久化:AOF 持久化(Append-Only-File),与 RDB 持久化不同,AOF 持久化是通过保存 Redis 服务器锁执行的写状态来记录数据库的。具体来说,RDB 持久化相当于备份数据库状态,而 AOF 持久化是备份数据库接收到的命令,所有被写入 AOF 的命令都是以 redis 的协议格式来保存的。在 AOF 持久化的文件中,数据库会记录下所有变更数据库状态的命令,除了指定数据库的 select 命令,其他的命令都是来自 client 的,这些命令会以追加 (append) 的形式保存到文件中。
对比:
AOF 更安全,可将数据及时同步到文件中,但需要较多的磁盘 IO,AOF 文件尺寸较大,文件内容恢复相对较慢,也更完整。
RDB 持久化,安全性较差,它是正常时期数据备份及 master-slave 数据同步的最佳手段,文件尺寸较小,恢复数度较快。 |
|