Що означає, що MongoDB не відповідає сумісністю з ACID перед v4?


226

Я не фахівець з бази даних і не маю офіційного досвіду інформатики, тому поводьтеся зі мною. Я хочу знати, які реальні негативні речі можуть трапитися, якщо ви використовуєте стару версію MongoDB до версії v4 , яка не відповідала ACID . Це стосується будь-якої бази даних, не сумісних з ACID.

Я розумію, що MongoDB може виконувати атомні операції , але вони не "підтримують традиційні блокування та складні транзакції", переважно з міркувань продуктивності. Я також розумію важливість транзакцій із базами даних, і на прикладі, коли ваша база даних призначена для банку, і ви оновлюєте кілька записів, які потрібно синхронізувати, ви хочете, щоб транзакція повернулася до початкового стану, якщо є відключення електроенергії, тому кредит дорівнює покупці тощо.

Але коли я вступаю в розмови про MongoDB, ті з нас, хто не знає технічних деталей того, як реально реалізуються бази даних, починають обробляти твердження на зразок:

MongoDB набагато швидший, ніж MySQL та Postgres, але є невеликий шанс, як 1 на мільйон, що він "не збережеться правильно".

Ця частина "не збережеться правильно" посилається на таке розуміння: Якщо в момент, коли ви пишете в MongoDB, відключення електроенергії є шанс на певний запис (скажімо, ви відстежуєте перегляд сторінки в документах з 10 атрибутами кожен), що в одному з документів збережено лише 5 атрибутів ... це означає, що з часом ваші лічильники перегляду сторінок будуть "трохи" вимкнені. Ви ніколи не дізнаєтесь на скільки, знаєте, що вони будуть на 99,999% правильними, але не на 100%. Це тому, що, якщо ви спеціально не зробили цю атомну операцію монгобада , ця операція не гарантована як атомна.

Отже, моє запитання полягає в тому, що таке правильне тлумачення, коли і чому MongoDB може не "правильно зберегти"? Які частини кислоти не задовольняє, і за яких обставин, і як ви знаєте, коли вимкнено ці 0,001% ваших даних? Неможливо це якось виправити? Якщо ні, це, мабуть, означає, що не слід зберігати такі речі, як ваша usersтаблиця, у MongoDB, оскільки запис може не зберегтись. Але знову ж таки, що 1/1000000 користувачеві може просто потрібно "спробувати підписатись ще раз", ні?

Я просто шукаю, можливо, список того, коли / чому трапляються негативні речі з невідповідною базою даних ACID, на зразок MongoDB, і в ідеалі, якщо є стандартне вирішення (наприклад, запустити фонове завдання для очищення даних або використовувати для цього лише SQL тощо). .

Відповіді:


133

Одне, що ви втрачаєте за допомогою MongoDB, - це транзакції з декількома колекціями (таблиці). Атомні модифікатори в MongoDB можуть працювати лише проти одного документа.

Якщо вам потрібно вилучити предмет із інвентаря і одночасно додати його до чийогось замовлення - ви не можете. Якщо ці дві речі - інвентар та накази - існують в одному документі (чого вони, мабуть, не роблять).

З цією самою проблемою я стикався в додатку, над яким працюю, і мав два варіанти вирішення:

1) Структуруйте свої документи якнайкраще та використовуйте атомні модифікатори якнайкраще, а для решти бітів використовуйте фоновий процес для очищення записів, які можуть бути синхронізовані. Наприклад, я видаляю елементи з інвентарю та додаю їх до масиву rezervi інвентаризації того ж документа за допомогою атомних модифікаторів.

Це дозволяє мені завжди знати, що предмети НЕ доступні в інвентарі (тому що вони зарезервовані замовником). Коли клієнт виїжджає, я вилучаю елементи із зарезервованого Інвентаря. Це не є звичайною транзакцією, і оскільки замовник міг відмовитися від кошика, мені потрібен передумови для пошуку та пошуку занедбаних візків та переміщення зарезервованого інвентарю у наявний пул інвентарю.

