Redis的RESP协议抓包分析

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

RESP是什么

图片[1]-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,可以清楚看到每一个指令。

图片[2]-Redis的RESP协议抓包分析-编程社

:表示整数

图片[3]-Redis的RESP协议抓包分析-编程社

简单错误

-Error message\r\n
比如
-ERR unknown command 'asdf'
-WRONGTYPE Operation against a key holding the wrong kind of value
图片[4]-Redis的RESP协议抓包分析-编程社

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 修改

图片[5]-Redis的RESP协议抓包分析-编程社

针对 null 的情况

$-1\r\n

resp2的情况

图片[6]-Redis的RESP协议抓包分析-编程社

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

图片[7]-Redis的RESP协议抓包分析-编程社

resp3 设计了 Nulls 类型来处理 null

图片[8]-Redis的RESP协议抓包分析-编程社

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

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

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

启用Nginx代理TCP流量

图片[9]-Redis的RESP协议抓包分析-编程社

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

图片[10]-Redis的RESP协议抓包分析-编程社

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

图片[11]-Redis的RESP协议抓包分析-编程社

数组

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

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

图片[12]-Redis的RESP协议抓包分析-编程社
图片[13]-Redis的RESP协议抓包分析-编程社

再比如 list 类型的。

lrange mylist 0 -1
图片[14]-Redis的RESP协议抓包分析-编程社
图片[15]-Redis的RESP协议抓包分析-编程社

Set

图片[16]-Redis的RESP协议抓包分析-编程社

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

图片[17]-Redis的RESP协议抓包分析-编程社

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

图片[18]-Redis的RESP协议抓包分析-编程社

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

图片[19]-Redis的RESP协议抓包分析-编程社



参考文章

https://redis.io/docs/latest/develop/reference/protocol-spec/ (官网文档)

https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md (官网文档)

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称

    暂无评论内容