在mongodb中跨副本分发读取

时间:2014-01-16 15:25:23

标签: mongodb

我正在尝试理解mongodb副本集中的读取行为。特别是我的环境具有高读取率,低写入率和相对较小的数据集(比如小于8GB)。我有一个3节点副本集。

我读了这个文件:

http://docs.mongodb.org/manual/core/read-preference/

特别是:

  
    

主要默认模式。所有操作都从当前副本集主要读取。

         

primaryPreferred在大多数情况下,操作从主数据库读取,但如果不可用,则从辅助成员读取操作。

         

secondary所有操作都从副本集的辅助成员中读取。

         

secondaryPreferred在大多数情况下,操作从辅助成员读取,但如果没有辅助成员可用,则从主要成员读取操作。

         

最近的操作从副本集的最近成员读取,无论成员的类型如何。

  

所以我的理解是默认情况下读取主要内容。有读取首选项允许从辅助(secondarysecondaryPreferred)读取。在这些情况下,可能会提供陈旧的数据。

在我看来,最好是在主机和辅助机器上分配读取,以便我可以最好地利用所有3台机器。但我并不认为这是一个选择。以下陈述特别困​​扰我:

  
    

如果读取操作占应用程序流量的很大一部分,则向次要成员分发读取可以提高读取吞吐量。但是,在大多数情况下,分片可以为更大规模的操作提供更好的支持,因为群集可以在一组机器上分配读写操作。

  

然而,在数据集相对较小的情况下,分片根本没有意义。有人可以对正确的配置有所了解吗?

2 个答案:

答案 0 :(得分:0)

我能够使用标记引用https://docs.mongodb.com/manual/tutorial/configure-replica-set-tag-sets/

来部分解决问题
conf = rs.conf()
conf.members[1].tags = { "tagType": "dummyValue"}
rs.reconfig(conf)

在每台辅助计算机上设置了自定义标记,并使用标记集(https://docs.mongodb.com/manual/core/read-preference/#tag-sets

定义了不同的mongo模板(我使用的是Spring Mongo)
<bean id="tag" class="com.mongodb.Tag">
    <constructor-arg value="tagType" />
    <constructor-arg value="dummyValue" />

<bean id="tagSet" class="com.mongodb.TagSet">
    <constructor-arg ref="tag" />
</bean>

<bean id="readPref" class="com.mongodb.ReadPreference" 
        factory-method="secondaryPreferred" >
        <constructor-arg ref="tagSet" />
</bean>

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoFactory" />
        <property name="readPreference" ref="readPref" />
        <property name="writeConcern" value="JOURNALED" />
    </bean>

使用不同的mongo模板手动分发调用,因此是在辅助mongo服务器上分配负载的部分解决方案。

答案 1 :(得分:0)

我曾在MongoDB的一个论坛上问过这个问题,这是他们的答案,

TL; DR:使用最近的值。

实际上,对群集进行分片肯定会解决问题,因为它将迫使您将数据集拆分为碎片(分片),并且读写操作将由mongos服务器平均分配-前提是您选择了良好的分片键。 但是,正如您所发现的,对于相对较少的数据集,这实际上没有任何意义,而且成本更高。

我们的文档并没有真正揭示出“最近”选项背后的所有魔力,但实际上背后有一个循环算法。 在我们的规范中,您可以阅读更多有关它的信息-特别是可以设置为调整循环算法的选项。

https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#nearest https://github.com/mongodb/specifications/blob/master/source/driver-read-preferences.rst#nearest

To distribute reads across all members evenly regardless of RTT, users should use mode ‘nearest’ without tag_sets or maxStalenessSeconds and set localThresholdMS very high so that all servers fall within the latency window.

这里有更多有关ping times的文档。

特别是这部分:

Once the driver or mongos has found a list of candidate members based on mode and tag sets, determine the “nearest” member as the one with the quickest response to a periodic ping command. (The driver already knows ping times to all members, see “assumptions” above.) Choose a member randomly from those at most 15ms “farther” than the nearest member. The 15ms cutoff is overridable with “secondaryAcceptableLatencyMS”.

此外,您拥有的RAM越多,需要从磁盘检索的文档就越少。如果工作集1较大,则应考虑添加一些RAM以减少IOPS和总体延迟。

除了上面提到的内容外,术语在某些地方并不一致,但是在https://www.mongodb.com/blog/post/server-selection-next-generation-mongodb-drivers中它明确说明了

The ‘localThresholdMS’ variable used to be called secondaryAcceptableLatencyMS, but was renamed for more consistency with mongos (which already had localThreshold as a configuration option) and because it no longer applies only to secondaries.

localThresholdMS是用作uri选项一部分的连接字符串,文档位于https://mongodb.github.io/mongo-java-driver/4.1/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html