Це, очевидно, менш ідеально, але це єдина частина великого застосування, де mongodb не відповідає ідеально. Плюс до цього часу він працює бездоганно. Це може бути неможливим для багатьох сценаріїв, але через структуру документа, яку я використовую, вона добре підходить.

2) Використовуйте транзакційну базу даних спільно з MongoDB. MySQL звичайно використовувати для надання транзакцій для речей, які їм абсолютно потрібні, дозволяючи MongoDB (або будь-якому іншому NoSQL) робити те, що найкраще.

Якщо моє рішення з №1 не працює в довгостроковій перспективі, я буду далі досліджувати поєднання MongoDB з MySQL, але поки що №1 добре відповідає моїм потребам.


27
" Атомні модифікатори в MongoDB можуть працювати лише проти однієї колекції " => Я думаю, ви мали на увазі "проти одного документа ".
assylias

2
Відмінна інформація, як правило, відмінна відповідь за винятком пропозицій використовувати MySQL.
Дуг Моліно

״ Одне, що ви втрачаєте за допомогою MongoDB, - це транзакції з декількома колекціями (таблиці). Атомні модифікатори в MongoDB можуть працювати лише проти одного документа ״ від mongo doc ( docs.mongodb.com/v3.2/core/write-operations-atomicity ): "У MongoDB операція запису є атомною на рівні єдиного документа, навіть якщо операція модифікує кілька вбудованих документів в одному документі. "
yoav.str

5
Відсутність багатодокументарних транзакцій ACID більше не стосується. MongoDB оголосив, що надходить у v4.0. Дивіться mongodb.com/blog/post/multi-document-transaction-in-mongodb
Григорій Мельник

1
Наразі, оскільки MongoDB 4.0 є сумісним з ACID mongodb.com/transaction з транзакціями з кількома документами. Подивіться на mongodb.com/blog/post/…
Рата,

134

Насправді не правильно, що MongoDB не відповідає сумісному кислоту. Навпаки, MongoDB є компілятором ACID на рівні документа .

Будь-яке оновлення одного документа є

  • Атомний: він або повністю завершений, або його немає
  • Послідовно: жоден читач не побачить "частково застосованого" оновлення
  • Ізольовано: знову ж таки, жоден читач не побачить "брудного" прочитаного
  • Міцний: (з відповідною проблемою щодо написання)

У MongoDB немає транзакцій - тобто оновлення декількох документів, які можна повернути назад і відповідають стандартам ACID.

Зауважте, що ви можете будувати транзакції поверх оновлень, сумісних з ACID, до одного документа, використовуючи двофазну фіксацію .


3
Зауважте, що транзакції двофазних комісій не відповідають стандартам ACID. Чомусь я зробив висновок про протилежне, поки не перейшов за посиланням.
Джастін С

1
Існує певне питання щодо довговічності розподіленого MongoDB на рівні документа, незалежно від конфігурації запису. Інструмент із відкритим кодом Jepsen виявив, що дані можуть бути втрачені перед мережевим розділом навіть із занепокоєнням щодо МАЙБОРІТНОСТІ щодо запису. Дивіться підписку
jrullmann

9
Наявність ACID на рівні одного документа, який певним чином еквівалентний одному запису в RDBMS, не є корисним у багатьох випадках. Термін транзакції не стосується однієї таблиці, і ви навіть можете мати механізм двофазної фіксації та залучати кілька XAResource, отже, посилання на один документ як сумісний із ACID є дещо проблематичним, IMHO.
Яїр Заславський

5
Погодьтеся з Яїром. "Відповідність ACID на рівні документа" не є торговою точкою. Це в основному просто означає "не сумісний з кислотами". ACID ніколи не мав на увазі "лише один рядок / документ / сутність". Йдеться про збереження ваших даних послідовним у всій базі даних.
joshua.paling

