Redis的RESP协议真的这么简单?抓包分析

934 阅读2分钟

听说 Redis 协议很简单,那今天就抓个包来一起看看吧。

RESP 是什么

官网

Redis 的序列化协议, 是一种二进制协议,支持多种数据类型,其中,数据的第一个字节(First byte)决定其类型,使用( CRLF \r\n)作为协议的终止符。

特点:易于实现,快速解析,可直接阅读

目前有 RESP2 和 RESP3(Redis6开始) 两个版本。

支持这么多种类型 👇

RESP data typeMinimal protocol versionCategoryFirst byte
Simple stringsRESP2Simple+
Simple ErrorsRESP2Simple-
IntegersRESP2Simple:
Bulk stringsRESP2Aggregate$
ArraysRESP2Aggregate*
NullsRESP3Simple_
BooleansRESP3Simple#
DoublesRESP3Simple,
Big numbersRESP3Simple(
Bulk errorsRESP3Aggregate!
Verbatim stringsRESP3Aggregate=
MapsRESP3Aggregate%
SetsRESP3Aggregate~
PushesRESP3Aggregate>

下面开始会用 Linux 上的 nc 命令 和 Wireshark 来抓包部分命令进行分析。

简单字符串 和 整数

# 简单字符串
+OK\r\n

# 整数
:[<+|->]<value>\r\n
比如
:0\r\n和:1000\r\n

通过 nc 命令,连接到 Redis Server,可以清楚看到每一个指令。

:表示整数

简单错误

-Error message\r\n
比如
-ERR unknown command 'asdf'
-WRONGTYPE Operation against a key holding the wrong kind of value

Bulk strings 大字符串

$<length>\r\n<data>\r\n
比如
$5\r\nhello\r\n
$0\r\n\r\n

大字符串,支持 512 MB,可以通过 redis.conf 中的 proto-max-bulk-len 修改

针对 null 的情况

$-1\r\n

resp2的情况👇

从 Wireshark 中抓包可以看到,Response 5 个字节,$-1\r\n

resp3 设计了 Nulls 类型来处理 null

这里需要通过 hello 去升级协议,但是我 window 上 redis-cli 的版本比较低,不支持,会报错。

折腾了好一会,感觉在 window 上装这个 redis 超级麻烦,索性用 Nginx 去代理转发。

因为 Wireshark 装在 window 上,但是这个 redis 跑在虚拟机上的,如果直接连接 redis-server ,Wireshark 抓不到 VMnet8 网卡上的流量。

启用 Nginx 代理 TCP 流量

redis-cli 针对 null 解析成 nil 表示。

可以看到返回 3 个字节,_\r\n 刚好对上

数组

* 表示数组长度,这里是 6

$ 是字符串长度,比如 name 是 4.

再比如 list 类型的。

lrange mylist 0 -1

Set

升级到 resp3 后,第一个字节是 ~ ,对应上面的表格

没升级的情况还是数组的表示方式 *

用 Redis-cli 发出去的 Request 请求也是一样,比如这里 *2\r\n$8\r\nsmembers\r\n$5\r\nmyset\r\n ,刚好 29 个字节。

参考文章

redis.io/docs/latest… (官网文档)

github.com/redis/redis… (官网文档)

结尾

好久没上这个官网看,发现这个外观变化挺大的(反复确认没找错 😱)

没想到 Redis7 已经支持上这个 向量 了,这就是 AI 浪潮吗!(我先去了解下,争取下文来分享下这个 向量数据库 😝 )

本文就到这里啦,感谢您的阅读,有不对的地方也请您帮忙指正!谢谢~😋

喜欢的小伙伴们,别忘了点赞关注呀~😋 祝你有个美好的一天!😝

github.com/Java4ye 😆