MongoDB 有线协议
注意
本 MongoDB 传输协议规范根据 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 美国许可证 进行许可。您不得出于任何商业目的使用或改编本材料,例如创建商业数据库或数据库即服务产品。
简介
MongoDB 传输协议是一种基于套接字的简易请求-响应式协议。客户端可通过常规 TCP/IP 套接字与数据库服务器进行通信。
TCP/IP 套接字
客户端应使用常规 TCP/IP 套接字连接数据库。
端口
mongod
和mongos
实例的默认端口号为 27017 。mongod
和 mongos
的端口号可配置,且可能不同。
字节排序
MongoDB 传输协议中的所有整数均采用小端字节顺序:即,最低有效字节在前。
消息类型和格式
MongoDB 将 OP_MSG 操作码同时用于客户端请求和数据库回复。旧版本的 MongoDB 采用多种消息格式,而这些格式现已弃用并替换为 OP_MSG
。
注意
该页面使用类似 C 语言的 struct
来描述消息结构。
本文档中使用的类型(例如int32
和cstring
)与BSON规范中定义的类型相同。
标准消息头
一般来说,每条消息均包含一个标准消息头,并后跟特定于请求的数据。标准消息头的结构如下:
struct MsgHeader { int32 messageLength; // total message size, including this int32 requestID; // identifier for this message int32 responseTo; // requestID from the original request // (used in responses from the database) int32 opCode; // message type }
字段 | 说明 |
---|---|
messageLength | 消息的总大小(以字节为单位)。该总数包括保存消息长度的 4 个字节。 |
requestID | 客户端或数据库生成的标识符,可用于唯一标识此消息。 |
responseTo | 从客户端消息中获取的 requestID 。 |
opCode | 消息类型。请参阅操作码以了解详细信息。 |
操作码
MongoDB 使用以下 opCode
值:
操作码名称 | 值 | Comment |
---|---|---|
OP_COMPRESSED | 2012 | 使用压缩包装其他操作码 |
OP_MSG | 2013 | 使用标准格式发送消息。同时用于客户端请求和数据库回复。 |
OP_REPLY Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 1 | 回复客户端请求。 responseTo 已设置。 |
OP_UPDATE Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2001 年 | Update document. |
OP_INSERT Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2002 | 插入新文档。 |
RESERVED | 2003 | 之前曾供 OP_GET_BY_OID 使用。 |
OP_QUERY Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2004 年 | 查询一个集合。 |
OP_GET_MORE Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2005 | 从查询中获取更多数据。参见游标。 |
OP_DELETE Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2006 | 删除文档。 |
OP_KILL_CURSORS Deprecated in MongoDB 5.0. Removed in MongoDB 5.1. | 2007 | 通知数据库该客户端已完成游标操作。 |
OP_COMPRESSED
任何操作码都可以压缩并包装在 OP_COMPRESSED
标头中。OP_COMPRESSED
消息包含原始压缩操作码消息以及处理和解压缩该消息所需的元数据。
OP_COMPRESSED
消息的格式为:
struct { MsgHeader header; // standard message header int32 originalOpcode; // value of wrapped opcode int32 uncompressedSize; // size of deflated compressedMessage, excluding MsgHeader uint8 compressorId; // ID of compressor that compressed message char *compressedMessage; // opcode itself, excluding MsgHeader }
字段 | 说明 |
---|---|
MsgHeader | 消息头,如标准消息头中所述。 |
originalOpcode | 包含封装操作码的值。 |
uncompressedSize | 缩小后的 compressedMessage 的大小,其中不含 MsgHeader 。 |
compressorId | 压缩此消息的压缩器的 ID。 compressorId 值的列表如下所示。 |
compressedMessage | 操作码本身,不包括 MsgHeader 。 |
为每个压缩器均分配了一个预定义的压缩器 ID,如下所示:
compressorId | 握手值 | 说明 |
---|---|---|
0 | noop | 此消息的内容未压缩。此举意在用于测试。 |
1 | snappy | 此消息的内容使用 snappy 进行压缩。 |
2 | zlib | 此消息的内容使用 zlib 进行压缩。 |
3 | zstd | 此消息的内容使用 zstd 进行压缩。 |
4-255 | reserved | 保留以供将来使用。 |
OP_MSG
OP_MSG
是一种可扩展消息格式,它可用于对线路上的客户端请求和服务器回复进行编码。
OP_MSG
格式如下:
OP_MSG { MsgHeader header; // standard message header uint32 flagBits; // message flags Sections[] sections; // data sections optional<uint32> checksum; // optional CRC-32C checksum }
字段 | 说明 |
---|---|
header | 标准消息头,如标准消息头中所述。 |
flagBits | 包含消息标志的整数位掩码,如标志位中所述。 |
sections | 消息正文部分,如消息部分中所述。 |
checksum | 可选的 CRC-32C 校验和,如校验和中所述。 |
标记位
flagBits
整数是位掩码编码标志,用于修改 OP_MSG
的格式和行为。
前 16 位 (0-15) 必须进行设置;如果设置了未知位,解析器则必须报错。
最后 16 位 (16-31) 是可选的,解析器必须忽略任何未知的计算置位。代理和其他消息转发器必须在转发消息之前清除任何未知的可选位。
Bit | 名称 | 请求 | 响应 | 说明 |
---|---|---|---|---|
0 | checksumPresent | ✓ | ✓ | |
1 | moreToCome | ✓ | ✓ | 另一条消息将紧随其后,而接收者无需执行后续操作。接收者在收到 moreToCome 设为 0 的消息之前不得发送其他消息;因为发送操作可能会阻塞,从而导致死锁。已设置 moreToCome 位的请求不会收到回复。仅当响应已设置 exhaustAllowed 位的请求时,回复才会设置此位。 |
16 | exhaustAllowed | ✓ | 客户端已准备好使用 此举可仅当请求者的网络层已为多个回复做好准备时才发送多个回复。 |
部分
一条 OP_MSG
消息包含一个或多个部分。每个部分都以指示其类型的 kind
字节开头。kind
字节之后的所有内容构成该部分的有效负载。
可用的部分类型如下。
类型 0:正文
正文部分会编码为单个 BSON 对象。BSON 对象中的此大小也会用作该部分的大小。此部分类型为标准命令请求和回复正文。
所有顶级字段均须具有唯一名称。
第 1 类:文档序列
类型 | 说明 |
---|---|
int32 | 该部分的大小(以字节为单位)。 |
C 字符串 | 文档序列标识符。在所有当前命令中,该字段是它从正文部分替换的(可能是嵌套的)字段。 此字段不得同时存在于正文部分。 |
零个或多个 BSON 对象 |
|
Kind 2
此部分专供内部使用。
校验和
每条消息均可能以 CRC-32C [2] 校验和结尾,而其中涵盖了消息中除校验和自身之外的所有字节。
如果不使用 TLS/SSL 连接,则 mongod
个实例和 mongos
个实例将通过校验和来交换消息。
如果使用 TLS/SSL 连接,mongod
实例和 mongos
实例会跳过校验和。
如果显示带有校验和的消息,驱动程序和较旧的二进制文件将忽略校验和。
校验和的存在由 checksumPresent
标记位指示。
传统操作码
从 MongoDB 5.1 开始,这些操作码已被移除,取而代之的是 OP_MSG:
OP_DELETE
OP_GET_MORE
OP_INSERT
OP_KILL_CURSORS
OP_QUERY
[1]OP_REPLY
OP_UPDATE
如果您运行的是旧版本的 MongoDB 并且需要有关先前操作码的详细信息,请参阅旧版操作码。
脚注
[1] | MongoDB 5.1 已删除对 OP_QUERY 查找操作和 OP_QUERY 命令的支持。但有一例外:运行 hello 和 isMaster 命令以作为连接握手的一部分仍然支持 OP_QUERY 。 |
[2] | 使用 Castagnoli 多项式计算出的 (1,2)32 位 CRC ,如 https://tools.ietf.org/html/rfc4960#page-140所述。 |