Node.js и MongoDB: производительность транзакций

Эпиграф

Иногда мы платим больше всего за то, что получаем бесплатно. ― Альберт Эйнштейн
Все в этом мире должно быть измерено. Цифры — единственный источник истины. Не верь никому, не верь себе. Мера. ― Я

Проблема?

В MongoDB 4+ мы получили поддержку многодокументных транзакций. Но как насчет производительности? Мы будем двигаться медленнее? Давайте разберемся!

На вопросы нужны ответы

Влияют ли транзакции на скорость основных операций MongoDB?

Влияют ли транзакции на скорость последовательности операций?

Есть ли разница в скорости основных операций MongoDB (и их комбинации) с транзакциями и без них?

Какая разница в скорости основных операций MongoDB (и их комбинации) с транзакциями и без них?

Реализация: шаг 1 (инструменты)

  1. Мы использовали MongoDB v4.0.3 (модуль mongodb-memory-server) — набор реплик (с минимальным количеством процессов mongod)
    https://www.npmjs.com/package/mongodb-memory-server
  2. Использование драйвера MongoDB v3.3.4 (модуль mongodb)
    https://www.npmjs.com/package/mongodb
  3. Что-то нужно для получения данных (мы использовали модуль микросекунды)
    https://www.npmjs.com/package/microseconds
  4. Данные нужно проанализировать (используем модуль ttest) и красиво отрисовать (модуль @stdlib/stdlib)
    https://www.npmjs.com/package/ttest< br /> https://www.npmjs.com/package/@stdlib/stdlib
  5. Процесс сбора данных займет много времени (поверьте), потому что нужно что-то для красоты и наглядности (модуль progress-barjs)
    https://www.npmjs.com/package/progress -баржс
  6. Осталось написать код(

Реализация: Шаг 2 (результаты)

Реализовать основные операции MongoDB ― insertOne, updateOne, deleteOne, findOne, insertMany*, updateMany*, deleteMany*, find*; и их комбинации ― insertOne + updateOne + deleteOne, insertOne + updateOne + deleteOne + findOne, insertMany* + updateMany* + deleteMany*, insertMany* + updateMany* + deleteMany* + find* с использованием и без использования транзакций

Измеряйте время выполнения каждой операции

Пример (операцияinsertMany + updateMany + deleteMany) с транзакцией и без нее:

Выполнить каждую операцию/измерение времени итерациями 300 раз (для последующего анализа будет использовано 100 «усредненных» измерений от 101 до 200)*

Выполнять операции в случайной последовательности в количестве 100 итераций**

* «много» = 300 (подобрано чисто эмпирическим путем)
** для получения дополнительной информации о реализации посетите репозиторий github (ссылка в конце этой статьи)

Реализация: Шаг 3 (анализ)

Сохраняем данные по каждой операции в массивы (всего 20 000 измерений на операцию ― 10 000 с использованием транзакций, 10 000 без)

Обрезать значения, выходящие за границы выделения

Рассчитать среднее

Рассчитать стандартное отклонение

Определите, есть ли статистически значимая разница между выборками

Какова средняя разница между выполнением каждого вида операции и в чью пользу?

На картинке ниже показаны результаты одной комбинации операций (insertMany + updateMany + deleteMany) и операции insertOne. Для других операций результат выглядит так же и описан в разделе заключение. Здесь у нас есть название операции(й) (insertManyUpdateManyDeleteMany и insertOne), среднее значение со стандартным отклонением (бирюзовый ― без транзакции, оранжевый ― с транзакцией), «Статистически значимо» означает, что существует некоторая разница между производительностью с/без транзакции и как операции с транзакцией выполняются медленнее или быстрее в процентах

Вывод

В общем, нет разницы: insertMany + updateMany + deleteMany (см. иллюстрацию выше)

Разница есть, ну такая (до 7%): updateMany, find, insertOne + updateOne + deleteOne + findOne, insertMany + updateMany + deleteMany + find

Транзакции медленнее, но не так сильно (до 91%): updateOne, deleteMany, findOne

Транзакции выполняются намного медленнее (со 197% до 792%): insertOne, insertMany, deleteOne, insertOne + updateOne + deleteOne

Для получения дополнительной информации и возможности самостоятельно проверить результаты, запустив скрипты, ― посетите репозиторий github.



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

использованная литература

https://medium.com/cashpositive/the-hitchhikers-guide-to-mongodb-transactions-with-mongoose-5bf8a6e22033
https://blog.yugabyte.com/are-mongodb-acid- готовые к транзакциям для высокопроизводительных приложений/
https://medium.com/@Alibaba_Cloud/multi-document-transactions-on-mongodb-4-0-eebd662ac237
https://www.mongodb.com/blog/post/mongodb-multi-document-acid-transactions-general-availability
https://docs.mongodb.com/manual/core/write-operations -atomicity/
http://www.dbta.com/Columns/MongoDB-Matters/Limitations-in-MongoDB-Transactions-127057.aspx
https://dzone.com/ article/multi-document-transactions-on-mongodb-40
http://www.dbta.com/Columns/MongoDB-Matters/MongoDB-Transactions-In-Depth-125890.aspx
> https://www.codementor.io/@christkv/mongodb-transactions-vs-two-phase-commit-u6blq7465
https://docs.mongodb.com/manual/core/read- изоляция-согласованность-недавность/
https://mathworld.wolfram.com/Outlier.html
https:// support.minitab.com/en-us/minitab-express/1/help-and-how-to/basic-statistics/inference/how-to/two-samples/2-sample-t/interpret-the-results/ ключевые результаты/