34

Хороше пояснення міститься в "Starbucks не використовує двофазну комісію" .

Мова не йде про бази даних NoSQL, але це ілюструє те, що іноді ви можете дозволити собі втратити транзакцію або тимчасово зберегти свою базу даних у непослідовному стані.

Я б не вважав, що це щось, що потрібно "виправити". Виправлення полягає у використанні реляційної бази даних, сумісної з ACID. Ви вибираєте альтернативу NoSQL, коли її поведінка відповідає вашим вимогам програми.


1
Як і будь-яка аналогія, вона має свої обмеження. У програмному забезпеченні легко створити новий масив [касири] і змусити їх обробляти синхронні транзакції кожен, тоді як реальна вартість у світі була б смішно дорогою.
HRJ

16

Я думаю, інші люди вже дали хороші відповіді. Однак я хотів би додати, що є ACID NOSQL БД (наприклад, http://ravendb.net/ ). Тож це не тільки рішення NOSQL - не ACID проти реляційних з ACID ....


1
дякую @subGate хтось там, хто може поділитися своїм досвідом роботи з ravenDB і якщо він дійсно задовольняє цій вимозі?
Нір Пенгас

12

"не збережеться правильно" може означати:

  1. За замовчуванням MongoDB не зберігає ваші зміни на диску. Тож існує можливість сказати користувачеві "оновлення успішно", відключення живлення відбувається і оновлення втрачено. MongoDB пропонує варіанти контролю рівня "довговічності" оновлення. Він може чекати, коли інші репліки отримають це оновлення (в пам'яті), чекають, коли запис відбудеться у файлі локального журналу тощо.

  2. Немає легких "атомних" оновлень для кількох колекцій і навіть декількох документів в одній колекції. У більшості випадків це не проблема, оскільки її можна обійти двофазним комітетом або реструктуризувати вашу схему, щоб оновлення були внесені до одного документа. Дивіться це запитання: Бази даних документів: надлишкові дані, посилання тощо (спеціально для MongoDB)


10

Станом на MongoDB v4.0, транзакції ACID з багатодокументарними документами мають підтримуватися. Завдяки ізоляції знімків транзакції забезпечують глобальний узгоджений вигляд даних та примушують виконувати все або нічого, щоб підтримувати цілісність даних.

Вони відчувають себе як транзакції з реляційного світу, наприклад:

with client.start_session() as s:
    s.start_transaction()
    try:
        collection.insert_one(doc1, session=s)
        collection.insert_one(doc2, session=s)
        s.commit_transaction()
    except Exception:
        s.abort_transaction()

Дивіться https://www.mongodb.com/blog/post/multi-document-transaction-in-mongodb


Кандидат у перший реліз MongoDB4.0 вийшов - linkedin.com/pulse/mongodb-40-rc0-now-available-grigori-melnik
Григорій Мельник

5

Прочитайте про властивості кислотних кислот, щоб краще зрозуміти.

Також у документації MongoDB ви можете знайти запитання та відповіді .

MongoDB не сумісний із кислотами. Читайте нижче для обговорення відповідності ACID.

  1. MongoDB є Aтомічним лише на рівні документа. Це не відповідає визначенню атомних, яке нам відомо з реляційних систем баз даних, зокрема посилання вище. У цьому сенсі MongoDB не відповідає А від кислоти.
  2. MongoDB Cза замовчуванням знаходиться на сайті. Однак ви можете читати з вторинних серверів у наборі реплік. У цьому випадку ви можете мати лише можливу послідовність . Це корисно, якщо ви не проти прочитати трохи застарілі дані.
  3. MongoDB не гарантує Iзаспокоєння (знову ж таки згідно з вищезазначеним визначенням):
  1. Для систем з декількома одночасними читачами та авторами MongoDB дозволить клієнтам читати результати операції запису до повернення операції запису.
  2. Якщо mongod закінчується до початку журналу, навіть якщо запис успішно повертається, запити можуть прочитати дані, які не будуть існувати після перезапуску mongod.

Однак MongoDB змінює кожен документ окремо (для вставок та оновлень); лише на рівні документа, а не на багатодокументних транзакціях.

  1. Що стосується Dурабільності - ви можете налаштувати цю поведінку за допомогою write concernпараметра, але не впевнений. Можливо, хтось знає краще.

Я вважаю, що деякі дослідження тривають з метою переміщення NoSQL до обмежень ACID або подібного. Це завдання, оскільки бази даних NoSQL зазвичай швидкі (ер), а обмеження ACID можуть значно уповільнити продуктивність.


4

Єдина причина, по якій атомні модифікують роботу проти однієї колекції, полягає в тому, що розробники mongodb нещодавно обмінялися блокуванням бази даних з широким блокуванням запису на колекцію. Вирішивши, що підвищена сумісність тут вартує компромісу. По суті, mongodb - це файл із картографічною пам'яттю: вони делегували управління буферним пулом підсистемою vm машини. Оскільки це завжди в пам’яті, вони здатні відійти від дуже замкнених курсів: ви будете виконувати лише операції в пам'яті, утримуючи її, що буде надзвичайно швидко. Це суттєво відрізняється від традиційної системи баз даних, яка іноді змушена виконувати введення-виведення під час тримання блоку сторінки або блокування рядків.


Ви можете пояснити, чому це збільшує одночасність? Вибачте, якщо я пропускаю очевидне тут.
батбрат

@batbrat: Розглянемо двох клієнтів, які намагаються одночасно записувати в різні колекції в одній базі даних. Заблокувавши базу даних, одному з клієнтів доведеться чекати, коли інший закінчиться, перш ніж може відбутися його запис. Зі замком колекції обидва клієнта можуть писати одночасно. Ось що мається на увазі під підвищеною одночасністю. Звичайно, якщо обидва клієнта намагаються записатись до однієї колекції, то доведеться почекати.
jrullmann

2

"У MongoDB операція над одним документом є атомною" - Це справа минулого

У новій версії MongoDB 4.0 ви МОЖЕТЕ:

Однак для ситуацій, які потребують атомності для оновлення декількох документів або узгодженості між читаннями для декількох документів, MongoDB надає можливість здійснювати транзакції з кількома документами проти наборів реплік. Операції з декількома документами можна використовувати в багатьох операціях, колекціях, базах даних та документах. Багатодокументні транзакції пропонують пропозицію "все або нічого". Коли транзакція вчиняється, всі зміни даних, здійснені в транзакції, зберігаються. Якщо будь-яка операція в транзакції завершилася невдачею, транзакція припиняється, а всі зміни даних, здійснені в транзакції, відкидаються, не стаючи видимими. Поки транзакція не вчиняється, жодні операції запису транзакції не видно поза транзакцією.

Хоча обмеження щодо того, як і які операції можна виконати, є невеликими .

Перевірте документацію Монго. https://docs.mongodb.com/master/core/transaction/


1

Ви можете впроваджувати атомні оновлення з декількома ключами (транзакції, що можна здійснити серіалізацію) на стороні клієнта, якщо ваше сховище підтримує лінійність за ключовими можливостями та порівнює та встановлює (що справедливо для MongoDB). Цей підхід використовується в Percolator Google і в CockroachDB, але ніщо не заважає вам використовувати його з MongoDB.

Я створив поетапну візуалізацію таких транзакцій. Сподіваюся, це допоможе тобі зрозуміти їх.

Якщо ви добре з рівнем ізоляції, зчитуваного з читання, то має сенс поглянути на операції RAMP Пітера Бейліса. Вони також можуть бути реалізовані для MongoDB на стороні клієнта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.