这些知识点你都掌握了吗?大家可以对着问题看下自己掌握程度如何?对于没掌握的知识点,大家自行网上搜索,都会有对应答案,本文不做知识点详细说明,只做简要文字或图示引导。
Redis 全景图
Redis 知识全景图都包括什么呢?简单来说,就是“两大维度,三大主线”。
Redis 问题画像
在学习和使用的过程中,你可以完善这张图,把你自己实践或掌握到的新知识点,按照“问题 --> 主线 --> 技术点”的方式梳理出来,放到这张图上。
基础篇
基本架构:一个键值数据库包含什么?
数据结构
有哪些底层数据结构
- 3.0 版本中 List 对象的底层数据结构由「双向链表」或「压缩表列表」实现;
- 3.2 版本之后,List 数据类型底层数据结构是由 quicklist 实现;
- 5.0新设计,7.0 版本之后,压缩列表已废弃,由 listpack 数据结构来实现。
键和值用什么结构组织
为了实现从键到值的快速访问,Redsi 使用了一个哈希表来保存所有键值对。
- 哈希表的冲突问题和rehash可能带来的操作阻塞**。Redis 解决哈希冲突的方式,就是渐进式 rehash**。
压缩列表
quicklist
通过控制每个链表节点中的压缩列表的大小或者元素个数,来规避连锁更新的问题。因为压缩列表元素越少或越小,连锁更新带来的影响就越小,从而提供了更好的访问性能。
quicklist 会控制 quicklistNode 结构里的压缩列表的大小或者元素个数,来规避潜在的连锁更新的风险,但是这并没有完全解决连锁更新的问题。
listpack
listpack 采用了压缩列表的很多优秀的设计,比如还是用一块连续的内存空间来紧凑地保存数据,并且为了节省内存的开销,listpack 节点会采用不同的编码方式保存不同大小的数据。
listpack 没有压缩列表中记录前一个节点长度的字段了,listpack 只记录当前节点的长度,当我们向 listpack 加入一个新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题。
高性能IO模型:为什么单线程的Redis能那么快?
Redis 是单线程,主要指 Redis 的网络 IO 和键值对读写是由一个线程完成的。
为什么单线程就能那么快?
- 一是Redis 大部分操作在内存上完成,并且采用了高效的数据结构;
- 二是采用多路复用,能保证在网络IO钟可以并发处理大量的客户端请求,实现高吞吐量。
Linux 中的 IO 多路复用机制是一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,**在 Redis 中值运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字。**内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流。
持久化:AOF日志和RDB快照
AOF 日志
优点
- 写后日志,可以避免出现记录错误命令的情况
- 在命令执行后才记录日志,不会阻塞当前的写操作。
风险
- 刚执行完第一步命令就宕机了,那么这个命令和相应的数据就有丢失的风险。
- 可能给下一个操作带来阻塞风险,因为AOF也是在主线程中执行的,如果在把日志写入磁盘时,磁盘压力大,就会导致写盘慢,进而导致后续操作无法执行。
分析发现,这两个风险都和AOF写回磁盘时机相关,这就意味着,我们如果能够控制一个写命令执行完后AOF 日志写回磁盘的时