Redis 底层原理全解析SDS / 跳表 / IO多路复用 / 单线程模型 本篇目标从“会用 Redis” → “理解 Redis 为什么这么设计”掌握面试中的“底层原理问题”建立源码级思维一、Redis 为什么快在前面我们说过 Redis 快但这一篇我们从底层重新理解✅ 本质原因升级版Redis 快 数据结构优化 IO模型优化 架构设计优化拆解为 4 大核心1. 高效数据结构SDS / 跳表 2. 内存操作无磁盘IO 3. IO多路复用高并发 4. 单线程模型无锁二、Redis 字符串底层SDS问题为什么不用 C 原生字符串C 字符串charstr[]hello;问题❌ 需要遍历才能知道长度O(n)❌ 容易缓冲区溢出❌ 不支持动态扩展✅ Redis 解决方案SDSSimple Dynamic StringSDS 结构核心struct sdshdr { int len; // 已使用长度 int free; // 剩余空间 char buf[]; // 数据 }优势1️⃣ 获取长度 O(1)直接读取 len2️⃣ 防止缓冲区溢出自动扩容3️⃣ 空间预分配如果扩容 → 多分配一部分空间好处减少频繁内存分配4️⃣ 惰性释放删除后不立即回收空间面试回答模板Redis 使用 SDS 替代 C 字符串 优势 1. O(1) 获取长度 2. 防止缓冲区溢出 3. 空间预分配 惰性释放三、Redis 有序集合底层跳表SkipList为什么不用红黑树Redis 选择跳表的原因实现简单 性能接近平衡树跳表结构理解Level 3: 1 ----------- 9 Level 2: 1 ------ 5 -- 9 Level 1: 1 -- 3 -- 5 -- 7 -- 9数据结构组成每个节点包含Key存储的数据值或分数。Forward Pointers一个数组指向该节点在每一层的下一个节点。Level该节点拥有的层数高度。类似“多层索引”查找过程从最高层 max_level开始 1. 在当前层向右遍历直到下一个节点的值大于等于目标值。 2. 如果当前节点值等于目标值返回成功。 3. 否则**下降一层**重复步骤 1。 4. 如果下降到第 0 层仍未找到返回失败。时间复杂度查询 / 插入 / 删除O(log n)Redis 中的应用ZSet有序集合面试回答模板ZSet 使用跳表 hash 表实现 - 跳表 → 排序 - hash → 快速查找四、Redis List 底层QuickList为什么不用普通链表问题❌ 内存碎片多❌ 访问慢✅ QuickList链表 压缩列表LinkedList ZipList结构[ziplist] - [ziplist] - [ziplist]优势节省内存保持链表灵活性五、Redis IO 模型IO 多路复用问题Redis 如何处理高并发 单线程怎么处理上万连接✅ 答案IO 多路复用类比理解一个服务员同时负责多张桌子常见实现select(轮询通知)poll(改进的轮询通知)epollLinux 事件回调特性SelectPollEpoll底层机制轮询线性扫描轮询线性扫描回调/就绪列表效率连接数多时效率O(n)低下连接数多时效率O(n)低下效率O(1)与活跃连接数相关高并发下极高效最大连接数有限制FD_SETSIZE通常1024理论上无硬性限制无硬性限制受系统资源限制工作模式仅水平触发仅水平触发支持水平触发和边缘触发内存与数据拷贝每次调用需在内核和用户空间拷贝整个fd集合每次调用需拷贝整个pollfd数组使用内存映射共享内存减少拷贝开销使用复杂度中中较高需管理epoll实例跨平台几乎所有平台大部分Unix-like系统Linux特有工作流程1. 监听多个 socket 2. 哪个有数据 → 处理哪个优势不需要多线程高效处理大量连接面试回答模板Redis 使用 IO 多路复用epoll 可以在单线程下高效处理大量连接请求六、Redis 单线程模型Redis 真的是单线程吗 面试陷阱题✅ 正确答案核心命令执行是单线程但网络 IO → 多路复用持久化 → 子线程为什么用单线程1️⃣ 避免锁竞争多线程 → 加锁 → 性能下降2️⃣ 减少上下文切换3️⃣ 内存操作本身就很快❗ 面试加分点Redis 性能瓶颈 ≠ CPU 而是内存 网络七、Redis 内存淘汰策略问题内存满了怎么办✅ 8 种策略重点记 3 个策略说明noeviction不删除allkeys-lru ⭐最近最少使用allkeys-random随机volatile-lru有过期的 key 中淘汰推荐allkeys-lru最常用八、Redis 过期删除策略Redis 如何删除过期 key✅ 三种方式1️⃣ 定时删除 ❌不用2️⃣ 惰性删除用到才检查3️⃣ 定期删除随机抽查面试总结Redis 使用惰性删除 定期删除九、Redis 线程模型演进Redis 6 之后变化引入多线程处理 IO但命令执行仍然是单线程十、终极面试总结Redis 为什么这么快1. 内存操作 2. 高效数据结构SDS / 跳表 3. IO 多路复用 4. 单线程避免锁竞争Redis 底层核心结构String → SDS List → QuickList ZSet → 跳表Redis 线程模型核心单线程 IO多路复用 后台线程