redis 应用层协议解析以及在 Python 客户端中的实现

本文深入解析Redis的应用层协议 RESP,包括简单字符串、错误、整数、二进制安全字符串、数组和Pipeline的实现。同时,讨论了redis-py客户端如何处理协议解析和报文构造。此外,探讨了redis-py-cluster在Pipeline上的实现和局限性,并展望了RESP3可能带来的改进。
摘要由CSDN通过智能技术生成

笔者:安大
网易游戏高级运维工程师,主要工作方向为网易游戏 Redis Saas 的开发与运维,也关注 Python 和 Rust 的最新进展。怕什么真理无穷,进一寸有进一寸的欢喜。

在这里插入图片描述
有任何疑问欢迎关注微信公众号:网易游戏运维平台。(长按识别上图二维码)
微信公众号原文链接:redis 应用层协议解析以及在 Python 客户端中的实现

Redis 的应用层协议设计

Redis 的通信协议设计得非常简单,具体可以参考 Redis Protocol specification,简称 RESP,在此进行一个大致的介绍。

RESP 本身并没有专门的字段标记整个请求的报文长度,它的设计思路整体针对于 命令管道(Pipeline)的需求,可以很方便地将多条命令封装在一次 tcp 报文发送中,比如:

当我们发送一个 GET A 命令,对应的报文如下:

*2\r\n$3\r\nGET\r\n$1\r\nA\r\n

而如果通过 Pipeline 发送 GET AGET B 两条命令时,并不需要什么额外处理,仅仅是将两条命令按顺序发送:

*2\r\n$3\r\nGET\r\n$1\r\nA\r\n*2\r\n$3\r\nGET\r\n$1\r\nB\r\n

接下来我们进行一个较为详细完整的解析

RESP 规定了五种数据类型:

  • 简单字符串(Simple Strings):以 + 作为开头,一般用于简单的字符串回复,比如 set A B 这类命令的返回报文中的 OK,就是封装在简单字符串类型中。

  • 错误(Errors):以 - 作为开头,用于返回错误信息,比如输入了一条不存在的命令,redis 服务会返回 ERR unknown command 'xx',这条错误信息就封装在错误类型报文中。

  • 整数(Integers):以 : 开头,用于返回整数结果,比如 LLEN 命令,当我们用它统计某个列表长度时,返回的数字就封装在整数类型中。

  • 二进制安全字符串(Bulk Strings):以 $ 作为开头,用于承载携带数据,是最重要最常用的类型,当你向 Redis 发送命令时,命令中的字符串会被封装在二进制安全字符串,比如开篇的例子中GET就被封装成了$3\r\nGET\r\n这样一个二进制安全字符串报文,而一个正常 GET 命令的返回报文同样是一个二进制安全字符串。

  • 数组(Arrays):以 * 开头,同样是最重要最常用的类型,开篇的例子中 GET A 命令中的两个字符串 GETA 分别被封装成了 $3\r\nGET\r\n$1\r\nA\r\n,然后被进一步封装成了一个数组类型 *2\r\n...,我们对 Redis 所有发送的命令都会被这样封装,先是子字符串被封装成二进制安全字符串,然后二进制安全字符串被封装成数组发往服务端。

以下是更为详细的示例:

1.1 简单字符串(Simple Strings)

简单字符串的回复通常是固定的,可以类似的理解为静态字符串,这种通常表达一种确定的、可预期的结果,比如最常见的就是 OK 和事务中返回的 QUEUED

127.0.0.1:6379> set a b
OK
127.0.0.1:6379> 

OK 这个字符串不会有任何改变,也不需要携带可变的信息,它仅仅是标识这个操作成功了,不会包含其他任何可变的数据。它以 + 为开头,以 \r\n 为结尾,比如 OK 的报文就是

+OK\r\n

1.2 错误(Errors)

错误与简单字符串非常相似,不同的是它以 - 作为开头,其他并没有什么不同,它仅仅是显示一个错误信息,而这个信息在协议上并没有什么强制的规范,可以写入任意字符串信息,当然错误字符串中是不能写 \r\n

比如命令不存在的报错 ERR unknown command 'tt' 封装结果就是

-ERR unknown command 'tt'\r\n

1.3 整数(Integers)

整数类型也很简单,和前两种不同的是,它是可以携带数据的,类型为有符号64位整数,用于一些返回整数类型的命令,目前文档显示,会返回整数的有以下这些命令,

  • SETNX
  • DEL
  • EXISTS
  • INCR
  • INCRBY
  • DECR
  • DECRBY
  • DBSIZE
  • LASTSAVE
  • RENAMENX
  • MOVE
  • LLEN
  • SADD
  • SREM
  • SISMEMBER
  • SCARD

当然 Redis 的官方文档一直都不是很靠谱,RESP 很久没更新了,目前来看至少用于 Stream 功能的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值