1.Redis支持的数据类型
- String: 字符串 ----> 简单动态字符串 O(1)
- Hash: 散列 ----> 压缩列表 O(n) 或 哈希表 O(1)
- List: 列表 ----> 压缩列表 O(n) 或 双向链表 O(n)
- Set: 集合 ----> 压缩列表 O(n) 或 整数数组 O(n)
- Sorted Set: 有序集合 ----> 压缩列表 O(n) 或 跳表 O(logN)
- HyperLogLog (2.8.9之后)
集合类型:有两种底层实现结构,哈希表和跳表实现“快”,整数数组和压缩链表节省内存空间
两个阈值,一旦超过了阈值,Hash 类型就会用哈希表来保存数据了。
- hash-max-ziplist-entries:表示用压缩列表保存时哈希集合中的最大元素个数。
- hash-max-ziplist-value:表示用压缩列表保存时哈希集合中单个元素的最大长度
2.为什么单线程Redis能那么快?
- Redis 的大部分操作在内存上完成
- Redis 采用了高效的数据结构,例如哈希表和跳表,这是它实现高性能的一个重要原因。
- Redis 采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率
- Redis的通信协议(RESP)比较简单,解析比较快
3.Redis 的管道
- 指的是客户端允许将多个请求依次发给服务器,过程中而不需要等待请求的回复,在最后再一并读取结果即可
4.Redis事务(MULTI,打包执行命令)
- 批量操作在发送EXEC命令前被放入队列缓存
- 收到 EXEC命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行,不会回滚
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中
- 一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
5.Redis实现异步队列
一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
如果对方追问可不可以不用sleep呢?list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
如果对方追问能不能生产一次消费多次呢?使用pub/sub主题订阅者模式,可以实现1:N的消息队列。
6.什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
- 持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失
- Redis持久化的两种方式:RDB和AOF
- RDB工作原理:RDB是指把当前的数据生成快照,以RDB文件:的形式存储(手动触发:save、bgsave)
- BGSAVE
- redis进程执行fork操作创建子进程, 子进程与主线程共享内存
- 子进程开始将数据写到临时RDB文件中
- 当子进程完成写RDB文件,用新文件替换老文件
这个过程Redis采用的是copy-on-write技术 ,那么什么是COW呢?
4dc5fb99a1c94f70957cce1ffef419cc.jpgbgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。
bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。
此时,如果主线程对这些数据也都是读操作(例如图中的键值对 A),那么,主线程和 bgsave 子进程相互不影响。
但是,如果主线程要修改一块数据(例如图中的键值对 C),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。
- AOF
- 将所有的写入命令会append追加到aof_buf缓冲区中
- AOF缓冲区向硬盘做sync同步
- 随着AOF文件越来越大,需定期对AOF文件rewrite重写,达到压缩
- 当redis服务重启,可load加载AOF文件进行恢复
AOF持久化流程:命令写入(append),文件同步(sync),文件重写(rewrite),重启加载(load)
AOF 机制给我们提供了三个选择,也就是 AOF 配置项 appendfsync 的三个可选值,如下:
72f547f18dbac788c7d11yy167d7ebf8.jpg
Redis会定期做aof重写,压缩aof文件日志大小。
如何压缩?
redis会对过大的AOF文件进行重写,以此来压缩AOF文件的大小。
具体的实现是:检查当前键值数据库中的键值对,记录键值对的最终状态,从而实现对某个键值对重复操作后产生的多条操作记录压缩成一条的效果,进而实现压缩AOF文件的大小效果
在redis实例重启时,优先使用aof来恢复内存的状态,如果没有aof日志,就会使用rdb文件来恢复。
AOF跟RDB相结合:
Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。这样一来,快照不用很频繁地执行,这就避免了频繁 fork 对主线程的影响。而且,AOF 日志也只用记录两次快照间的操作,也就是说,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免重写开销。
7.redis的6种数据淘汰策略
maxmemory 用于指定 Redis 能使用的最大内存
- noeviction:不删除策略,达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。
- allkeys-lru:所有key通用;优先删除最近最少使用(less recently used ,LRU) 的 key。
- volatile-lru:只限于设置了expire的部分; 优先删除最近最少使用(less recently used ,LRU) 的 key。
- allkeys-random:所有key通用;随机删除一部分 key。
- volatile-random:只限于设置了expire的部分; 随机删除一部分 key。
- volatile-ttl:只限于设置了expire的部分; 优先删除剩余时间(time to live,TTL)短的key
8.redis主键失效机制
- 消极方法(passive way),在主键被访问时如果发现它已经失效,那么就删除它
- 积极方法(active way),周期性地从设置了失效时间的主键中选择一部分失效的主键删除
- redis维护了一个字典表,当进行expires操作时,首先在字典表中查找要设置的主键是否存在,如果存在就将这个主键和失效时间添加到 expires 这个字典表。简单地总结来说就是,设置了失效时间的主键和具体的失效时间全部都维护在 expires 这个字典表中。
网友评论