2013-11-25 3 views
0

Предположим, что у меня есть две коллекции A и B. Между прочим, одна из них (коллекция A) имеет массив, ячейки которого содержат поддокументы с несколькими ключами.

У меня также есть сценарий, который будет проходить через очередь (внешний по MongoDB), вставить его элементы в коллекцию B и вытолкнуть любую соответствующую информацию из этих элементов в поддокументы в массиве в коллекции A, используя $push. По мере выполнения сценария размер документов в коллекции A значительно возрастает.

Проблема заключается в том, что всякий раз, когда документ не соответствует его выделенному размеру, MongoDB будет перемещать его внутренне, но он не освободит место, которое он занимал ранее --- новые документы MongoDB не будут использоваться это пробел, если только я не запустил команду compact или repairDatabase.

В моем случае скрипт, похоже, быстро окупится через мое дисковое пространство. Он вставляет несколько элементов в коллекцию B, затем пытается вставить в документ в коллекции A, и (я предполагаю) переносит указанный документ без повторного использования его старого места. Возможно, это случается не каждый раз, с дополнением, но когда эти документы имеют размер около 10 МБ, это означает, что каждый раз, когда он делает, это происходит через значительный фрагмент БД, хотя фактический размер данных остается небольшим. Процесс забирает мою (довольно маленькую, по общему признанию) БД за считанные минуты.

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

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

ответ

0

Рекомендация Sammaye была верна, но мне нужно было сделать еще больше, чтобы понять причину этой проблемы. Вот что я нашел.

Итак, во-первых, действительно ли MongoDB использует пространство так, как я описал выше?

Да, но это не так, как предполагалось. См. Ошибку SERVER-8078 и ее (неочевидный) дубликат, SERVER-2958. Частые операции $push заставляют MongoDB перемещать документы вокруг, а их старые пятна (еще!) Не используются повторно без команды compact или repairDatabase.

Во-вторых, я приближаюсь к этому неправильно? Возможно, есть параметр, который я могу установить, чтобы заставить MongoDB использовать это пространство автоматически; если есть, целесообразно ли его использовать?

Для некоторых использований $push, то usePowerOf2Size вариант изначально потребляет больше памяти, но стабилизируется лучше (см обсуждение SERVER-8078). Это может плохо работать с массивами, которые постоянно растут, что плохой идеей, поскольку размеры документов ограничены.

И, в-третьих, существуют ли другие, более подходящие, проектные подходы, которые мне не хватает?

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

+1

Они повторно используются, они просто должны иметь документ, который подходит для этой позиции, и при вставке нового документа mongodb будет искать только первые 100 записей фрилансеров. – Sammaye

1

Большинство вопросов, которые вы задали, должны были уже знать (поиск в Google привел бы 100 ссылок, включая критические записи в блоге по этому вопросу), попытавшись использовать MongoDB в таком случае, однако эта презентация должна отвечать как 90% из ваших вопросов: http://www.mongodb.com/presentations/storage-engine-internals

Что касается решения проблемы с помощью настроек и т. Д., Здесь действительно невозможно, мощность 2-х размеров не поможет массиву, который растет таким образом. Так что ответьте:

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

Я бы сказал, нет.

И, в-третьих, существуют ли другие, более подходящие, проектные подходы, которые мне не хватает?

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

+0

Спасибо, Sammaye. Для других, сталкивающихся с одной и той же проблемой: связанная выше 38-минутная презентация очень информативна, но она вообще не затрагивает эту проблему. Кроме того, большинство сотен ссылок, которые вы получаете с поиском Google, также не имеют отношения к делу. См. Мой ответ для ссылок на соответствующие билеты в JIRA MongoDB. –

Смежные вопросы