NoSQL технології на прикладі MongoDB
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Всім привіт!
Я Сергій Моренець, розробник, тренер і письменник, часто виступаю з вебінарами і воркшопами.При написанні четвертої частини свого циклу «Розробка Java додатків» я вирішив детально викласти використання NoSQL технологій, в першу чергу MongoDB. Це досить складна тема, особливо для тих, хто звик використовувати реляційні бази даних, тому я вирішив написати окрему статтю, де оглядово розповісти про NoSQL проекти, про їхню історію і, зокрема, про MongoDB.
Перш за все, що відноситься до NoSQL технологій і як вони з’явилися на світ? Сучасна історія баз даних починається в
- Tuple (кортеж) — невідсортований набір атрибутів (запис)
- Relation — набір кортежів (таблиця)
- Constraints — обмеження, що накладаються на схему даних
- Normal forms — результат реструктуризації або нормалізації таблиць
- Query language — мова запитів
З тих пір з’явилося досить багато реляційних СУБД, але в цілому, ми все ще використовуємо ті визначення, які з’явилися 50 років тому. У
- Фіксована схема даних (набір стовпців для таблиць)
- Транзакції (ACID)
- Підтримка SQL (ANSI SQL або розширення)
- Нормальні форми
Це призводило до різного роду складнощів і обмежень:
- Блокування рядків/таблиць/схем під час транзакцій
- Ускладнення SQL запитів (кількість поєднуваних таблиць) призводило до падіння продуктивності сервера і збільшення витрат пам’яті
- Дані можна було розміщувати на одному фізичному сервері
- Неможливість динамічно змінювати схему даних
- Неможливість використовувати складні типи даних (масиви, maps, JSON або
XML-структури) і вести пошук по ним
Однак все це було не настільки критично, поки кількість одночасних користувачів (транзакцій) і обсяги даних було не надто велике. Але ось настали
У цей момент з’явився термін scaling (масштабування), потім еластичність, як спроба подолати природні обмеження розміщення даних на одному сервері. З’явилися нові патерни — sharding/partitioning і реплікація. Старі добрі реляційні СУБД їх не підтримували або ще не підтримували, тому нові ІТ-гіганти почали створювати свої власні технології:
- 2006 року компанія Google представила проект BigTable
- 2007 року виник проект Hadoop
- У 2008 році Amazon почав розробку DynamoDB
- У 2009 році компанія 10Gen представила MongoDB
- У 2010 році з’явився проект Hive, який запропонував зручну мову запитів для Hadoop
Все це були сховища даних і системи з керування даними, які вже не були реляційними. Потрібно було спочатку придумати назву, а потім каталогізувати їх. І ось в 2009 році на одній з конференцій, де обговорювали BigTable і DynamoDB, придумали тег «Not only SQL», як пояснення, що нові системи не підтримують універсальну мову запитів SQL. Цей тег згодом скоротили до NoSQL. Але NoSQL технології не є однорідними, а діляться на 4 категорії (або моделі даних):
- Документні (document store)
- Ключ-значення (key-value)
- Wide-columns
- Графи (graph)
Такий поділ не означає, що кожна NoSQL БД відноситься тільки до однієї категорії. Наприклад, Amazon DynamoDB підтримує і документную модель, і ключ-значення. Більш того, в останні роки виділили ще дві категорії:
- Search engine (повнотекстовий пошук)
- Spatial (географічні та геометричні дані)
NoSQL технології широко застосовуються в Big Data проектах як сховища великих обсягів інформації, яку потрібно аналізувати і обробляти. Чим же NoSQL рішення відрізняються від реляційних СУБД?
- Відсутність підтримки SQL або якоїсь універсальної мови запитів. У кожної технології є своя власна мова, це пояснюється відмінностями в моделях даних і підтримуваних операціях. Хоча, наприклад в Apache Cassandra мова CQL дуже схожа на SQL
- За замовчуванням транзакції відсутні для прискорення роботи (вставки/зміни даних). Хоча в MongoDB 4.0 вони були введені на прохання розробників
- Неможливість об’єднувати в одному запиті різні relations (join в SQL)
- Гнучка схема даних, хоча і з можливістю її валідації
- Відсутні нормальні форми
- Eventual consistency (на противагу ACID і strong consistency в реляційних СУБД)
- Підтримка складних типів даних (списки, набори, maps, UUID, JSON, вкладені об’єкти)
- Вбудована реплікація і sharding
У той же час в NoSQL рішеннях є і звичні нам фітчи:
- індекси
- ідентифікатори об’єктів
Які мінуси NoSQL технологій:
- Відсутність єдиної стандартної мови запитів (такої як SQL)
- Відсутність єдиного API для доступу до даних (JDBC). Для кожної NoSQL СУБД є свій власний драйвер (в тому числі і на Java), а для Redis, наприклад їх цілих три.
- Неможливість використовувати Java EE (JPA), хоча є вже покинутий проект Hibernate OGM як спроба використовувати Hibernate для mapping’a
Не всі з цих мінусів є перешкодами. Наприклад, є популярний проект Spring Data для абстрагування доступу до сховищ даних (як NoSQL, так і реляційних). В Eclipse Microprofile з’явився аналог — JNoSQL. Але в цілому наявність різних моделей даних є безперечним плюсом. Більш того, з’явився такий термін як Polyglot Persistence, коли ви відмовляєтеся від єдиної (реляційної) БД на вашому проекті, а використовуєте ті сховища, які найкраще підходять для ваших завдань. Просто всі ці особливості ми розповідаємо на наших тренінгах по NoSQL.
Що ж реляційні бази даних? Для того, щоб не програти в цій еволюційної битві сховищ даних, деякі реляційні СУБД перетворилися в NewSQL-БД. По суті, вони мають ті ж характеристики, що й раніше (ACID, SQL), але запозичили багато фітчи з NoSQL технологій, щоб мінімізувати технологічне відставання:
- Реплікація
- Шардінг (масштабування)
- Покращена ефективність для великих обсягів даних
Найбільш яскравий приклад в цій категорії — Google Spanner (колишній проект Google BigTable).
Тепер давайте познайомимося з найбільш популярної категорією NoSQL — document-store, яка дозволяє зберігати дані довільної структури (schema-less) як колекцію документів.
Що таке документ? Використовуючи реляційні бази даних, ми звикли до того, що наші дані зберігаються в таблицях як рядки. У таблиці фіксований список стовпців і в кожному рядку зберігається певне значення для будь-якого стовпчика. Такий підхід з часом призводить до того, що список стовпців все більше і більше розширюється для підтримки нових фітч. Кількість стовпців може досягти
Які технології з цієї групи зараз популярні і затребувані?
- MongoDB
- Couchbase
- Amazon DynamoDB
- Microsoft Azure Cosmos DB
- CouchDB
Якщо ви не розглядаєте хмарні СУБД для хмарного проекту (DynamoDB і Cosmos DB), то серед інших трьох вибір очевидний — це MongoDB. Це не тільки найпопулярніша document-store технологія, але і сама використовувана NoSQL база даних.
Розробка цього амбітного проекту почалася в 2007 році компанією 10gen (2013 році перейменовану в 2013 році в MongoDB Inc), яку заснував американський програміст Дуайт Мерриман. MongoDB був його не першим проектом, але найуспішнішим. Перший публічний реліз відбувся в 2009 році, і з тих пір Mongo є флагманом NoSQL сховищ даних, включаючи чотири видання:
- Community Edition — для навчання, тестування, локальної розробки і невеликих проектів. Це єдина версія, для якої є офіційний Docker image.
- Enterprise Edition — включає in-memory storage engine, додаткові засоби безпеки і шифрування
- Atlas — хмарний сервіс, доступний в AWS, Google Cloud, Azure і т.д.
- Stich — serverless версія для мобільного і веб-розробки, коли ви можете звертатися до бази даних безпосередньо з JavaScript коду
MongoDB зберігає дані як JSON-документи, але в більш оптимальному і компактному форматі — BSON (бінарний JSON). BSON не тільки економить місце, але і за допомогою свого парсеру дозволяє зробити часткову зміну документа. Якщо для того, щоб змінити JSON документ, вам потрібно його спочатку повністю прочитати, змінити і потім зберегти, то BSON парсер може звернутися і змінити будь-який шматок документа, що скорочує загальний час операції.
Чи можна запхнути всі дані в один документ? На жаль, але в MongoDB є обмеження на розмір одного документа — 16 Мб. Така межа цілком обгрунтована. Для прискорення роботи MongoDB намагається зберігати часто використовувані дані в пам’яті. А так як документ являє собою єдине ціле, то і завантажуватися він буде цілком і займати пам’ять.
Як бути з бінарними даними (картинки, відео, аудіо)? Хоча BSON підтримує байтові масиви, але зберігати мультимедіа в документах вкрай не рекомендується через тих же обмежень. Для цього є спеціальний GridFS API, який дозволяє зберігати великі бінарні файли. Ці файли зберігаються не монолітно, а розбиваються на шматки (chunks) по 256 кб.
Наскільки безпечно використовувати MongoDB, якщо він зберігає частину даних в пам’яті? Що буде в разі апаратного збою? Для доступу до даних MongoDB використовує storage engine, який може бути трьох варіантів:
- MMAP (оголошений deprecated в версії 4.0)
- WiredTiger (з’явився в 3.2)
- In-Memory (доступно тільки для Enterprise Edition)
Тому для MongoDB 4 дефолтний движок — WiredTiger, який привніс багато цікавих фітч (мульти-документні транзакції, стиснення даних, блокування на рівні документа). Всі операції, які змінюють дані, зберігаються в спеціальному журнальному буфері, який зберігається в пам’яті. Кожні 100 мілісекунд вміст буфера синхронізується з журналом, який вже зберігається на диску. Кожні 100 секунд в журналі створюється контрольна точка (checkpoint), коли виконуються всі операції після попереднього checkpoint, і дані зберігаються на диск. Якщо протягом цих 100 секунд стався збій, то після рестарту сервера WiredTiger виконує всі операції, збережені в журналі після останнього checkpoint.
Чи підтримує MongoDB транзакції? Чи може вийде так, що якийсь документ збережеться частково? В цьому плані Mongo змінює документи атомарно. Незалежно від вмісту документа, ви завжди можете бути впевнені, що операція зміни завершиться успішно, або відкотиться. У MongoDB 4 на прохання розробників нарешті додали мульти-документні транзакції, які нам відомі по реляційним СУБД. Реалізацію ускладнювала наявність такої функціональності як реплікація і sharding, але все ж і підтримка sharding cluster була додана в версії 4.2. Правда, з кількома обмеженнями:
Ви не можете створювати колекції в рамках транзакції
- Таку транзакції можна здійснювати тільки на Mongo сервері, що входить в кластер для реплікації (нехай і з одного вузла)
Як ви бачите, в MongoDB є і свої переваги в порівнянні з реляційними СУБД, але вони вимагають зовсім іншого підходу на проектування та керування вашими даними.
Найкращі коментарі пропустити