redis协议指的是什么?

分类:编程技术 时间:2024-02-20 15:17 浏览:0 评论:0
0
本文主要介绍redis协议指的是什么。文章中的介绍非常详细,有一定的参考价值。感兴趣的朋友一定要读一下!

Redis客户端通过一种名为RESP(REdis Serialization Protocol,redis序列化协议)的协议与Redis服务器进行交互。虽然该协议是为Redis设计的,但它也可以用于其他客户端-服务器架构的软件系统。 (译注:从一些公开信息来看,陌陌的IM协议设计参考了Redis协议)

RESP权衡以下几个方面:

实现需要简单、易分析。快速且易于阅读

RESP可以序列化不同的数据类型,例如整数、字符串、数组,并且还为错误设计了特殊类型。客户端以字符串参数数组的形式发送请求到Redis服务器执行,Redis返回与命令相关的数据类型。

RESP 是二进制安全的并且不需要解析从一个进程发送到另一个进程的批量数据,因为它使用长度前缀来传输批量数据。

注意:这里提到的协议仅用于客户端-服务器通信。 Redis Cluster 使用不同的二进制协议在节点之间进行消息交换。

网络层

客户端通过6379端口建立TCP连接与Redis通信。

虽然RESP在技术上与TCP无关,但对于Redis来说该协议仅用于 TCP(或其他流协议,例如 Unix 域协议)。 (译注:Memcached则相反,支持TCP和UDP,但实际上生产环境基本只使用TCP,我认为这是一种过度设计,可能会被黑客利用来进行memcached UDP反射.)

请求响应模型

Redis接收由不同参数组成的命令。收到命令后,将对其进行处理并将响应发送到客户端。

泰s 是最简单的模型,但有两个例外:

Redis 支持流水线(稍后会提到)。因此客户端可以一次发送多个命令并等待响应。当客户端订阅 Pub/Sub 通道时,该协议将改变其语义并成为推送协议,这意味着客户端不需要发送命令,因为服务器收到消息后会自动向客户端发送新消息(客户端订阅的频道)。

除了这两点之外,Redis协议是一个简单的请求-响应协议。

RESP协议说明

RESP协议是在Redis 1.2中引入的,但现在已经成为Redis 2.0的标准交互协议。实现 Redis 客户端时应使用此协议。

RESP实际上是一个序列化协议,支持以下类型:简单字符串、错误、整数、批量字符串和数组。

RESP,作为请求重新sponse 协议在 Redis 中的使用如下:

客户端以 RESP Bulk Strings 数组的形式向 Redis 服务器发送命令。服务器实现不同的命令并返回相应的RESP实现。

在RESP中,某些数据的类型由第一个字节确定:

对于SIMple Strings,响应的第一个字节是“+”,对于Errors,响应的第一个字节对于整数,响应的第一个字节是“-”,对于批量字符串,响应的第一个字节是“:”,对于数组,响应的第一个字节是“$”,对于数组,响应的第一个字节是“ *"

此外,RESP可以使用特殊的Bulk String或数组来表示Null值,稍后会提到。

在 RESP 中,协议的不同部分始终用“\r\n”(CRLF) 分隔。

RESP 简单字符串

