OPTIONS
翻译或纠错本页面

复制集读选项的生效流程

在 2.2 版更改.

MongoDB驱动通过下列的流程来管理复制集和分片集群中的操作。为了决定如何路由它的操作,应用程序定期的获取复制集的状态视图,包括:节点是否活着,哪个节点是 主节点 ,检查每个 mongod 实例的延时情况。

节点的选择

客户端经由他们的驱动或是分片集群中得 mongos 实例来定期的获取复制集的状态视图。

当我们选择 non-primary 模式的复制集读选项的时候,驱动将通过下列过流程决定将操作的发送目标:

  1. 收集可用的节点的名单,并按节点类型分类(如 从节点,主节点或是所有节点)。

  2. 如果制定了标签,则排除不符合标签的节点。

  3. 判断出最近的(绝对路径)可用的节点。

  4. 将这些节点和其与网络延时列出。

    在这个阶段,应用程序可以设定可接受的延时的门槛。默认的 “可接受的延时” 是15毫秒,我们也可以在驱动中使用 secondaryAcceptableLatencyMS 设置来修改。如果是分片集群,我们可以通过修改 mongos--localThreshold 或是 localPingThresholdMs 选项来设置可接受的延时。

  5. 在这些节点中随机选取一个,并在其上进行读操作。

接下来驱动就会与其建立连接。应用程序可以设置 请求绑定 。参考你所用的 驱动 的文档来获得更多有关请求绑定的配置和默认状态。

请求绑定

重要

Request association is configurable by the application. See your driver documentation about request association configuration and default behavior.

由于 复制集 中不同 从节点 的数据可能会比 主节点 有不同程度的延后,且读请求每次可能会被发送在不同的 从节点 上。为了防止读操作先后在不同从节点上进行读取,我们可以通过驱动来在第一次读操作之后将该线程与该节点进行绑定,从而让此后的读请求都发送到该节点上。该线程将会一直在这个节点上进行读操作直到:

  • 应用程序用不同的复制集读选项执行了一次读操作,

  • 该线程终止了,或者

  • 客户端接收到socket异常,比如:有网络错误或是 mongod 进程在一次 故障切换 中关闭了连接。这将触发 retry ,对于应用程序来说这个过程是透明的(transparent)。

当使用请求绑定的时候,如果客户端发现复制集选举出了新的 主节点 ,那么驱动会解除所有线程与节点之间的关联。

自动重连

MongoDB驱动与 复制集 中得 mongod 实例之间的连接需要考虑以下两个平衡点:

  1. 客户端应该尽量获得最新的数据,且如果可能,所有的连接都应该是在复制集的同一个节点上进行读操作。建议使用 请求绑定 (e.g. pinning)。

  2. 客户端需要尽量减少因为连接、网络问题或是复制集的 故障切换 导致的无法连接数据库的时间。

所以,MongoDB驱动与 mongos 应:

  • 在建立与实例的连接后,尽可能对指定了该 mongod 实例的连接进行再利用,将连接与该 mongod 实例进行绑定。

  • 如果 mongod 上的连接丢失了,应用程序会尝试重连到一个符合现有 复制集读选项 的新节点上。

    对于应用程序本身来说,重连是透明的(transparent)。

  • Return an error only after attempting to connect to three members of the set that match the read preference mode and tag set. If there are fewer than three members of the set, the client will error after connecting to all existing members of the set.

    在报错后,驱动会根据指定的复制集读选项重新选择一个节点来连接。在没有指定复制集读选项的时候,驱动会使用 primary 模式。

  • 在检测到发生了故障切换后, [1] 驱动会尽快刷新来获得最新的复制集状态。

[1]

当发生了 故障切换 ,复制集的所有节点都会关闭所有现有连接并返回一个报错。这样可以防止或者最小化 回滚 的影响。

分片集群中的复制集读选项。

在 2.2 版更改: 在2.2版本之前, mongos 不支持指定 复制集读选项

在大多数 分片集群 中,每个分片是由一个 复制集 构成的。 因此,复制集读选项对其也适用。就复制集读选项来说,在分片集群中得复制集进行读操作与在单独的复制集上进行操作没有区别。

与普通复制集不同的是,在分片集群中,所有分片之间的交互是通过客户端连接到 mongos 实例后再连接到各个复制集的。 mongos 实例负责处理应用程序传来的复制集读选项,且对应用程序来说是透明的(transparent)。

在2.2版本后的分片集群架构中,复制集读选项的配置与复制集中完全一致。 所有的 mongos 实例都维护着连接到复制集的连接池,例如:

  • 没有指定复制集读选项的请求默认使用 primary 模式,除非 mongos

    为了防止混淆,我们建议是要设置复制集读选项。

  • All nearest and latency calculations reflect the connection between the mongos and the mongod instances, not the client and the mongod instances.

    这是显而易见的,因为所有的数据都必须通过 mongos 实例传输到客户端中。