服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - MongoDB - MongoDB读数据策略

MongoDB读数据策略

2023-05-07 02:00未知服务器之家 MongoDB

MongoDB是开源文档型NoSQL数据库,它的数据模型灵活,具有高扩展性、高可用性、易用性等特点,能够存储半结构化的数据,并且有丰富的查询语言和索引类型,当前MongoDB已广泛的用在各企业的核心业务系统中。MongoDB也是db-engines排

MongoDB是开源文档型NoSQL数据库,它的数据模型灵活,具有高扩展性、高可用性、易用性等特点,能够存储半结构化的数据,并且有丰富的查询语言和索引类型,当前MongoDB已广泛的用在各企业的核心业务系统中。MongoDB也是db-engines排名最高的非关系型数据库。

MongoDB读数据策略

图片来源:db-engines

在MongoDB读取数据主要是受read concern(读策略)、read preference (读偏好设置 )两个参数控制,其中readconcern决定在读取副本集和分片集数据时的一致性和隔离性,而readpreference 决定客户端驱动读取哪个数据节点的数据。它们的配合使用,可以提高MongoDB 集群的性能,以及在数据一致性和读性能上做平衡。

readconcern 一致性读策略

Readconcern 主要解决脏读问题,从3.2版本后开始支持。比如PSA集群,用户从 MongoDB 的 primary 上读取数据后,这条数据并没有同步从数节点,然后 primary 就故障了。此时不同的Readconcern值,MongoDB 返回数据的处理方式是不同的。

Readconcern有几个不同的参数,分别是local、available、majority、linearizable、snapshot ,数据库在这些参数下的一致性是由弱到强递增的。

◀几种模式介绍▶

  • Local

表示读取的数据从实例中返回数据,但不保证数据是否被持久化(即可能被回滚)。该参数默认值为local。

  • Available

表示读取的数据从实例中返回数据,但不保证数据是否被持久化(即可以回滚)。乍一看available和local没有啥区别,对于副本集架构两者是相同的,主要区别场景是分片群集。在分片集群下,数据迁移会出现孤儿文档(orphaned document),available模式可以从延迟最低的节点获取数据,而local则直接返回数据。该参数是3.6版的新功能。

  • Majority

表示读取返回多数副本集成员已确认的数据,这个数据是持久化的不会被回滚。需要注意,在Majority下只能保证读到的数据“不会发生回滚”,但并不能保证读到的数据一定是最新的,官方也明确做了说明。

Regardless of the read concern level, the most recent data on a node may not reflect the most recent version of the data in the system。

  • linearizable

线性读取数据。根据官方资料翻译成中文:该查询返回的数据,反映了在读取操作开始之前完成的所有成功的多数确认写入。查询可能会等待并发执行的写操作传播到大多数副本集成员,然后返回结果。也就是在这种模式下,读可能需要等待其他写操作完成。

  • snapshot

从最新的快照中读取数据。如果事务不是因果一致的会话的一部分,并且数据的写入参数writeconcern 值也是majority下,那将从多数提交数据的快照中读取数据。

一般在生产推荐配置成Majority,这种模式是在数据安全和性能上相对平衡的选择,但是使用Majority也有要求和问题。首先它只支持WiredTiger引擎,其次需要写入参数writeconcern 也是majority 才会生效,最后在Majority下也不能完全保证解决了脏读问题。

◀Majority 实现▶

MongoDB 在readconcern majority 下,数据库会起一个单独的snapshot 线程,周期性的对当前的数据集进行 snapshot,并记录 snapshot 最新 oplog的时间戳,得到一个映射表。

最新 oplog 时间戳

snapshot

状态

t0

snapshot0

committed

t1

snapshot1

uncommitted

t2

snapshot2

uncommitted

t3

snapshot3

uncommitted

当 oplog 同步到大多数节点时,对应节点的 snapshot 才会标记为 commmited,用户读取时,从最新的 commited 状态的 snapshot 读取数据,就能保证读到的数据一定已经同步到的大多数节点。那如何判断oplog 已经同步到大多数节点?

对于primary来说,当secondary 节点的oplog发生变化时,会通过命令将 oplog 进度立即通知给 primary,同时节点间的心跳消息里也会包含最新 oplog 的信息。这样primary 节点能很快知道数据是否已经同步到大多数节点的,并更新 snapshot 的状态。比如当t2已经写入到大多数据节点时,snapshot1、snapshot2都可以更新为 commited 状态。

对于secondary 节点来说,在拉取 oplog 时,primary 节点会将“最新的数据已同步到大多数节点的”的信息返回给 secondary 节点,然后secondary 节点通过这个oplog时间戳来更新自身的 snapshot 状态。

readpreference 读偏好设置

MongoDB 读控制策略除了readconcern策略外,还有readpreference 。它主要控制数据库客户端驱动从哪个节点读取数据。这个特性可以方便地实现读写分离、就近读取等策略。

MongoDB读数据策略

readpreference 是由三部分组成,分别是mode、maxStalenessSeconds 、tag set,其中mode支持五种类型,分别是:primary、primaryPreferred、Secondary、secondaryPreferred、nearest,我们先看几种模式的具体含义。

◀几种模式介绍▶

  • primary

默认模式。读操作只在主节点,如果主节点不可用,报错或者抛出异常。这种策略适用于应用程序需要严格的一致性,但可用性不是首要考虑因素的情况。

  • primaryPreferred

大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。

  • secondary

仅从secondary节点中读取,如果secondary节点不可用,读将会报错。

  • secondaryPreferred

大多情况下读操作在从节点,特殊情况(如没有从节点)读操作在主节点。

  • nearest

根据指定的延迟阈值,随机地从符合条件的数据节点中读取操作,不管该节点是主还是从节点。

◀maxStalenessSeconds▶

