Что на самом деле означало, что MongoDB не был совместим с ACID до версии 4?

Я не эксперт по базам данных и не имею формального образования в области компьютерных наук, так что терпите меня. Я хочу знать, какие реальные негативные явления могут произойти, если вы используете старый MongoDB. версии до v4, которые не соответствовали ACID. Это относится к любой базе данных, несовместимой с ACID.

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

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

MongoDB намного быстрее MySQL и Postgres, но есть крошечный шанс, вроде 1 на миллион, что он «не сохранит правильно».

Эта часть «не будет сохраняться правильно» относится к следующему пониманию: если произойдет отключение электроэнергии прямо в тот момент, когда вы пишете в MongoDB, есть шанс для конкретной записи (скажем, вы отслеживаете просмотры страниц в документах с 10 атрибутами каждый), что один из документов сохранил только 5 атрибутов ... что означает, что со временем ваши счетчики просмотров страниц будут «немного» отключены. Вы никогда не узнаете на сколько, вы знаете, что они будут правильными на 99,999%, но не на 100%. Это связано с тем, что, если вы специально не сделали это атомарной операцией mongodb, операция будет не гарантируется, что он был атомарным.

Итак, мой вопрос: как правильно интерпретировать, когда и почему MongoDB не может «правильно сохранять»? Каким частям ACID он не удовлетворяет, и при каких обстоятельствах, и как узнать, что 0,001% ваших данных отключены? Нельзя это как-то исправить? В противном случае это означает, что вам не следует хранить такие вещи, как ваша таблица users в MongoDB, потому что запись может не сохраниться. Но опять же, этому пользователю 1/1 000 000, возможно, просто нужно «попробовать зарегистрироваться снова», не так ли?

Я просто ищу, возможно, список того, когда и почему происходят негативные вещи с несоответствующей ACID базой данных, такой как MongoDB, и, в идеале, есть стандартный обходной путь (например, запустить фоновое задание для очистки данных или использовать только SQL для этого и т. Д.) .


person Lance Pollard    schedule 22.08.2011    source источник


Ответы (10)


Одна вещь, которую вы теряете с MongoDB, - это транзакции с несколькими коллекциями (таблицами). Атомарные модификаторы в MongoDB могут работать только с одним документом.

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

Я столкнулся с этой же проблемой в приложении, над которым работаю, и у меня было два возможных решения на выбор:

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

Это позволяет мне всегда знать, что предметы НЕ доступны в инвентаре (потому что они зарезервированы покупателем). Когда покупатель выезжает, я удаляю элементы из зарезервированного инвентаря. Это не стандартная транзакция, и, поскольку покупатель может покинуть корзину, мне нужен какой-то фоновый процесс, чтобы найти брошенные тележки и переместить зарезервированный инвентарь обратно в доступный инвентарный пул.

Это явно далеко не идеально, но это единственная часть большого приложения, где mongodb не подходит идеально. К тому же пока работает безупречно. Это может быть невозможно для многих сценариев, но из-за структуры документа, которую я использую, она подходит.

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

Если мое решение из №1 не сработает в долгосрочной перспективе, я продолжу исследование объединения MongoDB с MySQL, но на данный момент №1 хорошо соответствует моим потребностям.

person Bryan Migliorisi    schedule 22.08.2011
comment
Атомарные модификаторы в MongoDB могут работать только с одной коллекцией = ›Я думаю, вы имели в виду против одного документа. - person assylias; 05.04.2013
comment
Отличная информация, как правило, отличный ответ, за исключением предложения использовать MySQL. - person Doug Molineux; 24.10.2014
comment
״ Одна вещь, которую вы теряете с MongoDB, - это транзакции с несколькими коллекциями (таблицами). Атомарные модификаторы в MongoDB могут работать только с одним документом ״ из mongo doc (docs.mongodb.com/v3.2/core/write-operations-atomicity): в MongoDB операция записи является атомарной на уровне одного документа, даже если операция изменяет несколько встроенных документов в одном документ. - person yoav.str; 15.01.2017
comment
Отсутствие многодокументных транзакций ACID больше не актуально. MongoDB объявила о выходе версии 4.0. См. mongodb.com/blog/post/multi-document-transactions -in-mongodb - person Grigori Melnik; 18.02.2018
comment
На данный момент, поскольку MongoDB 4.0 соответствует требованиям ACID, mongodb.com/transactions с транзакциями с несколькими документами. Взгляните на mongodb.com/blog/ post / - person Ratah; 25.02.2019

