До какого уровня MongoDB блокирует записи? (или: что означает "за соединение"
в документации mongodb говорится:
начиная с версии 2.2, MongoDB реализует блокировки на основе каждой базы данных для большинства операций чтения и записи. Некоторые глобальные операции, обычно кратковременные операции с несколькими базами данных, по-прежнему требуют глобальной блокировки "экземпляра". До версии 2.2 существует только одна "глобальная" блокировка для каждого экземпляра mongod.
означает ли это, что в ситуации, когда у меня есть, скажем, 3 соединения с mongodb:/ / localhost / тест из разных приложений, работающих в сети - только один может писать одновременно? Или это просто за соединение?
IOW: это за соединение, или вся /тестовая база данных заблокирована во время записи?
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 двигателями хранения:
- MMAPv1: механизм хранения по умолчанию и один использовать в предыдущих версиях. Поставляется с блокировкой на уровне коллекции.
- WiredTiger: новый механизм хранения, поставляется с блокировкой и сжатием на уровне документа. (Доступно только для 64-разрядная версия)
Я знаю, что вопрос довольно старый, но все же некоторые люди путаются....
начиная с MongoDB 3.0, механизм хранения WiredTiger (который использует параллелизм на уровне документа) доступен в 64-разрядных сборках.
WiredTiger использует управление параллелизмом на уровне документа для операций записи. В результате несколько клиентов могут изменять различные документы коллекции одновременно.
для большинства чтения и записи операции, WiredTiger использует оптимистичный контроль параллелизма. WiredTiger использует только блокировки намерений на глобальном уровне, уровне базы данных и уровне коллекции. Когда механизм хранения обнаруживает конфликты между двумя операциями, возникает конфликт записи, в результате чего MongoDB прозрачно повторяет эту операцию.
некоторые глобальные операции, обычно кратковременные операции с несколькими базами данных, по-прежнему требуют глобальной блокировки "всего экземпляра". Некоторые другие операции, такие как удаление коллекция, по-прежнему требуют эксклюзивной блокировки базы данных.