MongoDB 3.4 以后版本新增maxStalenessSeconds参数。集群的从节点可能因为网络阻塞、磁盘吞吐低、长时间执行等原因,使从节点落后于主节点。当从节点延迟时间超过了该参数定义的值,客户端不会从该节点读取数据。maxStalenessSeconds 不能与primary 模式兼容,只能在其他四种模式下使用。

当选择了使用该参数控制读取数据,客户端会通过比较从节点和主节点的最后一次写时间来估计从节点的过期程度。客户端会把连接指向小于等于maxStalenessSeconds的从节点。另外,需要注意maxStalenessSeconds最小值是90秒,如果小于该值将报错。

You must specify a maxStalenessSeconds value of 90 seconds or longer: specifying a smaller maxStalenessSeconds value will raise an error.

◀标签集▶

如果一个复制集中的成员有tag,就可以通过下面的办法读取到带有具体标签的成员上。例如,如果某个节点有这样的成员标签:

{ "region": "South", "datacenter": "A" }
那么以下tag set可以将读操作指到上述成员(或具有相同标记的其他成员):
[ { "region": "South", "datacenter": "A" }, { } ]     // Find members with both tag values. If none are found, read from any eligible member.
[ { "region": "South" }, { "datacenter": "A" }, { } ] // Find members with the specified region tag. Only if not found, then find members with the specified datacenter tag. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { "region": "South" }, { } ] // Find members with the specified datacenter tag. Only if not found, then find members with the specified region tag. If none are found, read from any eligible member.
[ { "region": "South" }, { } ] // Find members with the specified region tag value. If none are found, read from any eligible member.
[ { "datacenter": "A" }, { } ] // Find members with the specified datacenter tag value. If none are found, read from any eligible member.
[ { } ] // Find any eligible member.

◀访问案例▶

总结上面的内容,可以通过下面三种方式去定义不同的readpreference策略。

复制集访问方式:
mongodb://db0.test.com,db1.test.com,db2.test.com/?replicaSet=myRepl&readPreference=secondaryPreferred&maxStalenessSecnotallow=150
分片集群方式:
mongodb://mongos1.test.com,mongos2.test.com/?readPreference=secondaryPreferred&maxStalenessSecnotallow=150
带tag的定式:
mongodb://mongos1.test.com/?readPreference=secondaryPreferred&readPreferenceTags=dc:ny,rack:r1&readPreferenceTags=dc:ny&readPreferenceTags=xxx

总结

通过上文介绍,我们知道MongoDB读数据策略,有readconcern和readpreference两个重要的概念。其中readconcern是读数据时的数据一致性级别,它决定了决定读取数据时读到什么样的数据。通常结合可用性和性能,会将readconcern设置为majority。而readpreference决定读哪个节点的数据,主要用于实现读写分离上。另外,MongoDB还提供了其他的配置选项,如写数据策略(writeconcern)这将在后面的文章中介绍。

作者介绍

司马辽太杰是 NineData 工程师。NineData 向企业和个人提供高效、安全的数据库SQL开发、数据库备份、数据复制/迁移/集成、数据对比等能力的产品,它是开箱即用的SaaS服务,可以快速提升企业SQL开发效率,保障企业数据安全。近期,NineData 即将会支持MongoDB、Redis等NoSQL数据库。NineData 官网地址:​​https://ninedata.cloud​​。

本文转载自微信公众号「云数据库技术」,可以通过以下二维码关注。转载本文请联系云数据库技术公众号。

MongoDB读数据策略

延伸 · 阅读

精彩推荐
  • MongoDBmongodb数据库基础知识之连表查询

    mongodb数据库基础知识之连表查询

    这篇文章主要给大家介绍了关于mongodb数据库基础知识之连表查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mongodb具有一定的参...

    ZJW02155642020-05-22
  • MongoDBMongoDB系列教程(五):mongo语法和mysql语法对比学习

    MongoDB系列教程(五):mongo语法和mysql语法对比学习

    这篇文章主要介绍了MongoDB系列教程(五):mongo语法和mysql语法对比学习,本文对熟悉Mysql数据库的同学来说帮助很大,用对比的方式可以快速学习到MongoDB的命...

    MongoDB教程网3252020-05-01
  • MongoDBMongoDB的索引

    MongoDB的索引

    数据库中的索引就是用来提高查询操作的性能,但是会影响插入、更新和删除的效率,因为数据库不仅要执行这些操作,还要负责索引的更新 ...

    MongoDB教程网2532020-05-12
  • MongoDBWindows下MongoDB配置用户权限实例

    Windows下MongoDB配置用户权限实例

    这篇文章主要介绍了Windows下MongoDB配置用户权限实例,本文实现需要输入用户名、密码才可以访问MongoDB数据库,需要的朋友可以参考下 ...

    MongoDB教程网3082020-04-29
  • MongoDB在mac系统下安装与配置mongoDB数据库

    在mac系统下安装与配置mongoDB数据库

    这篇文章主要介绍了在mac系统下安装与配置mongoDB数据库的操作步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    CXYhh1219312021-11-14
  • MongoDBMongoDB多条件模糊查询示例代码

    MongoDB多条件模糊查询示例代码

    这篇文章主要给大家介绍了关于MongoDB多条件模糊查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MongoDB具有一定的参考学习价值...

    浅夏晴空5902020-05-25
  • MongoDBMongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    这篇文章主要给大家介绍了关于MongoDB查询之高级操作(多条件查询、正则匹配查询等)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者...

    w田翔3872020-12-19
  • MongoDBMongodb索引的优化

    Mongodb索引的优化

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。接下来通过本文给大家介绍Mongodb索引的优化,本文介绍的非常详细,具有参考借鉴价值,感...

    MRR3252020-05-05