На самом деле неправильно, что MongoDB не соответствует требованиям ACID. Напротив, MongoDB является ACID-компилятором на уровне документа.

Любое обновление отдельного документа

  • Атомарный: либо полностью завершается, либо нет.
  • Согласовано: ни один читатель не увидит «частично примененное» обновление.
  • Изолировано: опять же, ни один читатель не увидит "грязного" чтения
  • Долговечный: (с соответствующей записью)

В MongoDB нет транзакций, то есть обновлений нескольких документов, которые можно откатить и которые совместимы с ACID.

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

person William Z    schedule 06.07.2013
comment
Обратите внимание, что транзакции двухфазных коммитов несовместимы с ACID. Почему-то предполагал обратное, пока не перешел по ссылке. - person Justin C; 27.07.2014
comment
Возникает вопрос о надежности распределенной базы данных MongoDB на уровне документа, независимо от конфигурации проблемы записи. Инструмент с открытым исходным кодом Jepsen обнаружил, что данные могут быть потеряны из-за сетевого раздела даже при БОЛЬШИНСТВЕ проблем записи. См. Описание здесь: aphyr.com/posts/284-call-me -maybe-mongodb - person jrullmann; 03.09.2014
comment
Наличие ACID на уровне отдельного документа, которое в некотором роде эквивалентно отдельной записи в СУБД, во многих случаях не полезно. Срок транзакции не относится к одной таблице, и вы даже можете иметь механизм двухфазной фиксации и задействовать несколько XAResource, поэтому ссылка на один документ как на ACID-совместимый несколько проблематична, ИМХО. - person Yair Zaslavsky; 12.02.2016
comment
Согласен с Яиром. ACID-совместимость на уровне документов не является преимуществом. По сути, это просто означает несовместимость с ACID. ACID никогда не предназначался для одной строки / документа / объекта. Речь идет о том, чтобы ваши данные были согласованы во всей базе данных. - person joshua.paling; 20.11.2016

Хорошее объяснение содержится в «Starbucks не использует двухфазную фиксацию».

Речь не идет о базах данных NoSQL, но это действительно иллюстрирует то, что иногда вы можете позволить себе потерять транзакцию или временно оставить свою базу данных в несогласованном состоянии.

Я бы не стал считать это чем-то, что нужно «исправить». Исправление заключается в использовании реляционной базы данных, совместимой с ACID. Вы выбираете альтернативу NoSQL, если ее поведение соответствует требованиям вашего приложения.

person duffymo    schedule 22.08.2011
comment
Как и у любой аналогии, у него есть свои ограничения. В программном обеспечении легко создать новый массив [кассиров] и заставить их обрабатывать синхронные транзакции каждый, в то время как реальная мировая стоимость этого была бы смехотворно высокой. - person HRJ; 07.12.2012

