【问题标题】:Express can't connect to mongodb replica set when new primary get elected选举新主节点时 Express 无法连接到 mongodb 副本集
【发布时间】:2017-11-23 16:59:53
【问题描述】:

我有一个mongodb replica set,配置如下:

  • M1 初级
  • M2 二级
  • M3 二级
  • M4 仲裁员

这是我连接到数据库的 Express 代码(我使用 mongoose 作为 ODM):

const config = {
  db: `mongodb://${process.env.DB_ADDRESS_1}/${process.env.DB_NAME},
                 ${process.env.DB_ADDRESS_2}/${process.env.DB_NAME},
                 ${process.env.DB_ADDRESS_3}/${process.env.DB_NAME}`,
  dbOptions: {
    server: {
      socketOptions: {
        keepAlive: 1
      },
      poolSize: 5,
      readPreference: 'nearest'
    },
    replSet: {
      rs_name: process.env.REPLICA_SET,
      poolSize: 5,
      readPreference: 'nearest',
      socketOptions: {
        keepAlive: 1,
        connectTimeoutMS: 30000,
        socketTimeoutMS: 0
      }
    },
    db: {
      w: 1,
      numberOfRetries: 2
    }
  }
}
mongoose.connect(config.db, config.dbOptions, (error) => {
  if (error) {
    console.log('Error on connecting to th db: ', error)
    console.log('\x1b[31m', '*** PLEASE CONNECT TO DATABASE BEFORE RUN SERVER', '\x1b[0m')
    process.exit(1)
  }
  callback()
})

应用程序按预期运行。 当 M1 宕机时,M2 或 M3 被选为primary,但我的express 应用仍然无法连接到replica set。

我的配置有问题吗?

【问题讨论】:

    标签: node.js mongodb mongodb-replica-set mongodb-cluster


    【解决方案1】:

    Connection URL 应该是:

    `mongodb://${process.env.DB_ADDRESS_1},${process.env.DB_ADDRESS_2},${process.env.DB_ADDRESS_3}/${process.env.DB_NAME}`
    

    因此,有一个节点列表,然后是有关数据库的信息。

    而且你的设置也有一个缺陷......当你有三个节点的副本集时,你不应该有仲裁者!这是因为,投票计数must be odd not even。

    【讨论】:

    • 感谢您对connection url 的帮助。但是,至于您对节点数量的建议,我不这么认为。 Ensure that the replica set has an odd number of voting members。我有 3 个节点,当 master 离开时,有 2 个节点加入投票成员,所以我认为添加 arbitrator 对“奇数投票成员”有好处。
    • 实际上是奇数票,不是投票成员。即使一个节点关闭,仍然(在配置中)信息“应该是 X 个节点”和“多数”是从所有配置的成员中计算出来的,而不是那些在当前时刻启动的成员。所以投票结果是“up members / all votes”。当一个节点宕机时,结果是满足多数的 2/3。这只是为了防止在我们进行网络分区时出现脑裂。
    • 我还是不明白。我有2个投票节点,1个仲裁员,也就是3个,是不是错了?
    • 能否请您看一下我的新问题:stackoverflow.com/questions/47478964/… 谢谢
    • 这不是“任何情况下的奇数投票成员”。它应该写成“奇数配置投票”,因为您可以(在副本集中)拥有零票的节点,正如我之前写的那样,所有配置的投票都很重要,这应该是奇数。仲裁器被发明为仅在您的配置具有偶数票的情况下使用。
    【解决方案2】:

    您的 MongoDB URI 连接字符串格式不正确。数据库名称应附加在服务器列表之后,而不是附加在每个服务器上。试试:

    mongodb://${process.env.DB_ADDRESS_1},
    ${process.env.DB_ADDRESS_2},
    ${process.env.DB_ADDRESS_3}
    /${process.env.DB_NAME}?replicaSet=${process.env.REPLICA_SET}
    

    有关示例,请参阅 https://docs.mongodb.com/manual/reference/connection-string/#connection-string-options。

    另一方面,您不需要副本集上的仲裁器。不建议在副本集中拥有偶数个节点,因为它需要多数人才能选举主节点。

    如果有 4 个节点,如果其中 2 个节点宕机,其余节点将无法选举主节点(当您拥有 3 节点副本集时也是如此)。因此,额外的仲裁器不会向副本集添加任何值。请参阅https://docs.mongodb.com/manual/core/replica-set-architectures/#consider-fault-tolerance 了解更多信息。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2013-05-25
    • 2021-02-09
    • 1970-01-01
    相关资源
    最近更新 更多