redis学习--redis客户端协议(RESP协议)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:     redis客户端与服务端通信,使用RESP(REdis Serialization Protocal,redis序列化协议)协议通信,该协议是专门为redis设计的通信协议,但也可以用于其它客户端-服务器通信的场景。

    redis客户端与服务端通信,使用RESP(REdis Serialization Protocal,redis序列化协议)协议通信,该协议是专门为redis设计的通信协议,但也可以用于其它客户端-服务器通信的场景。RESP协议的设计初衷如下:

  • 实现简单;
  • 快速解析;
  • 可阅读;

    RESP可以用于序列化不同的数据类型,如:整型、字符串、数组...并且为错误提供专门的类型;客户端发送请求时,以字符串数组的作为待执行命令的参数。redis服务器根据不同的命令返回不同的数据类型。

    RESP是二进制安全协议,并且处理批量数据无须逐个请求处理,因为批量数据传输时,在请求参数中添加了数据长度作为前缀。传输层基于TCP协议,默认端口为6739。

注:RESP协议仅用作redis客户端和服务端之间通信。redis集群节点之间使用另一种二进制协议进行数据交换。

请求-响应模型

    redis客户端请求都是基于"命令 + 参数"形式的,对数据的CRUD操作以及对redis节点的控制操作都被抽象为命令。每个命令根据需要可以包含0到多个参数。比如:info命令用于查看当前redis服务器节点的运行状况,不需要参数;而get命令用于获取指定key对应的value值,因而需要指定一个key作为参数;mget用于同时获取多个key对应value值,则可以指定多个key作为参数;
大部分redis请求都是基于"请求-应答"方式的,但存在如下两种例外情况:
1)Pipeline支持:redis支持pipeline方式进行数据请求,整个请求过程类似一个流水线,客户端可以一次发送多个命令给服务端,然后异步等待结果返回,这样客户端可以自行决定一个合适的时机接收返回结果。通过pipeline的方式,相比于逐个发送命令同步处理,效率获得了极大的提升。
2)pub/sub支持:redis支持pub/sub模式的消息处理,允许客户端订阅服务端的一个channel。当有特定消息产生时,服务端会推送消息给对应channel的客户端,而客户端无需主动发送命令获取消息。此时,协议的语义发生了改变,由"请求-应答"方式变为了"订阅-发布"方式。

RESP协议描述

    RESP协议支持5种数据类型:简单字符串(Simple Strings)、错误数据(Errors)、整数(Integers)、批量字符串(Bulk Strings)、数组(Arrays);客户端请求服务器时,会以批量数据类型的数组进行请求封装;服务端发送响应给客户端时,根据命令实现的不同,返回相应的数据类型。不同的数据类型根据请求/响应报文的第一个字节进行区分:

  • 简单字符串以+开头
  • 错误数据以-开头
  • 整数以:开头
  • 批量字符串以$开头
  • 数组以*开头

RESP协议的不同部分使用"rn"(CRLF)进行分隔;

简单字符串类型(Simple Strings)

    以+开头,后面跟字符串,以rn结尾;字符串中不能包含r或者n字符。简单字符串类型都是单行数据,用以最小的开支传输非二进制安全的字符串;比如,许多命令回复OK作为操作成功的标识,编码为简单字符串类型后占用5个字节,如下:

"+OK\r\n"

注:
1)如果需要发送二进制安全的字符串,则需要改用批量字符串类型;
2)作为简单字符串类型的客户端实现,返回给调用者的内容应该是介于+和rn之间的内容;

错误类型(Errors)

    RESP中将错误作为一种专门的类型,格式类似于简单字符串类型,区别是:

  • 错误类型用于返回错误消息给客户端;
  • 错误类型以-开头;

错误类型用于发生错误时,返回消息给调用方,比如,使用了数据类型不支持的操作,或者使用了不存在的命令等。错误消息的格式如下:

"-Error message\r\n"

如下是错误消息返回样例:

-ERR unknown command 'foobar'
-WRONGTYPE Operation against a key holding the wrong kind of value

注:作为客户端实现,当接收到错误类型消息时,应该向调用方抛出异常;上例中,-后面跟着的大写字符串ERR和WRONGTYPE用于标识错误类型,这是redis的内部规范而并非是RESP本身的规范。

整型(Integers)

    可以理解为表示整数的简单字符串类型;以:开头,以rn结尾,中间的字符串都由整数组成;比如:1000编码后变为如下格式:

:1000\r\

    redis中的许多命令都返回整数,比如:incr、llen、lastsave等,这些命令返回的整数意义由命令本身的含义决定,incr表示对一个整数进行原子自增运算,llen返回指定list的长度,lastsave则是返回一个时间戳。整型的范围不能超过64位有符号数的范围;
    整型类型也可以用于标识状态,比如:EXIST命令,用于判断一个key是否存在,存在返回1,不存在返回0;DEL命令,用于删除一个key,如果执行了删除操作,且删除成功返回1,如果未执行操作,返回0;

