Node.js + MongoDB: перформанс транзакцій
«Іноді ми платимо найбільше за те, що отримуємо безкоштовно» — А.Ейнштейн
Не так давно в MongoDB версії 4+ з’явилась підтримка мульти-документних транзакцій.
А оскільки наш проект якраз мігрував на версію 4.2, закономірно виникли запитання:
- Що буде з перформансом?
- На скільки операції сповільняться?
- Чи готові ми пожертвувати швидкістю заради (хоч якоїсь) точності?
Під час вивчення документації та інтернетів питань тільки побільшало:
- Чи всі операції буде сповільнено за рахунок транзакцій?
- На скільки буде сповільнено комбінації операцій?
Давайте спробуємо дати відповіді на ці запитання.
Для того, щоб претендувати хоча б на якусь мізерну долю істини — доведеться трохи попрацювати. Для простоти сприйняття розділю імплементацію на 3 кроки:
- Вибір інструментів
- Опис комбінацій операцій та отримання результатів
- Аналіз результатів
Тепер про кожен окремий крок детально.
Вибір інструментів:
- Необхідна тестова MongoDB (репліка з мінімільною кількістю mongod процесів) і драйвер для неї: mongodb-memory-server, mongodb.
- Для простоти вимірювання часу я обрав модуль «microseconds»
- Для аналізу отриманих результатів та візуалізації використаємо наступне: ttest, stdlib.
Опис комбінацій операцій та отримання результатів:
Імплементуємо кожну (із основних) окрему операцію 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 результатів «посередині», тобто з
Тепер, постійно змінюючи послідовність, проведемо 100 «макроітерації» (1 «макроітерація» = загальна кількість «мікроітарацій» * 300)*
* кількість 300 обрано абсолютно емпірично
** для більш повної інформації про імплементацію запрошую відвідати github репозиторій (посилання нижче по тексту)
Аналіз результатів:
В результаті всіх ітерацій ми отримали 20000 замірів для кожної операції та комбінації операцій (10000 з використанням транзакції, 10000 — без) у вигляді масивів
Далі необхідно провести деякі обчислення.
Обрізати результати, які явно випадають за межі вибірки
Вирахувати середнє значення
Знайти стандартне відхилення
Визначити існування статистично достовірної різниці між вибірками за допомогою ttest (підтвердження або спростування нульової гіпотези)
Візуалізуємо результати за допомогою простих графіків. Для прикладу візьмемо комбінацію insertMany + updateMany + deleteMany та окремо insertOne (всі інші результати будуть викладені в текстовому форматі в розділі «Висновки»). В результаті у згенерованих html-файлах маємо графік, назва якого відповідає назві операції чи комбінації операції (бірюзовим кольором позначені безтранзакційні ітерації, оранжевим — транзакційні). «Is statistically significant» (true/false) говорить про те, чи була взагалі якась статистично значима різниця. Все інше — абсолютні та відносні значення в мікросекундах та відсотках відповідно.
Висновки:
- Взагалі, це не має ніякої різниці між операціями з використанням транзакцій і без: 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.
Дякую за те, що прочитали.
Не соромтесь коментувати, сподіваюся, що у нас буде хороша дискусія.
Також ви можете запустити все це самостійно і отримати власні результати. Буде круто їх порівняти
Корисні посилання:
medium.com/...ith-mongoose-5bf8a6e22033
blog.yugabyte.com/...performance-applications
medium.com/...-mongodb-4-0-eebd662ac237
www.mongodb.com/...ions-general-availability
docs.mongodb.com/...ite-operations-atomicity
www.dbta.com/...-Transactions-127057.aspx
dzone.com/...ransactions-on-mongodb-40
www.dbta.com/...ions-In-Depth-125890.aspx
www.codementor.io/...wo-phase-commit-u6blq7465
docs.mongodb.com/...tion-consistency-recency
mathworld.wolfram.com/Outlier.html
support.minitab.com/...-the-results/key-results
18 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів