Масштабируемость MongoDB - производительность запросов, обрабатывающих один кусок? - PullRequest
0 голосов
/ 03 октября 2011

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

Некоторые подробности:

Для моего простого теста я использовал две машины для проверки и пробовал запросы к подобным коллекциям с 2 миллионами строк и 7 миллионами строк.Это, очевидно, очень маленькие коллекции, которые даже не требуют сегментирования, но я был удивлен, увидев существенное последовательное замедление запросов, затрагивающих только один фрагмент.Запросы включали ключ сегментирования, предназначались для наборов результатов в диапазоне от 10 до 100000 строк, и я измерил общее время, необходимое для прокрутки всех наборов результатов.И еще одно: поскольку моему приложению на самом деле потребуется гораздо больше данных, чем может поместиться в ОЗУ, все запросы были рассчитаны на основе холодного кэша.

Есть идеи, почему это так?Кто-нибудь еще наблюдал такие же или противоречивые результаты?


Дополнительные подробности (подсказано Тео):

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

Команда db.printShardingStatus () показывает, сколько существует чанков, а также точные значения ключей, используемые для разделения диапазонов чанков.Средний чанк содержит более 100 000 строк для этого набора данных, и проверка разбиений значения ключа подтверждает, что тестовые запросы попадают в один чанк.

Для целей этого теста я измерял только показания.Не было никаких вставок или обновлений.


Обновление:

После некоторого дополнительного исследования, я считаю, я определил причину замедления: чанки MongoDB являются чисто логическими, и данные в них НЕ находятся физически вместе (источник: "Масштабирование MongoDB" Кристины Ходоров).Это в отличие от разбиения в традиционных базах данных, таких как Oracle и MySQL.Это кажется существенным ограничением, так как сегментирование будет масштабироваться горизонтально с добавлением фрагментов / машин, но не так хорошо в вертикальном измерении, поскольку данные добавляются в коллекцию с фиксированным количеством фрагментов.

Если я правильно понимаю, если у меня есть 1 коллекция с осколками миллиарда строк на 10 осколках / машинах, даже запрос, который затрагивает только один осколок / машину, все еще запрашивает большую коллекцию из 100 миллионов строк.Если значения для ключа шардинга случайно расположены на диске, то это может быть нормально.Но если нет, и я выбираю более нескольких строк (например, 1000 с), то это, вероятно, приведет к множеству проблем ввода-вывода.

Итак, мой новый вопрос: почему бы не организовать чанки в MongoDB?физически для обеспечения вертикальной и горизонтальной масштабируемости?

Ответы [ 2 ]

1 голос
/ 12 февраля 2014

Отказ от ответственности: я работаю в Tokutek

Итак, мой новый вопрос: почему бы не организовать физически чанки в MongoDB для обеспечения вертикальной и горизонтальной масштабируемости?

Это именно то, что делается в TokuMX , заменяющем сервере для MongoDB. TokuMX использует индексы Fractal Tree с высокой пропускной способностью записи и сжатием, поэтому вместо хранения данных в куче данные кластеризуются с индексом . По умолчанию ключ shard кластеризован, поэтому он выполняет именно то, что вы предлагаете, физически организует фрагменты, обеспечивая порядок всех документов с помощью ключа shard на диске. Это делает запросы диапазона к ключу шарда быстрыми, как и для любого кластерного индекса.

1 голос
/ 04 октября 2011

Что заставляет вас говорить, что запросы касались только одного фрагмента? Если результат достиг 100 000 строк, это звучит маловероятно. Максимальный размер фрагмента составляет 64 Мб, и если ваши объекты не будут крошечными, многие из них не подойдут. Монго, скорее всего, разделил ваши куски и раздал их.

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

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

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

Запустите mongostat, пока вы выполняете свои тесты, он может многое вам сказать (запустите mongostat --discover | grep -v SEC, чтобы увидеть метрики для всех мастеров осколков, не забудьте включить --port, если ваш mongos не работает на 27017).


Обращаясь к вопросам в вашем обновлении: было бы здорово, если бы Монго физически держал куски вместе, но это не так. Одна из причин в том, что шардинг - это слой поверх mongod, и mongod не полностью осознает, что это шард. Это серверы конфигурации и процессы mongos, которые знают о ключах шарда и какие куски существуют. Таким образом, в текущей архитектуре mongod даже не имеет информации, которая потребовалась бы для хранения фрагментов на диске. Проблема еще глубже: формат диска Монго не очень продвинутый. Он по-прежнему (начиная с версии 2.0) не имеет оперативного сжатия (хотя сжатие улучшилось в версии 2.0), он не может сжимать фрагментированную базу данных и по-прежнему обслуживать запросы. К сожалению, Монго предстоит пройти долгий путь, прежде чем он способен на то, что вы предлагаете.

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

...