Резервные документы в сегментированном mongodb

У меня есть разделенная коллекция документов в mongodb и несколько серверов приложений, обращающихся к ней.

Каждое приложение вносит новые документы и в конечном итоге также должно удалить некоторые из них.

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

Моя идея такова:

unique = makeUniqueValue()
docs = []

for (i = 0;i < 10;i++) {
    r = findAndModify( claim: false, $set: { claim: unique });
    if (r.value) docs.push(r);
}

if (docs.length < 10)
    "release all docs by updating (claim: false) and try again in some time"

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

Каково известное и проверенное решение этой проблемы?

Гарантируют ли «обновление» и «findAndModify», что обновленный документ соответствует запросу до обновления?

Или другое приложение может «украсть» его между сопоставлением и обновлением, и, таким образом, оба приложения думают, что они заявили права на документ?


person Thomas Jensen    schedule 01.02.2014    source источник


Ответы (1)


После запуска обновления этого документа оно гарантирует, что запрос соответствует документу и является последней версией.

Никакая другая программа не должна иметь возможности воровать для каждого документа.

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

Это означает, что findAndModify не сможет что-то найти, пока операция записи может выполняться. Таким образом, он не может найти документ, который должен быть обновлен, как заявлено, например, в другом потоке/приложении.

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

При фактическом обновлении это не имеет значения, поскольку вы знаете, что эти документы являются документами, которые вам нужно обновить, однако такие операторы, как $set и т. д., выполняются последовательно для одного документа, поскольку сами такие операции обновления также не могут принимать частичное состояние документа, они либо принимают claim false или ничего. Обновление также будет выбирать строки непосредственно из файлов данных, а не из записанного статического набора результатов.

Если бы вы обновлялись с помощью _id или другого статического фрагмента данных, все было бы иначе.

person Sammaye    schedule 01.02.2014
comment
Спасибо! Итак, чтобы быть ясным; ни update (w/wo multi), ни findAndModify никогда не смогут обновить документ, если он не соответствует запросу? Следовательно, моя единственная задача — убедиться, что приложения не слишком сильно борются за фактическое резервирование документов, если доступно десять или более документов (я рассматриваю какую-то схему очередей). - person Thomas Jensen; 01.02.2014
comment
@ThomasJensen Я не понимаю, как все существующие системы должны это остановить, если есть шанс, то это определенно ошибка. - person Sammaye; 01.02.2014