【问题标题】:Mongoose: Read on ReplicaSetMongoose:在 ReplicaSet 上阅读
【发布时间】:2013-12-21 01:09:49
【问题描述】:

我有一个 mongodb 副本集,我想从中读取主数据库和辅助数据库的数据。

我已经使用这个命令连接到数据库:

mongoose.connect('mongodb://user:password@54.230.1.1,user:password@54.230.1.2,user:password@54.230.1.3/PanPanDB?replicaSet=rs0&readPreference=nearest');

它不起作用..我的应用程序继续从主要读取..有什么建议吗?

【问题讨论】:

    标签: node.js mongodb mongoose database-replication


    【解决方案1】:

    如果您想从辅助读取,您应该将read preference 设置为:

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

    • secondary - 从副本集的次要成员读取的所有操作。

    根据您的示例从 nearest 读取将通过 ping 时间选择最近的成员(可能是主要成员或次要成员)。

    注意事项

    使用primary 以外的任何读取首选项时,您需要注意可能影响您的应用程序逻辑的最终一致性的潜在问题。例如,如果您正在从辅助节点读取数据,则主节点上的更改可能尚未复制到该辅助节点。

    如果您在从辅助节点读取数据时担心更强的一致性,您应该查看Write Concern for Replica Sets 文档。

    由于辅助节点必须写入与主节点相同的数据,因此从辅助节点读取可能不会提高性能,除非您的应用程序读取量很大或最终一致性良好。

    【讨论】:

    • 这个答案可以通过一些特定于 Mongoose 的语法来改进,因为问题包含“mongoose”标签。
    • @MarkStosberg 迟来的回复旧评论,因为我似乎错过了原始通知。仅供参考,Mongoose 连接示例已经在问题文本中,这只是对“最近”的 readPreference 如何工作的错误预期。 Mongoose 支持标准的MongoDB Connection String format 或具有等效值的options object。可以说这个问题不应该被标记为 Mongoose,因为它实际上是关于一般的阅读偏好行为。
    • 为什么这不是读取的默认值,这完全超出了我的理解。
    • @TomO'Connor 默认是从主数据库进行强一致性读取。从辅助节点读取数据最终是一致的,但这并不适用于所有用例。
    【解决方案2】:

    按照MongoDB websiteMongoose web site 上的文档,您可以添加此指令以在Mongoose 上配置ReadPreference:

    var opts = { replSet: {readPreference: 'ReadPreference.NEAREST'} };
    

    mongoose.connect('mongodb://###:###@###:###/###', opts);

    已使用 Mongoose 3.8.9 版进行了测试

    【讨论】:

    • 根据猫鼬文档,您需要使用replset,并带有一个小的s。 MongoDB 使用大写字母S。这种差异给我带来了一些麻烦......
    • 您应该使用 'nearest' 作为字符串。 ReadPreference.NEAREST 只是一个定义。你应该检查源代码:github.com/mongodb/node-mongodb-native/blob/…
    【解决方案3】:

    除了设置连接 URI(如您所做的那样)和连接选项(如 Emas 所做的那样),我还必须为每个查询明确选择服务器,例如

    var query = User.find({}).read("nearest");
    query.exec(function(err, users) {
        // ...
    });
    

    【讨论】:

    • 谢谢你, .read("nearest") 是否记录在任何地方?你在哪里找到的?
    • 天哪,这是不久前的事了。我可能会在 github 或 stackoverflow 上找到它。它记录在 mongoose API 文档中...mongoosejs.com/docs/api.html#query_Query-read
    【解决方案4】:

    Mongoose 使用节点包“mongodb”,连接 uri 或 opts 由“mongodb”解析。这是mongodb connect optsmongodb readPreference的源代码。

    所以,我们可以像这样使用猫鼬:

    var opts = {db: {readPreference: 'nearest'}; mongoose.connect(uri, opts);

    另外,只需像这样使用uri

    var uri = 'mongodb://###?readPreference=nearest'; mongoose.connect(uri, opts);

    在猫鼬4.3.4以上生效。

    【讨论】:

      【解决方案5】:

      这是 Mongoose v5.9.5 中的正确实例化:

      const opts = {
          readPreference: 'nearest',
      }
      mongoose.connect(MONGODB_CONNECTION, opts)
      

      这些是不同的字符串值,具体取决于您要查找的首选项类型:

      ReadPreference.PRIMARY = 'primary';
      ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred';
      ReadPreference.SECONDARY = 'secondary';
      ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred';
      ReadPreference.NEAREST = 'nearest'
      

      【讨论】:

      • 将 readPreference 设置为选项会给我带来一个错误,也是一个奇怪的错误。TypeError: Reduce of empty array with no initial value
      【解决方案6】:

      您可以使用下面的代码简单地做到这一点

      var collection = db.collection(collectionName,{readPreference:'secondaryPreferred'});
      

      http://p1bugs.blogspot.in/2016/06/scaling-read-query-load-on-mongodb.html

      【讨论】:

        猜你喜欢
        • 2017-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多