Подтвердить что ты не робот

На какой уровень блокирует MongoDB запись? (или: что это означает "за соединение",

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Защелка считывателя-писателя

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

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

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

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

Обновление Atomic Document

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

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

Writer-Жадный

Еще несколько слов о том, чтобы быть писатель-жадным:

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

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

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

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

Относительно конкретных вопросов:

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

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

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

Ответ 3

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

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

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

Заметки о выпуске MongoDB 3.0

WiredTiger

Ответ 4

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

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

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

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

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

Уровень документа concurrency