Лучшие практики параллелизма в MongoDb - PullRequest
0 голосов
/ 19 июня 2020

Я новичок в MongoDb, я создаю приложение, которое управляет очень большим списком элементов (ресурсов), и для каждого ресурса приложение должно управлять своего рода бронированием.

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

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

Существуют ли альтернативные решения или передовые методы для повышения производительности и масштабируемости этого варианта использования? Возможное решение должно заключаться в том, чтобы иметь блокировку не на уровне коллекции, а на уровне документа (ресурс в моем примере), таким образом, пользователь, бронирующий ресурс, не блокирует другого пользователя, чтобы забронировать другой ресурс, даже если (также в этом case) Я не уверен в конечном результате, потому что команды записи не выполняются параллельно: я полагаю, что мне, вероятно, также понадобится кластер серверов для параллельного управления несколькими записями.

1 Ответ

0 голосов
/ 20 июня 2020

Вы абсолютно правы, вам определенно не следует блокировать всю коллекцию только для обновления одного документа.

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

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

Простое решение для эта проблема параллелизма решается сохранением номера версии (обычно _v) в каждом из ваших документов. И для каждого обновления вы увеличиваете номер версии. Затем каждый раз, когда вы выполняете чтение, изменение и обновление, вы убедитесь, что версия вашего прочитанного документа и версия этого документа в базе данных идентичны. Если номер версии отличается, обновление завершится неудачно, и вы можете просто повторить попытку.

Если вы используете node.js, то вы, вероятно, используете mongoose, а mongoose будет генерировать _v и выполнять параллелизм проверки за кадром. Таким образом, вам не нужно выполнять дополнительную работу для решения этой проблемы параллелизма.

...