目录
[原理篇 - 01.Redis 原理课程介绍](#原理篇 - 01.Redis 原理课程介绍)
[原理篇 - 02.Redis 数据结构 - 动态字符串](#原理篇 - 02.Redis 数据结构 - 动态字符串)
[原理篇 - 03.Redis 数据结构 - intset](#原理篇 - 03.Redis 数据结构 - intset)
[原理篇 - 04.Redis 数据结构 - Dict](#原理篇 - 04.Redis 数据结构 - Dict)
[原理篇 - 05.Redis 数据结构 - Dict的渐进式rehash](#原理篇 - 05.Redis 数据结构 - Dict的渐进式rehash)
[原理篇 - 06.Redis 数据结构 - ZipList](#原理篇 - 06.Redis 数据结构 - ZipList)
[原理篇 - 07.Redis 数据结构 - ZipList的连锁更新问题](#原理篇 - 07.Redis 数据结构 - ZipList的连锁更新问题)
[原理篇 - 08.Redis 数据结构 - QuickList](#原理篇 - 08.Redis 数据结构 - QuickList)
[原理篇 - 09.Redis 数据结构 - SkipList](#原理篇 - 09.Redis 数据结构 - SkipList)
[原理篇 - 10.Redis 数据结构 - RedisObject](#原理篇 - 10.Redis 数据结构 - RedisObject)
[原理篇 - 11.Redis 数据结构 - 五种数据类型 - String](#原理篇 - 11.Redis 数据结构 - 五种数据类型 - String)
[原理篇 - 12.Redis 数据结构 - 五种数据类型 - List](#原理篇 - 12.Redis 数据结构 - 五种数据类型 - List)
[原理篇 - 13.Redis 数据结构 - 五种数据类型 - Set](#原理篇 - 13.Redis 数据结构 - 五种数据类型 - Set)
[原理篇 - 14.Redis 数据结构 - 五种数据类型 - ZSet](#原理篇 - 14.Redis 数据结构 - 五种数据类型 - ZSet)
[原理篇 - 15.Redis 数据结构 - 五种数据类型 - Hash](#原理篇 - 15.Redis 数据结构 - 五种数据类型 - Hash)
[原理篇 - 16.Redis 网络模型 - 用户空间与内核空间](#原理篇 - 16.Redis 网络模型 - 用户空间与内核空间)
[原理篇 - 17.Redis 网络模型 - 阻塞 IO](#原理篇 - 17.Redis 网络模型 - 阻塞 IO)
[原理篇 - 18.Redis 网络模型 - 非阻塞 IO](#原理篇 - 18.Redis 网络模型 - 非阻塞 IO)
[原理篇 - 19.Redis 网络模型 - IO 多路复用](#原理篇 - 19.Redis 网络模型 - IO 多路复用)
[原理篇 - 20.Redis 网络模型 - IO 多路复用之 select](#原理篇 - 20.Redis 网络模型 - IO 多路复用之 select)
[原理篇 - 21.Redis 网络模型 - IO 多路复用之 poll](#原理篇 - 21.Redis 网络模型 - IO 多路复用之 poll)
[原理篇 - 22.Redis 网络模型 - IO 多路复用之 epoll](#原理篇 - 22.Redis 网络模型 - IO 多路复用之 epoll)
[原理篇 - 23.Redis 网络模型 - epoll 的 ET 和 LT 模式](#原理篇 - 23.Redis 网络模型 - epoll 的 ET 和 LT 模式)
[原理篇 - 24.Redis 网络模型 - 基于 epoll 的服务端流程](#原理篇 - 24.Redis 网络模型 - 基于 epoll 的服务端流程)
[原理篇 - 25.Redis 网络模型 - 信号驱动 IO 及异步 IO](#原理篇 - 25.Redis 网络模型 - 信号驱动 IO 及异步 IO)
[原理篇 - 26.Redis 网络模型 - Redis 是单线程吗,为什么用单线程](#原理篇 - 26.Redis 网络模型 - Redis 是单线程吗,为什么用单线程)
[原理篇 - 27.Redis 网络模型 - 多线程及多线程网络模型变更](#原理篇 - 27.Redis 网络模型 - 多线程及多线程网络模型变更)
[原理篇 - 28.Redis 通信协议 - RESP 协议](#原理篇 - 28.Redis 通信协议 - RESP 协议)
[原理篇 - 29.Redis 通信协议 - 基于 Socket 的自定义 Redis客户端](#原理篇 - 29.Redis 通信协议 - 基于 Socket 的自定义 Redis客户端)
[原理篇 - 30.Redis 内存回收 - 过期 key 处理](#原理篇 - 30.Redis 内存回收 - 过期 key 处理)
[原理篇 - 31.Redis 内存回收 - 内存淘汰策略](#原理篇 - 31.Redis 内存回收 - 内存淘汰策略)
原理篇 - 01.Redis 原理课程介绍

原理篇 - 02.Redis 数据结构 - 动态字符串


问题:flags=1表示什么?
flags 值 类型宏定义 对应结构体 len/alloc 类型 最大可存储字符串长度 适用场景 0 SDS_TYPE_5sdshdr5(已废弃)5bit 长度 31 字节 极短字符串 1 SDS_TYPE_8sdshdr8uint8_t(1 字节)255 字节 短字符串(如图中的 "name",长度 4)2 SDS_TYPE_16sdshdr16uint16_t(2 字节)65535 字节 中等长度字符串 3 SDS_TYPE_32sdshdr32uint32_t(4 字节)4GB 长字符串 4 SDS_TYPE_64sdshdr64uint64_t(8 字节)2^64 字节 超大字符串


原理篇 - 03.Redis 数据结构 - intset




原理篇 - 04.Redis 数据结构 - Dict



原理篇 - 05.Redis 数据结构 - Dict的渐进式rehash





原理篇 - 06.Redis 数据结构 - ZipList





原理篇 - 07.Redis 数据结构 - ZipList的连锁更新问题


原理篇 - 08.Redis 数据结构 - QuickList



问题:count和len区别?
因为QuickList里面存的是zipList,而zipList里面存的是entry


原理篇 - 09.Redis 数据结构 - SkipList




原理篇 - 10.Redis 数据结构 - RedisObject



原理篇 - 11.Redis 数据结构 - 五种数据类型 - String




原理篇 - 12.Redis 数据结构 - 五种数据类型 - List


原理篇 - 13.Redis 数据结构 - 五种数据类型 - Set




原理篇 - 14.Redis 数据结构 - 五种数据类型 - ZSet




原理篇 - 15.Redis 数据结构 - 五种数据类型 - Hash



原理篇 - 16.Redis 网络模型 - 用户空间与内核空间



原理篇 - 17.Redis 网络模型 - 阻塞 IO

原理篇 - 18.Redis 网络模型 - 非阻塞 IO

原理篇 - 19.Redis 网络模型 - IO 多路复用



原理篇 - 20.Redis 网络模型 - IO 多路复用之 select

原理篇 - 21.Redis 网络模型 - IO 多路复用之 poll

原理篇 - 22.Redis 网络模型 - IO 多路复用之 epoll


原理篇 - 23.Redis 网络模型 - epoll 的 ET 和 LT 模式

问题:什么是惊群现象?
一堆进程 / 线程都在等同一个事件,事件一来,所有人同时被唤醒抢资源,最后只有一个人能拿到,其他人白醒一次,白白浪费 CPU。
原理篇 - 24.Redis 网络模型 - 基于 epoll 的服务端流程

原理篇 - 25.Redis 网络模型 - 信号驱动 IO 及异步 IO


原理篇 - 26.Redis 网络模型 - Redis 是单线程吗,为什么用单线程


原理篇 - 27.Redis 网络模型 - 多线程及多线程网络模型变更









原理篇 - 28.Redis 通信协议 - RESP 协议


原理篇 - 29.Redis 通信协议 - 基于 Socket 的自定义 Redis客户端

问题:代码实现?
javapackage com.company; import java.io.*; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; public class Main { static Socket s; static PrintWriter writer; static BufferedReader reader; public static void main(String[] args) { try { // 1.建立连接 String host = "192.168.150.101"; int port = 6379; s = new Socket(host, port); // 2.获取输出流、输入流 writer = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8)); reader = new BufferedReader(new InputStreamReader(s.getInputStream(), StandardCharsets.UTF_8)); // 3.发出请求 // 3.1.获取授权 auth 123321 sendRequest("auth", "123321"); Object obj = handleResponse(); System.out.println("obj = " + obj); // 3.2.set name 虎哥 sendRequest("set", "name", "虎哥"); // 4.解析响应 obj = handleResponse(); System.out.println("obj = " + obj); // 3.2.set name 虎哥 sendRequest("get", "name"); // 4.解析响应 obj = handleResponse(); System.out.println("obj = " + obj); // 3.2.set name 虎哥 sendRequest("mget", "name", "num", "msg"); // 4.解析响应 obj = handleResponse(); System.out.println("obj = " + obj); } catch (IOException e) { e.printStackTrace(); } finally { // 5.释放连接 try { if (reader != null) reader.close(); if (writer != null) writer.close(); if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } private static Object handleResponse() throws IOException { // 读取首字节 int prefix = reader.read(); // 判断数据类型标示 switch (prefix) { case '+': // 单行字符串,直接读一行 return reader.readLine(); case '-': // 异常,也读一行 throw new RuntimeException(reader.readLine()); case ':': // 数字 return Long.parseLong(reader.readLine()); case '$': // 多行字符串 // 先读长度 int len = Integer.parseInt(reader.readLine()); if (len == -1) { return null; } if (len == 0) { return ""; } // 再读数据,读len个字节。我们假设没有特殊字符,所以读一行(简化) return reader.readLine(); case '*': return readBulkString(); default: throw new RuntimeException("错误的数据格式!"); } } private static Object readBulkString() throws IOException { // 获取数组大小 int len = Integer.parseInt(reader.readLine()); if (len <= 0) { return null; } // 定义集合,接收多个元素 List<Object> list = new ArrayList<>(len); // 遍历,依次读取每个元素 for (int i = 0; i < len; i++) { list.add(handleResponse()); } return list; } // set name 虎哥 private static void sendRequest(String ... args) { writer.println("*" + args.length); for (String arg : args) { writer.println("$" + arg.getBytes(StandardCharsets.UTF_8).length); writer.println(arg); } writer.flush(); } }
原理篇 - 30.Redis 内存回收 - 过期 key 处理









原理篇 - 31.Redis 内存回收 - 内存淘汰策略






末尾页
本文摘要: Redis原理课程系统介绍了Redis的核心数据结构和工作机制,包括:1) 5种动态字符串类型(SDS)及其适用场景;2) 6种底层数据结构实现如intset、Dict、ZipList等;3) 五种数据类型的存储结构;4) 网络模型演进过程,从阻塞IO到epoll多路复用;5) 单线程模型优势及多线程扩展;6) RESP通信协议及Java客户端实现示例;7) 内存回收策略包括过期key处理和淘汰机制。课程全面剖析了Redis高性能背后的设计原理,涵盖数据结构、网络通信、内存管理等核心模块。