Я думаю, что другие люди уже дали хорошие ответы. Однако я хотел бы добавить, что существуют базы данных ACID NOSQL (например, http://ravendb.net/). Так что это не только решение NOSQL - нет ACID против Relational с ACID ....

person SubGate    schedule 28.02.2013
comment
спасибо @subGate. кто-нибудь, кто может поделиться своим опытом работы с ravenDB, и действительно ли он удовлетворяет требованиям? - person Nir Pengas; 22.10.2013

Начиная с 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-transactions-in-mongodb

person Grigori Melnik    schedule 18.02.2018
comment
Вышел первый кандидат на выпуск MongoDB4.0 - linkedin.com/pulse/mongodb-40-rc0-now-available-grigori-melnik - person Grigori Melnik; 25.05.2018

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

  1. По умолчанию MongoDB не сохраняет ваши изменения на диске сразу. Таким образом, существует вероятность того, что вы скажете пользователю «обновление выполнено успешно», произойдет отключение электроэнергии и обновление будет потеряно. MongoDB предоставляет опции для контроля уровня «стойкости» обновлений. Он может ждать, пока другие реплики получат это обновление (в памяти), дождаться записи в локальный файл журнала и т. Д.

  2. Не существует простого «атомарного» обновления нескольких коллекций и даже нескольких документов в одной коллекции. В большинстве случаев это не проблема, поскольку ее можно обойти с помощью двухфазной фиксации или реструктуризация вашей схемы таким образом, чтобы обновления вносились в один документ. См. Этот вопрос: Базы данных документов: избыточные данные, ссылки и т. Д. (MongoDB конкретно)

person Sergey    schedule 01.09.2011

Прочтите о свойствах ACID, чтобы лучше понять.

Также в документации MongoDB вы можете найти вопрос и ответ..

MongoDB не поддерживает ACID. Читайте ниже, чтобы обсудить соответствие ACID.

  1. MongoDB Atomic только на уровне документа. Это не соответствует определению атомарного, которое мы знаем из систем реляционных баз данных, в частности, по ссылке выше. В этом смысле MongoDB не соответствует A от ACID.
  2. По умолчанию MongoDB Consitent. Однако вы можете читать со вторичных серверов в наборе реплик. В этом случае вы можете получить только конечную последовательность. Это полезно, если вы не против прочитать немного устаревшие данные.
  3. MongoDB не гарантирует Isolation (опять же согласно приведенному выше определению):
  1. Для систем с несколькими одновременными читателями и писателями MongoDB позволит клиентам читать результаты операции записи до того, как операция записи вернется.
  2. Если mongod завершается до фиксации журнала, даже если запись завершается успешно, запросы могут иметь данные чтения, которые не будут существовать после перезапуска mongod.

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

  1. Что касается Durability - вы можете настроить это поведение с помощью параметра write concern, хотя не уверен. Может кто знает получше.

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

person Ely    schedule 09.05.2015

Единственная причина, по которой atomic изменяет работу с одной коллекцией, заключается в том, что разработчики mongodb недавно заменили блокировку базы данных на блокировку записи для всей коллекции. Решив, что усиление параллелизма здесь стоило компромисса. По сути, mongodb - это файл с отображением в память: они делегировали управление пулом буферов подсистеме виртуальной машины. Поскольку он всегда в памяти, они могут обойтись без очень разрозненных блокировок: вы будете выполнять операции только в памяти, удерживая его, что будет очень быстро. Это значительно отличается от традиционной системы баз данных, которая иногда вынуждена выполнять ввод-вывод, удерживая блокировку страницы или строку.

person joeshmoe    schedule 16.04.2013
comment
не могли бы вы объяснить, почему это увеличивает параллелизм? Извините, если я упускаю очевидное. - person batbrat; 14.03.2014
comment
@batbrat: рассмотрим двух клиентов, которые пытаются одновременно писать в разные коллекции в одной базе данных. При блокировке базы данных одному из клиентов придется дождаться завершения работы другого, прежде чем может произойти запись. С блокировкой коллекции оба клиента могут писать одновременно. Вот что подразумевается под повышенным параллелизмом. Конечно, если оба клиента попытаются записать в одну и ту же коллекцию, придется подождать. - person jrullmann; 03.09.2014

«В MongoDB операция над отдельным документом является атомарной» - Это уже прошлое

В новой версии MongoDB 4.0 вы МОЖЕТЕ:

Однако для ситуаций, когда требуется атомарность для обновлений нескольких документов или согласованность между чтениями нескольких документов, MongoDB предоставляет возможность выполнять транзакции с несколькими документами для наборов реплик. Многодокументные транзакции можно использовать в нескольких операциях, коллекциях, базах данных и документах. Операции с несколькими документами предлагают принцип «все или ничего». Когда транзакция фиксируется, все изменения данных, внесенные в транзакцию, сохраняются. Если какая-либо операция в транзакции завершается неудачно, транзакция прерывается, и все изменения данных, внесенные в транзакцию, отменяются, не становясь видимыми. Пока транзакция не зафиксирована, никакие операции записи в транзакции не видны вне транзакции.

Хотя есть несколько ограничений для операций Как и What.

Проверьте Mongo Doc. https://docs.mongodb.com/master/core/transactions/

person Community    schedule 01.09.2018

Вы можете реализовать атомарные обновления с несколькими ключами (сериализуемые транзакции) на стороне клиента, если ваше хранилище поддерживает линеаризуемость по каждому ключу, а также сравнение и установку (что верно для MongoDB). Этот подход используется в перколяторе Google и в CockroachDB, но ничто не мешает вам использовать его с MongoDB.

Я создал пошаговую визуализацию таких сделки. Надеюсь, это поможет вам их понять.

Если вас устраивает уровень изоляции зафиксированного чтения, имеет смысл взглянуть на RAMP-транзакции. Питера Бейлиса. Они также могут быть реализованы для MongoDB на стороне клиента.

person rystsov    schedule 04.03.2016