简单字符串编码如下:一个加号,后跟一个不包含 CR 或 LF 字符(无换行符)的字符串,以 CRLF 结尾(“\r \n")结束。

简单字符串可以轻松传输非二进制安全字符串。例如,许多 Redis 命令在成功时会响应“OK”,这是用 RESP 简单字符串编码的 5 个字节:

"+OK\r\n"

To传输二进制安全字符串,使用 RESP Bulk Strings。

当Redis响应简单字符串时,客户端库应该向调用者返回从第一个“+”字符到字符串末尾的字符串,不包括CRLF字节。

RESP 错误

RESP 有一种特殊的错误数据类型。实际上错误就像RESP简单字符串一样,但第一个字符串是“-”而不是加号。 RESP 中的 Simple Strings 和 Errors 之间的真正区别在于,错误被客户端视为异常,而构成 Error 类型的字符串是字符串本身。基本格式为:

"-Error message\r\n"

错误响应只有在发生错误时才会发送,例如您操作了数据类型错误,或者命令执行错误es 不存在等。当收到 Error 响应时,客户端应该抛出异常。

以下是错误响应的示例:

-ERRknown command 'foobar'-WRONGTYPE 针对持有错误类型值的键进行操作

第一个空格或新行之间第一个单词的“-”表示要返回的错误类型。这只是Redis本身的约定,并不是RESP Error指定的格式。

例如,ERR 是一般错误,而 WRONGTYPE 是更具体的错误,表示客户端尝试对错误的数据类型进行操作。这称为错误前缀,允许客户端知道服务器返回的错误类型,而无需依赖可能随时更改的确切消息描述。

客户端实现可能会针对不同的错误返回不同类型的异常,或者向调用者返回表示错误的字符串。但是,这个功能不是必需的,因为它很有用s,并且一些精益客户端实现可能只是返回通用错误条件,例如 false。

RESP 整数

此类型是以 CRLF 结尾的字符串,表示整数,以“:”字节开头。例如,“:0\r\n”或“:1000\r\n”是整数响应。

许多 Redis 命令返回 RESP 整数,例如 INCR、LLEN 和 LASTSAVE。

返回的整数没有特殊含义。是INCR的增加数、LASTSAVE的UNIX时间戳等。但是返回的整数保证在6位4位有符号整数的范围内。

整数响应也广泛用于表示真或假。 EXISTS 和 SISMEMBER 等命令将返回 1(表示 true)和 0(表示 false)。

以下命令将返回一个整数:SETNX、DEL、EXISTS、INCR、INCRBY、DECR、DECRBY、DBSIZE、LASTSAVE、RENAMENX、MOVE、LLEN、SADD、SREM、SISMEMBER、SCARD。

RESP 批量字符串

批量字符串用于表示带有最大长度512M。

Bulk Strings的编码格式如下:

“$”后跟字符串字节数(前缀长度),以CRLF结尾,以实际字符串CRLF结尾< /p>

因此字符串“foobar”被编码为:

“$6\r\nfoobar\r\n”

空字符串:< /p>

"$0\r\n\r\n"

RESP Bulk String还可以使用表示Null值的特殊格式来表示不存在的值。这种特殊格式的长度值为-1,没有数据,所以Null表示为:

"$-1\r\n"

这样称为空散装字符串。

当服务器返回 Null Bulk String 时,客户端 API 不应返回空字符串,而应返回 nil 对象。例如,Ruby 库应返回“nil”,而 C 库应返回 NULL(或在返回的对象上设置特殊标志)等。

RESP 数组

客户端使用RESP 数组将命令发送到 Redis 服务器。同样,一些Redis命令也使用RESP Arra返回元素集合时,使用 ys 作为返回类型。一个示例是 LRANGE 命令,它返回元素列表。

RESP 数组使用以下格式发送:

“*”是第一个字节,后面是数组中的元素数量,然后是 CRLF。然后是数组中每个 RESP 类型代表的元素。

例如空数组表示为:

"*0\r\n"

两个RESP Bulk的数组编码字符串“foo”和“bar”为:

“*2\r\n$3\r\nfoo \r\n$3\r\nbar\r\n”

可以看到,数组前面的*CRLF之后,数组中的其他数据类型依次连接在一起。例如,包含三个整数的数组编码如下:

"*3\r\n:1\r\n:2\r\n:3\r\n"

数组可以包含混合类型,并不要求所有元素都是同一类型。例如,具有 4 个整数和 1 个批量字符串的数组可以编码为:

*5\r\n:1\r\n:2 \r\n:3\r\n:4\r\n$6\r\nfoobar\r\n

(为清楚起见,响应分为多行)。

服务器发送的第一行 *5\r\n 表示后面将有 5 个响应,然后发送代表元素的每个响应。

Null 数组的概念也存在,是 Null 值的替代方案(通常使用 Null Bulk String,但由于历史原因我们同时拥有两种格式)。

例如,当BLPOP命令超时时,返回一个长度为-1的Null数组,如下所示:

"*-1\r\n"

当服务器返回Null数组时,客户端库API应该返回null对象而不是空数组。需要区分返回空列表和其他情况(例如BLPOP命令超时)。

< p>RESP允许数组的数组,例如包含两个数组的数组编码如下:

*2\r\n*3\r\ n:1\r\n:2\ r\n:3\r\n*2\r\n+Foo\r\n-Bar\r\n

高效解析Redis协议

虽然Redis协议很容易阅读和实现,但是可以有效率二进制协议。

RESP 使用长度前缀来传输批量数据,因此无需扫描数据负载中是否存在 JSON 等特殊符号,也无需在数据负载周围添加引号。

Bulk和Multi Bulkk-length处理可以一次处理一个字符,并且可以同时扫描CR字符,如下面的C代码:

#include int main( void) { unsigned char *p = "$123\r\n"; int len = 0; p++; while(*p != '\r') { len = (len*10)+(*p - '0' ); p++; /* 现在p指向'\r',len在bulk_len中。 */ printf("%d\n", len); return 0;}

当识别出CR后,后面的LF可以忽略不做处理。然后可以一次性读取大量数据,而无需分析数据负载。剩余的 CR 和 LF 字符串可以被丢弃而不被处理。

与二进制协议进行性能比较时,Redis 协议非常简单,可以用大多数高级语言实现,从而减少了客户端软件中的错误数量。

注:

1.协议中的CR和LF相当于分隔符。命令之间存在多个 CRLF 不应影响后续解析。应忽略多个 CRLF。 。例如:

$> (printf "PING\r\nPING\r\nPING\r\n\r\n\rPING\r\n" ; 睡眠 1) | nc 本地主机 6379+PONG+PONG+PONG+PONG

2.相比memcached协议,redis协议确实设计得更简单:

(1)一致的请求形式。 Redis 请求全部作为 Bluk 字符串数组发送。不同的命令仅在数组中具有不同数量的元素。所有命令的处理可以先读取整个数组,然后根据不同的命令解析数组的参数;而不是不同的要求l就像 mc 协议一样。命令格式不同,因此在读取网络字节流的过程中,不同的命令必须进行不同的处理,这增加了协议分析的难度。

(2)长度前缀是高效协议解析的关键。字段长度信息不是二进制的,也可以是专利和文本协议。

以上就是redis协议所指的全部内容。感谢您的阅读!希望分享的内容对大家有所帮助。更多相关知识,欢迎关注行业资讯频道!

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > redis协议指的是什么?

用户评论