简体   繁体   中英

Express can't connect to mongodb replica set when new primary get elected

I have a mongodb replica set with the following config:

  • M1 primary
  • M2 secondary
  • M3 secondary
  • M4 arbitrator

Here is my Express code to connect to db (I use mongoose as the 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()
})

The app works as expected. When M1 get down, either M2 or M3 get elected to be the primary , BUT my express app still CAN'T connect to the replica set .

Is there any wrong in my config?

Connection URL should be:

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

So, there is a list of nodes and after that comes information about the database.

And your setup has one flaw too... When you have three node replica set, you SHOULD NOT have arbitrator as forth! This because, vote count must be odd not even .

Your MongoDB URI connection string is not following the proper format. The database name should be appended after the server list, and not appended on every server. Try:

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}

See https://docs.mongodb.com/manual/reference/connection-string/#connection-string-options for an example.

On another note, you don't need an arbiter on the replica set. It's not recommended to have an even number of nodes in a replica set, since it requires a majority to elect a primary.

With 4 nodes, if 2 of the nodes are down, the remaining nodes are not able to elect a primary (which is also the case when you have a 3-node replica set). Hence, the additional arbiter doesn't add any value to the replica set. See https://docs.mongodb.com/manual/core/replica-set-architectures/#consider-fault-tolerance for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM