在某些状况下,将读请求发送给副本集的备份节点是合理的,例如,单个服务器没法处理应用的读压力,就能够把查询请求路由到可复制集中的多台服务器上。如今绝大部分MongoDB驱动支持读偏好设置(read preference;或翻译为读取首选项),用来告诉驱动从特定的节点读取数据。html
primary — 这是默认的设置,代表只从可复制集的主节点读取数据,所以具备强一致性。若是可复制集有问题,而且没有可选举的从节点,就表示出现错误。sql
premaryPreferred — 设置了此参数的驱动会从主节点读取数据,除非某些缘由使主节点不可用或者没有主节点,此时它会从从节点读取数据。此种设置下,读请求没法保证一致性。mongodb
secondary — 这个设置告诉驱动应该一直从从节点读取数据。这种设置对于咱们想确保读请求不会影响主节点的写入请求时很是有用。若是没有可用的从节点,读请求会抛出异常。服务器
secondarypreferred — 读请求会发出到从节点,除非没有从节点可用,此时才会从主节点读取。网络
nearest – 驱动会尝试从最近的可复制集成员节点读取读取数据,经过网络延迟判断。能够是主节点也能够是从节点。所以读请求只会发送给驱动认为最快通讯的节点。测试
primary是惟一一个能够确保读一致的模式。由于写请求首先在主节点完成,从服务器的更新会有些延迟,因此可能在从节点没法找到刚刚在主节点写入的文档数据。spa
汇总以上知识,各偏好设置下读取数据请求所发往的节点以下所示:翻译
MongoDB 3.4及更新的版本新增了maxStalenessSeconds设置。rest
副本集的从节点可能由于网络阻塞、磁盘吞吐低、长时间执行操做等,致使其落后于主节点。读设置maxStalenessSeconds选项让你对从节点读取定义了最大落后或“过时”时间。当从节点估计过时时间超过了maxStalenessSeconds,客户端会中止使用它进行读操做。htm
最大过时和primary模式不匹配,只有选择从节点成员读取操做才能应用。
当选择了使用maxStalenessSeconds进行读操做的服务端,客户端会经过比较从节点和主节点的最后一次写时间来估计从节点的过时程度。客户端会把链接指向估计落后小于等于maxStalenessSeconds的从节点。若是没有主节点,客户端使用从节点间的最近一次写操做来比较。
默认是没有最大过时时间而且客户端也不会在指向读操做时考虑从节点的落后。
注意:
必须定义maxStalenessSeconds的值大于等于90秒:定义一个更小的值会抛出异常。客户端经过按期检查每一个副本集成员最后一次写时间来估计副本集过时程度。由于检查不频繁,因此估计是粗略的。所以,客户端不能强制maxStalenessSecconds小于90秒。
副本集链接字符串格式
mongodb://username:password@host1:port1,host2:port2[,...,hostN:portN]/database?options
options 是链接配置中的可选项,replicaSet、readPreference、maxStalenessSeconds是其中的一个子项。
下面咱们举一个例子来讲明字符串是怎么配置的,测试环境的副本集信息以下:
副本集名称 | 节点IP | 节点Role | 端口 |
repltest | 168.17.XXX.XX1 | 主节点 | 27017 |
168.17.XXX.XX2 | 从节点 | ||
168.17.XXX.XX3 | 仲裁节点 |
帐号信息以下:
Username | Password | DBName |
mongousertest | testuserpwd | mongotestdb |
若是但愿程序读请求路由到从节点secondary,100秒为节点数据失效时间,此时C# 程序中connectionStr的字符串能够设置以下:
string connectionStr = "mongodb://mongousertest:testuserpwd@168.17.XXX.xx1:27017,168.17.XXX.xx2:27017/mongotestdb?replicaSet=repltest&readPreference=secondary&maxStalenessSeconds=100";
部份内容参考官网:https://docs.mongodb.com/manual/core/read-preference/index.html