大数据 -48 Redis 深入理解 Redis 通信机制:从 RESP 协议到 Reactor 事件驱动模型

点一下关注吧!!!非常感谢!!持续更新!!!
🚀 AI 篇持续更新中!(长期更新)
AI 炼丹日志-30-新发布【1T 万亿】参数量大模型!Kimi‑K2 开源大模型解读与实践,持续打造实用 AI 工具指南!📐🤖
💻 Java 篇正式开启!(300 篇)
目前 2025 年 07 月 21 日更新到:Java-77 深入浅出 RPC Dubbo 负载均衡全解析:策略、配置与自定义实现实战 MyBatis 已完结,Spring 已完结,Nginx 已完结,Tomcat 已完结,分布式服务正在更新!深入浅出助你打牢基础!
📊 大数据板块已完成多项干货更新(300 篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT 案例 详解
Redis 采用单线程+多路复用架构,通过事件驱动实现高并发处理。通信基于 RESP 协议,定义了简单字符串、错误、整数、批量字符串和数组五种数据格式,具有可读性强、易解析、支持二进制等优点。通信默认使用 TCP 长连接,支持串行和双工模式,其中 Pipeline 机制可显著提升吞吐量。Redis 内部使用 Reactor 模式处理 IO 事件,通过 aeEventLoop 统一管理网络事件和时间事件,底层利用 epoll 或 kqueue 实现高效的 IO 多路复用,避免多线程带来的锁竞争和上下文切换开销。整体设计简单高效,是其高性能关键所在。

章节内容
上节我们完成了:
Redis 的缓存机制
Redis 的淘汰策略
LRU LFU 等机制

通信协议
Redis 的单线程模型
Redis 采用单进程+单线程的架构设计,这种设计有以下特点:
所有操作都是原子性执行的,避免了多线程环境下的锁竞争问题
通过 I/O 多路复用技术处理大量并发连接
单线程简化了数据结构的实现,提高了性能
Redis 协议(RESP)
Redis Serialization Protocol (RESP)是应用系统与 Redis 服务端交互的通信协议,主要特点包括:
协议格式
RESP 定义了 5 种数据类型:
简单字符串(Simple Strings):以"+"开头,如 "+OK\r\n"
错误(Errors):以"-"开头,如 "-ERR unknown command\r\n"
整数(Integers):以":"开头,如 ":1000\r\n"
批量字符串(Bulk Strings):以"6\r\nfoobar\r\n"
数组(Arrays):以"*"开头,如 "*2\r\n3\r\nfoo\r\n3\r\nbar\r\n"
通信示例
客户端发送命令:
服务端响应:
应用场景
客户端库实现:各种语言的 Redis 客户端库都需要实现 RESP 协议
命令行交互:redis-cli 工具通过 RESP 与服务器通信
主从复制:Redis 集群中的主从节点通过 RESP 协议同步数据
协议优势
简单易实现
人类可读
高效解析
支持二进制安全的数据传输
响应模式
概念介绍
Redis 协议位于 TCP 层上,即客户端和 Redis 实例保持双工的连接。

串行模式
串行模式是一种最基本的客户端-服务器通信方式,其工作流程如下:
连接建立阶段:
客户端与服务端通过 TCP/IP 协议建立持久的长连接
连接建立后,双方通过心跳机制(ping-pong)保持连接活性
典型的心跳间隔通常为 30-60 秒,通过 ACK 应答确认连接状态
请求-响应流程:
客户端发送第一个请求报文
服务端处理该请求并返回响应
客户端必须完整接收到第一个响应后,才能发起第二个请求
每个请求都需要等待前一个请求完成才能继续
典型应用场景:
Telnet 协议:用于远程终端连接的标准协议
Redis-cli 工具:Redis 数据库的默认命令行接口
简单的 RPC 调用场景
性能特点:
网络延迟显著影响总吞吐量(RTT 时间累加)
无法充分利用网络带宽(存在大量空闲等待时间)
服务端资源利用率低(处理请求时存在等待间隔)
实现简单,无需考虑请求乱序问题
改进方向:
引入管道化(Pipeline)技术
采用多路复用(Multiplexing)方案
实现并行请求处理
这种模式虽然简单可靠,但因其串行处理的特性,在现代高并发场景中通常不是最优选择。

双工模式
双工模式是指通信双方可以同时进行双向数据传输的工作方式。在计算机网络中,TCP 协议就是一种典型的全双工通信协议。
批量请求与批量响应
在双工模式下,系统支持:
客户端可以一次性发送多个请求
服务器可以一次性返回多个响应
请求和响应可以交叉进行而不会混淆(得益于 TCP 的双工特性)
Pipline 技术详解
Pipline(管道)是一种优化网络通信性能的重要技术:
工作原理:
客户端将多个命令打包成一个批次
通过单个网络调用发送给服务器
服务器按顺序执行这些命令
将执行结果按顺序打包后返回
性能优势:
减少网络往返时间(RTT)
提高吞吐量
降低网络延迟影响
技术特点:
一次 pipline 操作包含:
多条命令的批量发送
仅需一次网络传输时间
命令执行结果的批量返回
应用场景:
数据库批量操作
消息队列的批量生产/消费
缓存系统的批量读取/写入
示例:在 Redis 中,使用 pipline 可以显著提高批量操作的效率:
后者只需一次网络往返即可完成 100 次 set 操作。
我们使用 Jedis 库可以很轻松的使用 pipline:
Redis 通信协议详解
RESP 协议概述
Redis 客户端与服务器之间的交互采用 REdis Serialization Protocol(RESP)序列化协议。这是一种简单高效的二进制安全协议,专为 Redis 设计,具有以下特点:
请求格式
请求以字符串数组的形式表示要执行的命令及其参数:
响应格式
Redis 使用以下特有数据类型作为回复:
简单字符串(Simple Strings):以"+"开头
错误(Errors):以"-"开头
整数(Integers):以":"开头
批量字符串(Bulk Strings):以"$"开头
数组(Arrays):以"*"开头
通信机制
连接方式
采用 TCP 协议建立连接
默认服务端口号:6379(可以通过配置修改)
支持 TLS 加密连接(需配置)
数据分隔
每条命令和数据都必须以 CRLF(\r\n)结尾
示例:
SET key value
命令实际传输为*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n
二进制安全特性
所有参数都是二进制安全的,可以包含任意字节
支持处理包含 null 字节(\x00)的数据
字符串长度按字节计算而非字符
典型交互示例
命令发送示例
发送GET counter
命令:
发送SET message "Hello World"
命令:
响应示例
成功响应:
错误响应:
整数响应:
批量字符串响应:
性能优化
管道机制(pipelining):允许一次性发送多个命令而不需要等待每个回复
连接复用:保持长连接减少 TCP 握手开销
批量操作命令:如 MSET、MGET 等减少网络往返次数
内联格式
可以使用 telnet 工具进行测试,发送一些内容过去
处理流程
处理流程
服务器启动监听
接受命令请求并解析
执行命令请求
返回命令回复
具体的过程图可以看下边的流程图片:

处理机制
Redis 服务器是典型的事件驱动系统,Redis 将事件分为两大类:
文件事件
时间事件
文件事件
文件事件即 Socket 读写事件,也就是 IO 事件,比如客户端连接、命令请求、数据回复、连接断开等等。
Reactor 模式详解
Redis 中的 Reactor 模式实现
Redis 采用单线程的 Reactor 模式作为其核心事件处理机制,这种设计使其能够在单个线程中高效处理大量并发连接。Reactor 模式属于 I/O 多路复用技术的一种典型实现方式,特别适合高并发、低延迟的场景。
I/O 多路复用基础
I/O 多路复用(Input/Output Multiplexing)是指使用单个线程管理多个 Socket 连接的技术。通过系统调用(如 select、poll、epoll 或 kqueue)监视多个文件描述符的状态变化,当某个 Socket 就绪时,应用程序就能立即得到通知并进行处理,而不需要为每个连接创建独立线程。
Reactor 模式核心组件
事件驱动架构:
整个系统围绕事件进行组织
事件包括:连接建立、数据到达、超时等
事件触发相应的处理逻辑
输入源(Event Sources):
一个或多个并发输入源(如网络 Socket)
可以是客户端连接、定时器事件等
Redis 中主要包括网络 I/O 事件和时间事件
服务处理器(ServiceHandler):
也称为 Dispatcher 或 Event Demultiplexer
负责监听和收集所有事件源产生的事件
在 Redis 中由 aeEventLoop 实现
请求处理器(RequestHandlers):
多个具体的事件处理器
每个处理器负责处理特定类型的事件
Redis 中包括:连接处理器、命令处理器等
工作流程
事件注册:
各种事件源向 ServiceHandler 注册感兴趣的事件
例如:注册 Socket 的可读事件
事件循环:
ServiceHandler 通过 I/O 多路复用 API(如 epoll)等待事件
当事件发生时,ServiceHandler 被唤醒
事件分发:
ServiceHandler 同步地将事件分发给对应的 RequestHandler
分发过程通常是通过回调机制实现的
事件处理:
RequestHandler 执行具体的业务逻辑
在 Redis 中,这包括解析命令、执行命令、返回响应等
Redis 中的具体实现
在 Redis 源码中,Reactor 模式的主要实现包括:
aeEventLoop:事件循环的核心结构体
aeApiPoll:封装底层 I/O 多路复用 API
aeCreateFileEvent:注册文件事件
aeCreateTimeEvent:注册时间事件
Redis 的事件处理流程示例:
客户端连接到 Redis 服务器的连接请求到达
aeEventLoop 通过 epoll 检测到新的连接事件
调用 acceptTcpHandler 处理新连接
当客户端发送命令数据时,触发读事件
调用 readQueryFromClient 处理命令请求
优势与局限
优势:
单线程避免了多线程的上下文切换开销
通过事件驱动实现高并发处理
逻辑简单,避免多线程同步的复杂性
局限:
受限于单线程,无法充分利用多核 CPU
长时间运行的命令会阻塞整个事件循环
大键操作可能影响响应时间
Redis 通过以下方式弥补局限:
对耗时操作(如持久化)使用子进程
6.0+版本支持 I/O 多线程(但仍保持单线程命令处理)
Reactor 图
下面这些图片可以让你更好地理解 Reactor 模式:


多路复用
IO 多路复用机制就是通过一种机制,一个进程可以监视多个描述符(Socket),一旦某个描述符就绪,能够通知程序进行相应的复写操作。IO 多路复用机制有这么几种:
select
poll
epoll
kqueue
Select
select 函数监视的文件描述符分 3 类:
writefds
readfds
exceptfds
调用后 select 函数会阻塞,直到有描述符就绪或者超时,函数返回。当 select 函数返回后,可以通过 fd 列表遍历,来找到就绪的描述符。
Select 优点
几乎在所有平台上都有支持,跨平台支持。
Select 缺点
单个进程打开文件描述有一定的限制,有 FD_SETSIZE 设置,默认是 1024 ,采用数组存储,另外在检查数组中是否有文件描述符需要读写时,采用的是线性的扫描(不管是否活跃都扫描轮询),效率较低。
Poll
poll 使用一个 pollfd 的指针实现,pollfd 结构包含了要监视的 Event 和 发生的 Event,不再使用 select 的参数值传递的方式。
Poll 优点
采用链表的形式存储,它监听的描述符数量没有限制,可以超过 select 默认限制的 1024 大小
Poll 缺点
另外在检查链表中是否有文件描述符需要读写时,采用线性扫描的方法,即不管 Socket 是不是活跃的,都轮询一次,效率较低。
epoll
epoll 子啊 Linux2.6 内核中提出的,是之前 select 和 poll 的加强版本。相对于 select 和 poll 来说,epoll 更加灵活,没有描述符限制。
epoll 使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的 copy 就只需要一次。
epoll 优点
epoll 没有最大并发连接限制,上限是最大能打开文件的数目,比如 1GB 内存大约能打开 10 万文件左右。epoll 最大的优点就在于只处理活跃的连接,而不需要轮询遍历,所以效率很高。
kqueue
kqueue 是 unix 下的一个 IO 多路复用库。最初是 2000 年在 FreeBSD 系统上开发的一个高性能的事件的事件通知接口。注册一批 Socket 描述符 kqueue 后,当其中描述符状态发生改变时,kqueue 将一次性通知应用程序哪些描述符可读可写或出错。
kqueue 优点
能处理大量数据,性能较高。
版权声明: 本文为 InfoQ 作者【武子康】的原创文章。
原文链接:【http://xie.infoq.cn/article/76da92b1338d7fb47fc3e0e3b】。文章转载请联系作者。
评论