До какого уровня MongoDB блокирует записи? (или: что означает "за соединение"


в документации mongodb говорится:

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

означает ли это, что в ситуации, когда у меня есть, скажем, 3 соединения с mongodb:/ / localhost / тест из разных приложений, работающих в сети - только один может писать одновременно? Или это просто за соединение?

IOW: это за соединение, или вся /тестовая база данных заблокирована во время записи?

4 53

4 ответа:

это не за соединение, это за mongod. Другими словами, блокировка будет существовать во всех соединениях с test база данных на этом сервере.

это также блокировка чтения / записи, поэтому, если запись происходит, то чтение должно ждать, иначе как MongoDB может знать, что это последовательное чтение?

однако я должен упомянуть, что блокировки MongoDB очень отличаются от SQL / обычных транзакционных блокировок, которые вы получаете, и обычно блокировка будет удерживаться в течение примерно микросекунды между средние обновления.

блокировка MongoDB отличается

блокировка в MongoDB не работает, как блокировка в СУБД, поэтому немного объяснения в порядке. В более ранних версиях MongoDB была одна глобальная защелка чтения/записи. Начиная с MongoDB 2.2, для каждой базы данных существует защелка чтения/записи.

читатели-писатель защелка

защелка множественн-читатель, одиночн-писатель, и писатель-жадный. Это означает, что:

  • там может быть неограниченное количество одновременных читателей в базе данных
  • там может быть только один писатель в то время на любой коллекции в любой базе данных (подробнее об этом в бит)
  • писатели блокируют читателей
  • под "писателем-жадным" я имею в виду, что как только приходит запрос на запись, все читатели блокируются до завершения записи (подробнее об этом позже)

обратите внимание, что я называю это "защелка", а не "замком". Это потому, что она легкая, и в правильно сконструированная схема блокировки записи держится порядка десятка или около того микросекунд. Смотрите здесь для получения дополнительной информации о читателях-писатель блокировки.

в MongoDB вы можете запускать столько одновременных запросов, сколько хотите: пока соответствующие данные находятся в оперативной памяти, они все будут удовлетворены без блокировки конфликтов.

Атомарные Обновления Документов

Напомним, что в MongoDB уровень транзакции является одним документом. Все обновления для одного документа являются Атомный. MongoDB достигает этого, удерживая защелку записи только до тех пор, пока требуется обновить один документ в ОЗУ. Если есть какая-либо медленная операция (в частности, если документ или запись индекса должны быть выгружены с диска), то эта операция будет доходность фиксатор записи. Когда операция дает защелку, то следующая операция в очереди может продолжаться.

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

Писатель-Жадный

еще несколько слов о писателе-жадина:

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

  • все последующие читатели, нуждающиеся в этой защелке, заблокируют
  • этот писатель будет ждать, пока все текущие читатели не закончат
  • писатель получит защелку записи, сделает свою работу, а затем отпустите защелку записи
  • все читатели в очереди теперь продолжат

фактическое поведение является сложным, так как этот писатель-жадный поведение взаимодействует с уступкой способами, которые могут быть неочевидными. Напомним, что начиная с версии 2.2, есть отдельные защелка для каждой базы данных, поэтому запись в любую коллекцию в базе данных " A "будет приобретать отдельную защелку, чем запись в любую коллекцию в базе данных "B".

конкретные вопросы

что касается конкретных вопросов:

  • блокировки (фактически защелки) удерживаются ядром MongoDB только до тех пор, пока требуется обновить один документ
  • если у вас есть несколько подключений, поступающих в MongoDB, и каждый из них выполняет серию записей, защелка будет удерживаться на основе каждой базы данных только до тех пор, пока эта запись не будет завершена
  • несколько соединений, входящих в выполнение записи (обновление / вставка / удаление), будут чередоваться

хотя это звучит так, как будто это было бы большой проблемой производительности, на практике это не замедляет работу. С правильно разработанная схема и типичная рабочая нагрузка, MongoDB будет насыщать емкость ввода-вывода диска - даже для SSD-до того, как процент блокировки в любой базе данных превысит 50%.

самая высокая емкость кластера MongoDB, о которой я знаю, в настоящее время выполняет 2 миллиона записей в секунду.

Mongo 3.0 теперь поддерживает блокировку на уровне коллекции.

в дополнение к этому, теперь Монго создал API, который позволяет создать механизм хранения. Mongo 3.0 поставляется с 2 двигателями хранения:

  1. MMAPv1: механизм хранения по умолчанию и один использовать в предыдущих версиях. Поставляется с блокировкой на уровне коллекции.
  2. WiredTiger: новый механизм хранения, поставляется с блокировкой и сжатием на уровне документа. (Доступно только для 64-разрядная версия)

MongoDB 3.0 примечания к выпуску

WiredTiger

Я знаю, что вопрос довольно старый, но все же некоторые люди путаются....

начиная с MongoDB 3.0, механизм хранения WiredTiger (который использует параллелизм на уровне документа) доступен в 64-разрядных сборках.

WiredTiger использует управление параллелизмом на уровне документа для операций записи. В результате несколько клиентов могут изменять различные документы коллекции одновременно.

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

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

Параллелизм Уровня Документа