>데이터 베이스 >Redis >Redis RESP 프로토콜 구현 예에 대한 자세한 설명

Redis RESP 프로토콜 구현 예에 대한 자세한 설명

WBOY
WBOY앞으로
2022-09-06 17:36:582043검색

추천 학습: Redis 비디오 튜토리얼

세그먼테이션을 위한 RESP 프로토콜

RESP是基于TCP来实现的Redis通信协议,该协议是以/r/n(라인) 검토, 프로토콜은 5가지 유형을 지원하며 구체적인 정보는 다음과 같습니다:

유형 접두사 Remarks
단순 문자열 + +
로 시작하는 단순 문자열 - 오류 데이터는 -
Integer 으로 시작합니다. : 정수는 다음으로 시작합니다.
복잡한 문자열 $ 복잡한 문자열은 $
Array * 배열은 *
로 시작합니다.

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

*3
$3
set
$4
name
$5
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<n;i++ {
			toArgs(rd)
		}
	case &#39;$&#39;:
		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协议功能写完了,我们运行下看下实际效果:

분명히 우리는 데이터를 성공적으로 분해했습니다.

이 글에서는 RESP 프로토콜의 내용을 간단히 분해하기 위해 go를 사용하는 방법을 소개합니다. /code> 마스터-슬레이브 미들웨어는 어떻습니까? go简单的拆解RESP协议的内容,为什么我们不介绍如何编写redis主从中间件呢?

最开始是打算这样写的,但是知识多了,介绍起来会很杂,很难把一个点讲清楚,所以我们就单独挑了一个核心点来介绍,我愿意将其称之为面向核心编程(我的基友很早之前告诉我的),所谓的面向核心编程简而易在就是我们在涉及一个功能的时候,要学会拆解该功能,将核心功能先用demo做出来,而后再慢慢丰富周边,从而完成整个需求涉及。

最后我们再来聊聊RESP원래 이렇게 쓰려고 했는데, 지식이 너무 많으면 서론이 너무 복잡해지고, 한 가지 포인트를 명확하게 설명하기 어려워서 핵심 포인트만 골라 소개하려고 합니다. 코어 지향 프로그래밍(내 친구가 오래 전에 말해줬습니다) 소위 코어 지향 프로그래밍은 간단하고 쉽습니다. demo를 사용하여 만들어진 다음 주변 영역을 천천히 풍부하게 만들어 전체 요구 사항 패키지를 완성합니다. 마지막으로 RESP 프로토콜에 대해 이야기해 보겠습니다. 공식 웹사이트에서는 이를 간단한 구현, 빠른 분석

,

직접 읽기 가능으로 요약합니다. 이 두 글을 주의깊게 연구한다면, 당신은 분명히 이 점에 대해 깊은 이해를 갖게 될 것입니다.

추천 학습: 🎜Redis 비디오 튜토리얼🎜🎜

위 내용은 Redis RESP 프로토콜 구현 예에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 jb51.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제