选出新的主节点时,Express 无法连接到 mongodb 副本集
Express can't connect to mongodb replica set when new primary get elected
我有一个 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
。
我的配置有问题吗?
您的 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。
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.
我有一个 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
。
我的配置有问题吗?
您的 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。
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.