如何设计 RQData 通讯协议 - Ricequant米筐量化

本文详细介绍了RQData的通讯协议设计,包括序列化协议和传输协议,并对比了Redis、MySQL和gRPC的协议。RQData采用MessagePack作为序列化协议,支持TCP长连接和流式传输,优化了数据获取速度。文章还讨论了不同协议的优缺点,如Redis的可读性,MySQL的复杂性和gRPC的HTTP/2支持。
摘要由CSDN通过智能技术生成

前面我们介绍了 RQData 如何用 Asyncio 来提高服务端性能,这次我们介绍一下 RQData 的通讯协议,通过对比 RQData 的通讯协议和一些常用程序的通讯协议,看看如何设计一个合适的通讯协议。

互联网上两台计算机进行通讯的基础是网络传输协议——数据在网络上以字节流的形式从一台计算机传输到另一台计算机,如果没有双方约定好的协议,就无法将数据流重塑成我们需要的数据结构。这就像是一个家长拆了一个用积木搭成的城堡,然后把一个一个积木递给小孩子,小孩子根据记忆用这些积木把城堡再重新搭起来。上述过程就是通讯协议涉及的内容,也是我们在讨论通讯协议所需要关心的事。

 

背景知识

讲解通讯协议之前,我们先介绍一下计算机是如何存储数据的。

计算机最小的存储单位是比特( bit ),一个比特有两种状态——1 和 0 。计算机里大部分部件是用晶体管组成的,晶体管有导通和截止两种状态,在数字电路里分别表示 1 和 0 。八个比特是一个字节( byte ),一个字节是大多数计算机语言能处理数据的最小单位 。1 个字节能表示的无符号整型范围是 0-255 ( 2 的 8 次方),如果大于 255 就需要用 2 个字节来表示,这时 2 个字节就有了先后排序的选择:假如 2 个字节的多位数中,低位放在较小的位置上,高位放在较大的位置上,称为小端排序,反之是大端排序。比如说 65280 需要用 11111111 和 00000000 表示,如果表示为 1111111100000000 就是小端排序,0000000011111111 就是大端排序。网络传输一般都是用大端排序,所以大端排序也被称为网络序。

程序中的对象需要转变为有意义的字节序列(类似于城堡到积木的过程)才能在网络中传输,之后字节序列被接收端反转成为一个相同的对象(类似于积木到城堡的过程),对象转为字节序列的这个过程称为序列化,也被称为编码,字节序列转变回对象的过程称为反序列化,也常被称为解码。

统一解决序列化 /反序列化以及数据传输问题的工具就是通讯协议。因此,我们在关注通讯协议的时候主要关注两个方面:

  • 序列化协议是怎么做的;
  • 在连接中,消息怎么传输的。

接下来我们就来看看几个常用的软件是怎么处理这两方面内容的。

 

Redis

Redis 是一个应用非常广泛的内存数据库,是现在最流行的键值对存储数据库之一。Redis 有 5 种基本的数据结构,分别是字符串、列表、哈希表、无序集合和有序集合。接下来我们从序列化协议和传输协议两方面来分析一下 Redis 是如何传输这些数据结构的。

序列化协议

Redis 的通讯协议设计上是可阅读的,它通过 CRLF (也就是 word 中的回车符,字符串表示为 “\r\n”)来分隔不同的参数。Redis 的序列化协议是自己定制的,通过第一个字符来表明返回的类型,序列化的数据结构支持以下类型:

  • 单行字符串:返回的第一个字节是 “+” ;
  • 多行字符串:返回的第一个字节是 “$” ;
  • 错误信息:返回的第一个字节是 “-” ;
  • 整形数字:返回的第一个字节是“ : ” ;
  • 数组:返回的第一个字节是“ * ”。

接下来具体介绍一下上述数据结构类型。

01 字符串

一个简单的字符串回复是 “+OK\r\n”,单行字符串仅表示状态,比如说一个键值成功返回 OK 的设置就会使用单行字符串。如果字符串复杂或含有 \r\n 字符,Redis 则会通过多行字符串回复,一个多行字符串有如下结构 “ $6\r\nfoobar\r\n ”,一个 $ 后面跟着一个数字来表示字符串的长度,数字和字符串的内容以 CRLF 分割,最后仍旧以一个 CRLF 结束。空字符串长度为 0,表示为 “$0\r\n\r\n”。此外,当多行字符串长度为 -1,且只有一个 CRLF 时,特殊地表示为 NULL (无值),格式是 “$-1\r\n”

02 错误

如果出现错误,返回的第一个字符是 -, 接着的一行内容是错误的描述, 通常用空格区分错误类型和错误描述, 比如 “-WRONGTYPE Operation against a key holding the wrong kind of value”, 表示请求的键值对应的类型不是期望的类型。

03 整形数字

返回类型是数字时,第一个字符是:,以 CRLF 结尾,以字符串表示而非二进制。比如 “:0\r\n”“:512\r\n” 都是整数回复。整形 0 和 1 也被广泛地用于表示逻辑真和逻辑假,比如说判断一个键值存不存在,就通过返回“ 0 ”表示不存在,返回“ 1 ”表示存在。

04 数组

返回类型为数组时,第一个字符是 *,紧接着是数组的长度 n,接下来就是 n 的具体内容 ——n 个上述提到的多个类型的数据。一个包含整形和字符串的 2 个元素的数组例子如下(多行结尾省略 CRLF )ÿ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值