Сильное падение производительности с помощью MongoDB Change Streams

Я хочу получать обновления в реальном времени о изменениях базы данных MongoDB в Node.js.

Один поток изменений MongoDB отправляет уведомления об обновлениях почти мгновенно. Но когда я открываю несколько потоков (10+), между записью базы данных и приходом уведомления происходят массивные задержки (до нескольких минут).

Это как настроить поток изменений:

let cursor = collection.watch([
  {$match: {"fullDocument.room": roomId}},
]);
cursor.stream().on("data", doc => {...});

Я попробовал альтернативный способ создания потока, но он так же медленный:

let cursor = collection.aggregate([
  {$changeStream: {}},
  {$match: {"fullDocument.room": roomId}},
]);
cursor.forEach(doc => {...});

Автоматический процесс вставляет крошечные документы в коллекцию при сборе данных о производительности.

Дополнительные сведения:

  • Количество открытых курсоров: 50
  • Скорость записи: 100 документов/сек (партии из 10 с использованием insertMany)
  • Время выполнения: 100 секунд
  • Средняя задержка: 7,1 секунды
  • Самая большая задержка: 205 секунд (не опечатка, более трех минут)
  • Версия MongoDB: 3.6.2
  • Настройка кластера №1: MongoDB Atlas M10 (3 набора реплик)
  • Настройка кластеров # 2: блок DigitalOcean Ubuntu + одномодовый кластер mongo в Docker
  • Использование процессора Node.js: <1%

Обе установки создают одну и ту же проблему. Что здесь может быть?

Ответы

Ответ 1

Размер пула соединений по умолчанию в клиенте Node.js для MongoDB равен 5. Поскольку каждый курсор потока изменений открывает новое соединение, пул соединений должен быть как минимум равным числу курсоров.

const mongoConnection = await MongoClient.connect(URL, {poolSize: 100});

(Спасибо MongoDB Inc. за расследование этой проблемы.)