Express не может подключиться к набору реплик mongodb при выборе нового основного

У меня есть mongodb replica set со следующим конфигом:

  • М1 первичный
  • М2 вторичный
  • М3 вторичный
  • Арбитр М4

Вот мой экспресс-код для подключения к БД (я использую 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,

Что-то не так в моем конфиге?

2 ответа

Решение

URL соединения должен быть:

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

Итак, есть список узлов и после этого идет информация о базе данных.

И в вашей настройке тоже есть один недостаток... Когда у вас установлены три реплики узла, вы НЕ ДОЛЖНЫ иметь арбитра, как указано выше! Это потому, что подсчет голосов должен быть нечетным, а не четным.

Строка подключения URI MongoDB не соответствует нужному формату. Имя базы данных следует добавлять после списка серверов, а не на каждом сервере. Пытаться:

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/ для примера.

С другой стороны, вам не нужен арбитр для набора реплик. Не рекомендуется иметь четное количество узлов в наборе реплик, так как для выбора первичного сервера требуется большинство.

С 4 узлами, если 2 узла не работают, оставшиеся узлы не могут выбрать первичный (что также имеет место, когда у вас есть набор реплик из 3 узлов). Следовательно, дополнительный арбитр не добавляет никакого значения к набору реплик. См. https://docs.mongodb.com/manual/core/replica-set-architectures/ для получения дополнительной информации.

Другие вопросы по тегам