Назад | Перейти на главную страницу

MongoDB: производительность случайного и последовательного чтения

У меня есть монгодб с одним экземпляром с коллекцией из 3 полей: _id, block_id, payload.

В коллекции есть вторичный индекс:

{ "v" : 1, "key" : { "block_id" : 1, "_id" : -1 }, 
  "ns" : "testdb.testdev", "name" : "_block_id_id" }

Я делаю много запросов, например:

query: { query: { block_id: 868413 }, orderby: { _id: -1 } } ntoreturn:1 nscanned:1 nreturned:1 reslen:4166 163ms

Во время них нет других запросов. Когда я читаю последовательно по block_id, это в 10 раз быстрее, чем когда я запрашиваю со случайным block_id. У меня низкое использование процессора, низкое использование хранилища. Коллекция в 2-3 раза больше объема памяти.

Что может быть здесь узким местом?

Здесь нужно уточнить пару вещей:

  1. Вы увидите только медленные запросы, регистрируемые по умолчанию (> 100 мс), у вас могут быть миллионы запросов, выполняемых ниже этого порога, которые никогда не будут зарегистрированы
  2. Способ выяснить, в чем причина медленных операций, - это посмотреть статистику, когда медленные операции регистрируются.
  3. Вам следует повторно запустить запросы с .explain () чтобы убедиться, что они используют индекс, который, по вашему мнению, они

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

Другой вариант - MMS (Служба мониторинга MongoDB) - это бесплатно и позволяет отображать всю соответствующую статистику с течением времени, чтобы вы могли определить, какие скачки / падения, когда вы видите медлительность. Я рекомендую установить munin-node, если вы пойдете по этому маршруту (см. Документы MMS), потому что он даст вам представление о статистике ввода-вывода, а также статистике MongoDB.

Обычно вы будете искать одно из следующего:

  1. Ошибки страницы - если это всплеск, ваши запросы вызывают подкачку на диск - это на порядок медленнее, чем операции в памяти, и его необходимо минимизировать.
  2. Резидентная память - тесно связана с ошибками страниц, это ваш рабочий набор в памяти. Вы упоминаете, что ваш набор данных в 2–3 раза превышает размер ОЗУ, но включили ли вы индексы в эту оценку (см. db.collection.stats () команда)

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

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

  1. Удаление ненужных индексов, которые могут занимать место
  2. Посмотрите на использование покрытый индекс запросы, если возможно (не нужно листать данные, только индекс)
  3. Проверьте настройки опережения чтения - длинная и сложная тема - см. Вот и Вот для получения дополнительной информации (и дополнительной информации в целом)