Сильное падение производительности с помощью 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. за расследование этой проблемы.)