一. 分布式读操作
介绍分片集群和副本集如何影响读操作的性能。
1.1 分片集群读操作
分片集群允许数据分割到集群内的不同mongod实例上,这对应用程序来说几乎是透明的。
对于分片集群,应用程序发出操作与集群相关的mongos实例。
读操作直接定向到一个特定的分片上,集群读操作是最有效的。
查询到分片集合应该包括集合分片片键。 当一个查询包含分片片键,mongos从config server使用集群元数据将查询路由到分片。
查询条件包括分片关键。查询路由器mongos将查询直接到定位到相应的分片。
如果查询不包含分片片键,mongos将查询广播到集群中的所有分片。 这种分散聚集查询是非常低效的。对于大型集群,这种操作是要命的。
1.2 复制集读操作
副本集使用读的优先模式来决定在哪里以及如何路由读操作到副本集的成员。
默认情况下,应用程序读操作在复制集的primary上。从primary读可以保证文档的最新版本,因为复制集是异步复制的。然后,通过分配部分或者全部读操作到复制集的secondary节点上,可以提高读取吞吐量或减少等待时间,对实时性应用程序需要并不高。
可以通过修改读操作的优先模式来更改读的特性。
读操作的模式有:
读操作的模式有:
读模式 | 描述 |
---|---|
primary | 默认模式。所有读操作都从primary节点读取。 |
primaryPreferred | 在大多数情况下,读操作从primary节点读取,但如果primary节点不可用,读操作从secondary节点读取。 |
secondary | 所有读操作都从secondary节点读取。 |
secondaryPreferred | 在大多数情况下,读操作从secondary节点读取,但如果secondary节点不可用,读操作从primary节点读取。 |
nearest | 读操作从副本集网络延迟最小的节点读取,无论该节点的类型。 |
根据应用程序的需求,选择不同的读操作模式。
最大限度的一致性:在任何情况下,避免读取到旧数据,使用primary模式。在没有primary节点,发生在选举阶段,或大部分节点不可用,将阻塞所有的读取操作。
最大限度的高可用性:尽可能的保证读操作,使用 primaryPreferred 模式。当有一个primary节点会得到一致性读,如果没有,仍然可以查询secondary节点。
减少等待时间 :要始终从低延迟的节点读取,使用nearest。驱动和mongos从最少延迟读取。nearest不保证一致性。如果复制延迟,查询可能返回过期数据。nearest只反映网络的延迟,并不能反映I/O和CPU的负载。
从secondary节点读取,并不能反映primary当前的状态,异步复制下,secondary节点可能落后primary节点一定的时间。通常情况下,应用程序不要求这种严格的一致性,对于高可用性的要求是最多的。
二. 分布式写操作
1.1 分片集群写操作
对于分片集群分片集合,mongos将应用程序的写操作直接特定到指定的分片。mongos从config server使用集群元数据将写操作路由到适当的分片上。
基于片键将数据分区,然后,MongoDB将这些块分片到分片上, 片键决定块分片的分布情况。这可能会影响集群写操作的性能。
注意:
影响单个文档的更新操作必须包括片键或_id字段。
影响多个文档的更新操作,在某些情况下更有效,如果有片键,但是可以广播到所有的分片。
如果片键的值增加或每个插入减少,所有的插入操作目标是单一的分片。因此,一个单一的分片容量成为限制分片集群的插入能力。
1.2 复制集写操作
在复制集下,所有的写操作在primary节点。所有的写操作记录在操作日志中oplog。oplog是对数据集的可再现序列。secondary节点不断复制oplog并应用,该过程是异步的。
大量的写操作,特别是批量操作,可能会创造一个问题,secondary节点难以从primary节点复制并应用oplog,从而导致secondary节点落后于primary节点。
当secondary显著落后于primary时,对于正常的复制集来说是个问题,特别是在故障转移时,需要回滚数据以便达到数据的一致性。
为了避免这个问题,可以自定义写关注来确认写到另一个节点上。这提供了一个机会,让secondary赶上primary。 写关注可以减缓写操作的整体进展,但是可以保证了secondary节点当前状态与primary节点大致相同。
设置写关注级别为w:2, 确保写入到primary节点和至少一个secondary节点上。