MongoDB如何从指定节点读取数据

1,410 阅读3分钟

当你有一个MongoDB的replica set,其他模块希望每日大量的读取DB里的数据,如何做?

除开提供API,最简单直接的方案,就是单独开一个从节点给他们使用,希望他们只在这个从节点上读取,做到不影响其他节点。

开一个从节点简单,如何保证只从这个指定从节点读取呢?

要得到答案,就需要介绍一下mongoDB的writeConcern和ReadPref,他们和MongoDB的replica set读写的控制逻辑息息相关,看完这些,答案自然就知道了。

writeconcern.WriteConcern

writeConcern和MongoDB的写入息息相关,它的配置如下

{ w: <value>, j: <boolean>, wtimeout: <number> }
  • w:

    定义一个写入操作在什么条件下给客户端返回成功

    • w为0,不需要给客户端发送任何确认;性能高
    • w为1,只需要成功写入primary即可向客户端返回成功;这是默认值
    • 其他值:比如对于3成员副本集,1primary和2secondary,w为2,代表需要1个primary和1个secondary确认写入成功,才向客户端返回成功
    • w为"majority", 写入操作要传递到绝大多数投票成员才算成功,绝大多数的关键字为calculated majority, 4.1版本可以通过 rs.status() 获取 writeMajorityCount 字段得到。
    • , 写入操作要写到指定tag(即concern name)的成员才算成功,所谓tag,是创建副本集时,指定的成员tag,即为成员取名
  • j:

    j为true,代表要将操作写入w所要求的所有成员的journal日志才给客户端回应,journal日志是磁盘存储的预写重放日志,用于mongoDB意外故障后快速恢复,每次实例启动时都会检查journal日志来确定是否要恢复数据

  • wtimeout:

    为write concern定义毫秒级别的超时时间,只有当w>1时才有用

readpref.ReadPref

ReadPref控制读数据,主要是mode和tagSets:

  • Mode

    • primary

      默认配置

      只读主节点的数据,如果主节点不可用,报错

    • primaryPreferred

      如果主节点可用,从主节点读取数据,否则从可选的从节点读取数据

    • secondary

      只从从节点处读取数据

    • secondaryPreferred

      如果从节点可用,从从节点读取数据,否则从主节点读取数据

    • nearest

    ​ 从网络延迟最小的节点读取数据,不管这个节点的主、从角色。

  • tagSets

    当你为节点指定了tagSet,可以通过配置readPref里的tagSet,来指定从符合的节点来读取数据, 例子如下,详情可以看这里

[ { "region": "South", "datacenter": "A" }, { } ]     // Find members with both tag values. If none are found, read from any eligible member.

到这里,能够看到,通过tag是可以实现从指定节点进行读取的,那么,tag具体如何使用呢?

简单,如下代码,在replica set初始化时,可以指定member的tag,这样就能实现节点和tag绑定,然后在读取时,通过driver指定readPref,就能实现从指定tag的节点读取数据了。

rs.initiate(
   {
      _id: "myReplSet",
      version: 1,
      members: [
         { _id: 0, host : "mongodb0.example.net:2701",tags :{ "dc": "east", "usage": "production" } }
      ]
   }
)


广告时间

Qmgo, 这款更好用的Go语言MongoDB driver,支持上述所有的replica set配置噢!

引用:

WriteConcern: docs.mongodb.com/manual/refe…

ReadPref: docs.mongodb.com/manual/core…

TagSets: docs.mongodb.com/manual/tuto…