学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第81篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。
本文简单介绍Mongodb的分布式操作。mongodb支持复制集和分片集合,本文结合官方文档,整理介绍复制集和分片结合的数据读取。
复制集中的数据读取
默认情况下,应用链接到复制集后,从复制集的主节点承担了客户端或应用的数据读写操作。mongodb允许用于指定参数readpreferences来通过复制集中的其他节点来读取数据。
同样用户可以设置readpreferences参数,将读取操作转移到从节点或与主节点最近的节点来实现下面的操作目的
- 减少多数据中心数据同步的延迟
- 将大量的读取操作分配的主节点以外的节点,从而提高读取数据吞吐量
- 在从节点做数据备份
- 当主节点切换时,直到新的主节点选出来以后才可以读取数据。
在复制集从节点读取数据时,因为数据变更从主节点同步到从节点需要时间和过程,因此读取数据的状态可能不是最新的状态。同样因为数据同步的延迟,在从节点中读取到的数据可能不是单调连续的。客户端可以使用数据一致性的session设置,保证数据读取的正确性。当然,使用从节点读取数据时,客户端可以按照数据库连接或操作来设置。用户可以参考相关的文档来设定不同的参数。
复制集中的数据写入
在复制集中,所有的写入操作都是发生在主节点。主节点执行写入操作,同时将操作记录在主节点的操作日志当中。操作日志是一个可重现的顺序操作的集合。从节点持续的将操作日志同步到自己的节点,并依据操作日志当中记录下来的事件,将数据变更同步写入到自己节点的数据集中。用户可以指定mongodb主节点通知用户数据变更完成的方式。比如,当主节点数据写入完成后,就返回写入结果给客户,或者在最近的一个从节点完成后,将数据变更结果返回给客户。
分片集中数据读取
分片集允许用户将数据分成不同的数据块,保存到分片集的不同节点当中。这种方式对应用和数据库客户端来说是透明的。数据分块保存发生在数据库集群当中。在复制集当中,用户的操作是针对集群中的一个mongos服务实例的。mongos服务实例,依据数据分块时产生的元数据,将请求派发到不同的节点。
当用户指定具体的数据分片时,mongodb分片集无需再次确认到哪个节点中读取数据,这样读取操作会变得很高效。针对分片集群的查询应该带上分片键。带有分片键的查询,mongos可以用过分片元数据将查询分配到具体的分片节点当中。
对于没有分片键的查询,mongodb分片集群不得不查询集群中所有的节点。这样从每个分片节点收集数据,会变得很低效。在大型分片集群当中,这种分散收集的方式是不可行的。
与复制集类似,分片集在从节点中读取到的数据可能无法反应数据最新的状态。在从节点中读取的数据,也无法保证是单调一致的。用户可以使用一致性会话,保证数据读取的一致性。
分片集中数据的写入
在分片集合中,mongos直接将应用或客户端发过来的数据写到对应的数据分片中。mongos通过元数据配置库,找到数据应该写入的节点,将写入数据的操作派发到该节点。
Mongodb依据用户指定的分片键,将数据分成不同的数据块。然后将这些数据块保存到不同的分片节点中。分片键决定了数据块写入的节点。mongodb分片集写入数据时,会影响集群的性能。
mongodb数据更新单个文档数据时,必须要包含分片键或主键。多文档数据的更新时,带有分片键在某些情况下会提高效率。多文档数据更新也有可能被发到每一个分片服务上。
如果分片键的值每个插入操作都增加或减少,那么所有的这些插入操作会产生一个新的数据分片。这样来说,单个插入操作的容量,就会被限制为分片的容量。