MongoDB 线程协议
注意
本 MongoDB 线程协议规范受以下许可协议的许可:Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License。您不得将此材料用于任何商业目的,例如创建商业数据库或数据库即服务产品。
简介
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 | 消息类型。有关详细信息,请参阅 Opcodes。 |
Opcodes
MongoDB 使用这些 opCode
值
操作码名称 | 值 | 注释 |
---|---|---|
OP_COMPRESSED | 2012 | 使用压缩封装其他操作码 |
OP_MSG | 2013 | 使用标准格式发送消息。用于客户端请求和数据库响应。 |
OP_REPLY 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 1 | 响应客户端请求。设置 responseTo 。 |
OP_UPDATE 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 2001 | 更新文档。 |
OP_INSERT 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 2002 | 插入新文档。 |
RESERVED | 2003 | 以前用于 OP_GET_BY_OID。 |
OP_QUERY 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 2004 | 查询集合。 |
OP_GET_MORE 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 2005 | 从查询中获取更多数据。请参阅游标。 |
OP_DELETE 自 MongoDB 5.0 开始弃用。在 MongoDB 5.1 中已删除。 | 2006 | 删除文档。 |
OP_KILL_CURSORS 自 MongoDB 5.0 开始弃用。在 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 }
字段 | 描述 |
---|---|
消息头 | 消息头,如《标准消息头》中所述。 |
originalOpcode | 包含封装的操作码值。 |
uncompressedSize | 压缩后的 compressedMessage 的大小,不包括MsgHeader 。 |
compressorId | 压缩消息的压缩器的ID。以下提供了 compressorId 值的列表。 |
compressedMessage | 操作码本身,不包括 MsgHeader 。 |
每个压缩器被分配一个预定义的压缩器ID,如下所示
compressorId | 握手值 | 描述 |
---|---|---|
0 | noop | 消息内容未压缩。这用于测试。 |
1 | snappy | 消息内容使用snappy进行压缩。 |
2 | zlib | 消息内容使用zlib进行压缩。 |
3 | zstd | 消息内容使用zstd进行压缩。 |
4-255 | 保留 | 为将来使用保留。 |
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位)是 可选的,解析器必须忽略任何设置的未知位。代理和其他消息转发器在转发消息之前必须清除任何未知可选位。
位 | 名称 | 请求 | 响应 | 描述 |
---|---|---|---|---|
0 | checksumPresent | ✓ | ✓ | 消息以包含CRC-32C校验和的4字节结束。有关详细信息,请参阅校验和。 |
1 | moreToCome | ✓ | ✓ | 后续还有一条消息将跟随此消息,而无需接收方采取进一步行动。接收方 不得 发送另一条消息,直到接收到一个将 moreToCome 设置为0的消息。发送可能会阻塞,从而导致死锁。设置了 moreToCome 位的请求不会收到回复。回复仅在响应设置了 exhaustAllowed 位时才会设置此位。 |
16 | exhaustAllowed | ✓ | 客户端已准备好使用 这确保了只有在请求方网络层准备好时才会发送多个回复。 |
部分
OP_MSG
消息包含一个或多个部分。每个部分都以一个表示其类型的 kind
字节开始。kind
字节之后的所有内容构成了该部分的负载。
以下是可用的部分类型。
类型 0:主体
主体部分被编码为单个 对象 BSON对象。BSON对象中的大小也作为部分的大小。此部分类型是标准的命令请求和回复主体。
所有顶层字段 必须 有一个唯一的名称。
类型 1:文档序列
类型 | 描述 |
---|---|
int32 | 部分大小的字节数。 |
C 字符串 | 文档序列标识符。在所有当前命令中,该字段是从主体部分替换的(可能嵌套的)字段。 此字段 不得 也存在于主体部分。 |
零个或多个 BSON对象 |
|
类型2
本节用于内部目的。
校验和
每条消息可以以一个覆盖消息中所有字节(除了校验和本身)的CRC-32C校验和结束。
如果您不使用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 命令的支持。作为一个例外,OP_QUERY 在连接握手过程中仍然支持运行hello 和isMaster 命令。 |
[2] | (1, 2) 32位CRC使用如https://tools.ietf.org/html/rfc4960#page-140所述的Castagnoli多项式计算 |