Redis RESP协议如何实现

227次阅读
没有评论

共计 1817 个字符,预计需要花费 5 分钟才能阅读完成。

本文丸趣 TV 小编为大家详细介绍“Redis RESP 协议如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Redis RESP 协议如何实现”文章能帮助大家解决疑惑,下面跟着丸趣 TV 小编的思路慢慢深入,一起来学习新知识吧。

回顾 RESP 协议

RESP 是基于 TCP 来实现的 Redis 通信协议,该协议是以 /r/n(行) 进行分割的,协议支持 5 种类型,具体信息如下:

类型前缀备注简单字符串 + 简单字符串以 + 开头错误数据 - 错误数据以 - 开头整数: 整数以: 开头复杂字符串 $ 复杂字符串以 $ 开头数组 * 数组以 * 开头

即,我们向 redis 发送命令:set name pdudo,其实发送的具体信息是

*3
pdudo

而服务器返回的信息也是类似的,只不过还需要了解 + 和 -,这 2 个前缀分别代表正确消息和错误的消息。

我们准备 2 个例子,我们来敲一下

例子 1

set name pdudo

例子 2

lpush pdudo data1
lpush pdudo data2
lrange pdudo 0 -1

快来动动你的小手指,看能不能根据 RESP 协议规则,将上述例子命令敲出来。现在你体会到了 Redis 官网介绍 RESP 协议时所述的 简单 和 易读 可么?

对于 RESP 来说,一定要搞清楚协议后,最好能够手写协议去执行,再考虑写程序去实现协议!!!

如何拆解 RESP 协议

终于到了喜闻乐见的环节了,我们要拆解和组装协议了。那我们至少来解决如下 3 个问题:

该协议是基于 TCP 流的,我们如何判断整个命令什么时候结束?

如何拆解命令?

协议什么时候结束

一般而言,我们自己在使用 TCP 传输数据,都会在数据开头定义 2 个或者 4 个字节,用于存储该数据有多少个字节,这样方便检验接收,类似于这种情况。

而 RESP 有意思了,它是以 /r/ n 来分割的。最前面会以前缀来判断其类型,例如我们发送命令,其会用到的前缀有 * 以及 $,那么我们如何来判断,我们要读取多少个 /r/ n 呢?

因为上述 * 代表数组,即有多少组数据需要处理,图中为 n。

而 $ 表示复杂字符串,即需要获取 m 个字符数据,不包含 /r/n

如何拆解 RESP 协议

若要拆解命令,则我们得获取命令,如上图所示,报文 $m,其实记录的有 m 长度的数据 (不包含 \r\n),所以我们可以这样来写伪代码。

根据如上,我们很容易写出伪代码。

func toArgs(rd *bufio.Reader) {data , _ , _ := rd.ReadLine()
 switch data[0] {
 case  * :
 n := data[1:] //  循环 n 次
 for i:=0;i i++ {toArgs(rd)
 case  $ :
 m := data[1:] //  获取 m 个数据
 //  获取 m 长度的数据即可
}

如上我们先获取前缀为 * 的,继而获取其值 n,我们则循环 n 次,即可获取该报文的数据。而前缀为 $ 的,我们可以直接获取该 m 长度的数据即可,这里主要要处理一下 \r\n。

将命令构建 RESP 报文规范,根据拆解反操作就可以了,这里暂不介绍了。

上述,我们核心功能已经探讨完毕了。

功能实现

代码已经编写完毕,放置在了 gitee 上: gitee

如上我们已经学会了如何拆解和组装 RESP 协议了,我们接着来看,我们如何用 go 来编写拆解和组装协议的代码呢?我们可以看。

我们先创建一个字符,然后将其封装为 bufio.Reader,我们来看下:

因为我们要使用 readLine() 函数,所以我们需要将其转换为 bufio.Reader 类型,若是直接从 net.Conn 中获取,不用转换,直接可以使用 bufio.Reader 的。

我们将上述伪代码编写一下,实现拆解的功能。

其具体执行过程是我们先获取一行数据,放置到 data 中,而后判断其前缀是什么,若是 * 则取其后面的数据,将其转为 int 类型 n,而后再递归该函数 n 次,而后中遇到 $,我们则取后面的数据,也是将其转为 int 类型 m,而后再取 m 长度的实际数据,这就是我们的命令了,最后我们再踢掉命令的 \r\n 即可。

其中,有一个函数是 byteToInt 是我们自己写的通过切片转为数字的函数,我们看下

该函数主要的功能是将其 []byte 数字转换为 int 数据。

如上,我们整个 RESP 协议功能写完了,我们运行下看下实际效果:

很显然,我们成功拆解了该数据。

读到这里,这篇“Redis RESP 协议如何实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-13发表,共计1817字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)