批量字符串类型(Bulk Strings)

    批量字符串类型,用于表示二进制安全的字符串,最大长度支持512MB。格式如下:

  • 以$开头,紧接着是一个用于标识包含传输字符串字节个数的数字,以rn结尾;
  • 待传输的字符串数据;
  • 以rn结尾标识消息的结束;

比如:字符串"foobar"编码后,格式如下:

"$6\r\nfoobar\r\n"

空字符串的表示:如果消息为空字符串"",则编码如下:

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

Null值的表示:如果消息返回Null值,则编码如下:

"$-1\r\n"

注:区别null值和空字符串的不同,作为redis客户端实现,当接收到服务端返回的Null值时,不应该对调用方返回空字符串,而应该返回一个null值,不同的编程语言环境对null值的表示不同,比如:java中为null,C语言中为NULL,Ruby中为nil;

数组类型(Arrays)

redis客户端请求命令均是存放在数组类型中,同样,如果一个命令需要返回多条数据也可以使用数组类型,比如LRANGE命令,使用数组类型返回list中的一个多条数据;数组类型的编码规则如下:

  • 以*开头,随后跟一个用于标识数组元素数量的实数,以rn结尾;
  • 跟随多个数组元素,数量与上面指定的数量相同,每个数组元素都是嵌套RESP中的一种数据类型的数据;
  • 一个数组类型不要求其数组元素为同一种类型,可以是混合类型;
  • 数组类型同样可以嵌套数组类型;

比如:存放"foo"和"bar"两个批量字符串的数组,编码后格式如下:

"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"

空数组的表示:

"*0\r\n"

Null数组的表示:

"*-1\r\n"

注:区别Null数组和空数组的不同,作为redis客户端实现,当接收到服务端返回的Null数组时,不应该对调用方返回空数组;

嵌套数组的表示:[ [ 1, 2, 3 ], [ "Foo", "Bar" ] ]

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

数组中Null元素的表示:[ "foo", null, "bar" ]

*3\r\n
$3\r\n
foo\r\n
$-1\r\n
$3\r\n
bar\r\n

内联命令(Inline Commands)

为了方便通过telnet等工具人工与redis服务器进行交互操作,redis允许一种称为内联命令的格式进行交互。
比如:
1)客户端发送PING,服务端返回PONG:

C: PING
S: +PONG

2)判断一个key是否存在:

C: EXISTS somekey
S: :0

RESP协议的高性能

    因为RESP协议中对于批量字符串和数组类型都会通过在内容前面加一个长度标识(prefixed lengths)来表示批量字符串的长度或者数组包含的元素个数,因此解析的时候,不需要像json等格式一样,为了查找某个特殊字符,就需要逐个扫描全部报文,而是可以根据这些长度标识跳过不关注的字符;从而提高解析的性能。这使得RESP协议既保持了文本协议的可读性和简单性,又具有和二进制协议接近的性能。
如下为C语言查找长度标识的示例:

#include <stdio.h>

int main(void) {
    unsigned char *p = "$123\r\n";
    int len = 0;

    p++;
    while(*p != '\r') {
        len = (len*10)+(*p - '0');
        p++;
    }

    /* Now p points at '\r', and the len is in bulk_len. */
    printf("%d\n", len);
    return 0;
}

参考

RESP协议官方文档:Redis Protocol specification

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
NoSQL Redis 数据安全/隐私保护
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
文章提供了Redis最流行的图形化界面工具Another Redis Desktop Manager的下载及使用教程,包括如何下载、解压、连接Redis服务器以及使用控制台和查看数据类型详细信息。
96 6
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
|
1月前
|
NoSQL Redis 数据库
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
文章提供了Redis图形化界面工具的下载及使用教程,包括如何连接本地Redis服务器、操作键值对、查看日志和使用命令行等功能。
99 0
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
|
27天前
|
NoSQL 数据可视化 Linux
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
本文介绍了Redis的两个可视化管理工具:付费的Redis Desktop Manager和免费的Another Redis DeskTop Manager,包括它们的下载、安装和使用方法,以及在使用Another Redis DeskTop Manager连接Redis时可能遇到的问题和解决方案。
86 1
redis学习四、可视化操作工具链接 centos redis,付费Redis Desktop Manager和免费Another Redis DeskTop Manager下载、安装
|
12天前
|
NoSQL 网络协议 算法
Redis 客户端连接
10月更文挑战第21天
23 1
|
24天前
|
NoSQL Linux Redis
Docker学习二(Centos):Docker安装并运行redis(成功运行)
这篇文章介绍了在CentOS系统上使用Docker安装并运行Redis数据库的详细步骤,包括拉取Redis镜像、创建挂载目录、下载配置文件、修改配置以及使用Docker命令运行Redis容器,并检查运行状态和使用Navicat连接Redis。
171 3
|
30天前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
52 8
|
26天前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
22 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
30天前
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
22 3
|
30天前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
35 2
|
1月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
164 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习