MongoDB 有线协议

1,059 阅读6分钟

MongoDB内部

MongoDB 遵循传统 RDBMS 中常见的客户机-服务器体系结构。

客户机-服务器体系结构包括一个服务器和多个连接到服务器的客户机。在分片和复制的场景中,多个服务器——而不是仅仅一个——形成拓扑。在独立模式或集群和分片拓扑中,数据从客户机传输到服务器,再传输回来,并在节点之间传输。

BSON 规格

MongoDB 以类似 JSON 的二进制格式(称为 BSON)对存储的文档进行编码,

BSON 文档是零个或多个二进制键/值对的集合。构成 BSON 表示的基本二进制类型如下:

Byte-1 byte

int32-4 byte

int64-8 byte

double-8 byte

Int32和 int64分别对应于32位和64位有符号整数。Double 对应于64位 IEEE754浮点值。

示例:

{“ hello”: “ world”}

此类文件可以使用 BSON 表示如下:

* x16 x00 x00 x00 x02he1lo x00 x06 x00 x00 x00wor1d x00 x00 x00”这里显示的 BSON 符号使用熟悉的 C 语义进行二进制值表示,使用十六进制等价物。

如果将可读文档映射为二进制表示法,则应如下所示:


{ and }-“ x16 x00 x00 and x00“ 

hello”:-x02hello x00

"world"-\x06\x00\x00\x00wor1d\x00

MongoDB 有线协议

客户机使用简单的基于 TCP/IP 的套接字连接与 MongoDB 服务器通信。用于通信的有线协议是一个简单的基于请求-响应的套接字协议。有线协议头和有效负载是 BSON 编码的。消息的排序遵循小 endian 格式,这与 BSON 的格式相同。

在标准的请求-响应模型中,客户机向服务器发送请求,服务器对请求作出响应。根据有线协议,请求通过消息头和请求有效负载发送。

响应返回一个消息头和响应有效负载。请求和响应之间的消息头的格式非常相似。但是,请求的格式和响应有效负载并不相同。

下图描述了客户机和 MongoDB 服务器之间的基本请求-响应通信。

image.png

MongoDB 连接协议允许许多操作,允许的操作如下:

  • OP_INSERT (代码: 2002)-插入一个文档。 CRUD 术语中的“创建”操作。

  • OP_UPDATE (code: 2001)-更新文档。 CRUD 中的更新操作。

  • OP_QUERY (code: 2004)-Querya 文档集合。 CRUD 中的“读”操作。

  • OP_GET_More (代码: 2005)-从查询中获取更多数据。查询响应可以包含大量文档。为了提高性能并避免发送整个文档集,数据库引入了游标的概念,该概念允许增量获取记录。

  • OpP_GET_more 操作有助于通过游标获取其他文档。

  • OP_REPLY (代码: 1)-回复客户端请求。此操作发送响应以回复

  • OP_QUERY 和 oP_GET_more 操作。

  • OP_KILL_CURSORS (代码: 2007)-关闭游标的操作。

  • OP_DELETE (代码: 2006)-删除文档。

  • OP_MSG (代码: 1000)-通用消息命令。每个请求和响应消息都有一个消息头:

  • 信息的长度(以字节为单位)。矛盾的是,长度包括4个字节来保存长度值。

  • RequestID ——一个唯一的消息标识符。客户端或服务器可以生成该标识符,具体取决于启动操作的是哪个客户端或服务器。

  • Response seTo ——对于 oP _ QUERY 和 oP _ GET _ more,来自数据库的响应包括来自原始客户机请求的 requestID 作为 response To 值。这允许客户端将请求映射到响应。

  • RequestID ——一个唯一的消息标识符。客户端或服务器可以生成该标识符,具体取决于启动操作的是哪个客户端或服务器。

  • Response seTo ——对于 oP _ QUERY 和 oP _ GET _ more,来自数据库的响应包括来自原始客户机请求的 requestID 作为 response To 值。这允许客户端将请求映射到响应。操作代码。

接下来,介绍几个简单和常见的请求-响应场景。

插入一个文档

在创建和插入新文档时,客户机通过一个请求发送一个 OP_INSERT 操作,该请求包括:

  • 消息头——包括 messageLlength、 requestID、 response to 和 opCode 的标准消息头结构。

  • Int32值-Zero (只是为将来使用而保留)。

  • Cstring-完全限定的集合名称

一个名为 aDatabase 的数据库中的一个。数组-此数组包含需要插入到集合中的一个或多个文档。

数据库处理一个插入文档请求,您可以通过调用 getLastError 命令查询请求的结果。但是,数据库没有显式发送与插入文档请求相对应的响应。

查询集合

当查询集合中的文档时,客户端通过一个请求发送一个 OP _ QUERY 操作。它通过一个涉及 OP _ REPLY 操作的数据库响应接收一组相关的文档。来自客户端的 OP _ QUERY 消息包括:

  • 消息头——包含 messageLlength、 requestID、 response To 和 opcode 元素的标准头。

  • Int32值-包含表示查询选项的标志。这些标志定义了游标、结果流和一些切分停止时的部分结果的属性。例如,您可以定义在返回最后一个数据之后游标是否应该关闭,并且您可以指定在一段特定的不活动时间之后是否应该超时空闲游标。

  • A cstring-完全限定的集合名称。

  • 一个 int32值-要跳过的文档数量。

  • 另一个 int32值-要返回的文档数。对应于这个请求的具有 OP _ REPLY 操作的数据库响应接收文档。如果返回的文档比返回的多,通常也会返回一个游标。此属性的值有时根据驱动程序及其限制结果集的能力而变化。

  • BSON 格式的查询文档-包含必须与搜索的文档匹配的元素。

  • 一个文档-表示要返回的字段。这也是 BSON 格式。

为了响应客户机 OP _ QUERY 操作请求,MongoDB 数据库服务器使用 OP _ REPLY 进行响应。来自服务器的 OP _ REPLY 消息包括:

  • 消息头——客户端请求和服务器响应中的消息头非常相似。另外,如前所述,opP _ REPLY 的 response To 头属性将包含相应 OP _ QUERY 的客户端请求的 requestID 值。

  • Int32值-包含通常表示错误或异常的响应标志情况。响应标志可能包含有关查询失败或无效游标 ID 的信息。

  • Int64值-包含允许客户端获取更多文档的游标 id。A

  • Int32值-游标中的起始点。

  • 另一个 int32值-返回的文档数

  • 数组-包含响应查询返回的文档。

到目前为止,只提供了一个有线协议的样本。

文档都存储在服务器上。客户机与服务器交互以插入、读取、更新和删除文档。

您已经看到,客户机和服务器之间的交互涉及高效的二进制格式和有线协议。


本文正在参加「金石计划 . 瓜分6万现金大奖」