一、什么是 RESP 协议?
RESP(REdis Serialization Protocol) 是 Redis 使用的通信协议。
特点:
- 文本协议(可读,可直接 telnet)
- 简单
- 快速
- 支持 Pipeline(多条命令批处理)
- 支持多种数据类型
- 客户端与 Redis 所有交互都基于 RESP
Redis 5 之前默认 RESP2
Redis 6 起开始支持 RESP3,但仍兼容 RESP2
二、为什么 Redis 使用 RESP?
- 解析简单(基于行 + 前缀)
- 高性能(一次性读取全部命令)
- 支持批量、多参数、多命令(管道)
- 人类可读(调试方便)
- 易扩展(RESP3 解决更复杂的数据结构)
几乎所有语言的 Redis 客户端都实现了 RESP。
三、RESP2 五大数据类型
RESP2 支持五种数据类型:
| 类型 | 前缀 | 说明 |
|---|---|---|
| 简单字符串 | + |
OK 类消息 |
| 错误 | - |
执行错误 |
| 整数 | : |
数值 |
| 批量字符串(Bulk String) | $ |
二进制安全字符串 |
| 数组(Array) | * |
多条命令参数 |
下面逐个讲解。
四、RESP2 通信规则解析
4.1 简单字符串(Simple Strings)
格式:
+<string>\r\n
应用示例:
SET name jack
Redis 返回:
+OK\r\n
特点:
- 不包含换行符
- 常用于成功返回(OK、PONG)
4.2 错误(Errors)
格式:
-<error message>\r\n
示例:
GET
Redis 回复:
-ERR wrong number of arguments for 'get' command\r\n
错误消息只是一个字符串。
4.3 整数(Integer)
格式:
:<number>\r\n
示例:
INCR count
返回:
:1\r\n
适用于:
- INCR
- LLEN
- ZCARD
- HLEN
- EXISTS(返回 0/1)
4.4 批量字符串(Bulk Strings)
用于二进制安全的数据(包括图像、JSON 等)
格式:
$<length>\r\n<payload>\r\n
示例:
$4\r\njack\r\n
如果是 NULL:
$-1\r\n
示例:GET name
客户端发送(注意!客户端不会显示发送方式,但底层是这样):
*2
$3
GET
$4
name
Redis 返回:
$4
jack
4.5 数组(Arrays)
数组是多个 RESP 回复的集合。
格式:
*<count>\r\n
<item1>
<item2>
...
示例:
LRANGE list 0 -1
返回:
*3
$3
one
$3
two
$5
three
这是 Redis 命令参数与返回数据最重要的格式。
五、请求与响应的完整示例(非常重要)
客户端执行:
SET name jack
客户端底层发送实际内容为:
*3\r\n
$3\r\n
SET\r\n
$4\r\n
name\r\n
$4\r\n
jack\r\n
Redis 回复:
+OK\r\n
GET
*2\r\n
$3\r\n
GET\r\n
$4\r\n
name\r\n
Redis 回复:
$4\r\n
jack\r\n
六、RESP 如何支持 Pipeline
假设客户端 pipeline 发送三条命令:
SET a 1
SET b 2
GET a
客户端一次性发送:
*3 $3 SET $1 a $1 1
*3 $3 SET $1 b $1 2
*2 $3 GET $1 a
Redis 会:
- 读一次 socket
- 一次性解析
- 按顺序执行
- 一次性返回多个结果
返回:
+OK
+OK
$1
1
这就是 Pipeline 的实现基础。
七、RESP3(Redis 6+ 新协议)概述
RESP3 新增更多数据类型:
| 类型 | 前缀 |
|---|---|
| Map | % |
| Set | ~ |
| Double | , |
| Bool | # |
| Null | _ |
| Big Number | ( |
| Attribute | ` |
但 Redis 默认仍然使用 RESP2,RESP3 多用于新的客户端。
八、总结(背诵版)
RESP2 五大类型:
| 类型 | 前缀 | 示例 |
|---|---|---|
| 简单字符串 | + |
+OK |
| 错误 | - |
-ERR... |
| 整数 | : |
:100 |
| Bulk String | $ |
$3\r\nabc\r\n |
| 数组 | * |
*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n |
九、面试高频问题
1. Redis 使用的协议是什么?
RESP(Redis Serialization Protocol)
2. Redis 为什么不使用 JSON/HTTP?
- HTTP 开销大
- JSON 解析慢
- 无法支持二进制安全
- 无法支持 Pipeline
3. RESP2 中最常用的数据类型是什么?
Bulk String(因为大部分命令参数都是字符串)
4. RESP 支持二进制数据吗?
是的,Bulk String 是二进制安全的。
5. RESP3 是什么?解决什么问题?
提供更多原生数据类型(如 map、set、bool)