MongoDB и наборы данных, которые не помещаются в оперативной памяти, независимо от того, как сильно вы пихаете

12

Это очень зависит от системы, но шансы почти наверняка пройдут мимо произвольного обрыва и мы попадем в реальную проблему. Мне любопытно, какие эмпирические правила существуют для хорошего соотношения ОЗУ и дискового пространства. Мы планируем следующий раунд систем, и нам нужно будет сделать выбор в отношении оперативной памяти, твердотельных накопителей и количества каждого нового узла.

Но теперь о некоторых деталях производительности!

Во время обычного рабочего процесса одного запуска проекта, MongoDB имеет очень высокий процент записей (70-80%). Как только наступает второй этап конвейера обработки, его чтение становится чрезвычайно высоким, так как требуется дедуплицировать записи, идентифицированные в первой половине обработки. Это рабочий процесс, для которого «держите ваш рабочий набор в ОЗУ», и мы строим это предположение.

Весь набор данных постоянно подвергается случайным запросам из источников, полученных от конечных пользователей; хотя частота нерегулярна, размер обычно довольно мал (группы по 10 документов). Так как это связано с пользователем, ответы должны быть ниже порога «скучно сейчас» в 3 секунды. Этот шаблон доступа с меньшей вероятностью будет находиться в кэше, поэтому весьма вероятно, что попадет на диск.

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

Размеры готовых документов варьируются в широких пределах, но средний размер составляет около 8К.

Большая часть обычной обработки проекта настоятельно рекомендует использовать реплики для распределения трафика чтения. Я читал в другом месте, что от 1:10 RAM-GB до HD-GB - хорошее эмпирическое правило для медленных дисков. Поскольку мы серьезно рассматриваем возможность использования гораздо более быстрых твердотельных накопителей, я хотел бы знать, существует ли подобное правило большого пальца для быстрых дисков.

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

sysadmin1138
источник
Сложный вопрос, хорошо заданный.
gWaldo
Похоже, что вы, вероятно, столкнетесь с проблемами блокировки записи, прежде чем сможете честно настроиться на IO. Если вы забиваете БД записями, вы, вероятно, будете удерживать блокировки записи достаточно долго, чтобы запросы зависали независимо от того, насколько быстрым является основной IO. Что-то вроде Fusion IO может немного уменьшить блокировку записи, но это просто выигрывает некоторое время, но это ненастоящее решение.
MrKurt
@MrKurt Часть того, что я пытаюсь выяснить, - это когда мне нужно осколок, в дополнение к тому, насколько я могу сделать отдельные узлы реплики. Моя предварительная спецификация включает SSD-карту на основе PCIe.
sysadmin1138
Ах, понял. С самого начала вы могли бы рассмотреть возможность шардинга, мы много делаем для одного сервера. Это позволяет обойти блокировку записи и эффективно масштабировать записи в общее количество ядер. Кроме того, позднее можно легко перемещать осколки между серверами.
MrKurt

Ответы:

5

Это будет куча маленьких очков. Однако, к сожалению, нет однозначного ответа на ваш вопрос.

MongoDB позволяет ядру ОС обрабатывать управление памятью. Помимо использования как можно большего объема оперативной памяти для решения проблемы, есть только несколько вещей, которые можно сделать, чтобы «активно управлять» вашим рабочим набором.

Единственное, что вы можете сделать, чтобы оптимизировать записи, - это сначала запросить эту запись (выполнить чтение), чтобы она оказалась в рабочей памяти. Это позволит избежать проблем с производительностью, связанных с глобальной блокировкой всего процесса (которая должна стать per-db в v2.2)

Не существует строгого правила для соотношения ОЗУ и SSD, но я думаю, что необработанные операции ввода-вывода в SSD должны позволить вам использовать гораздо более низкое соотношение. На вершине моей головы, 1: 3, вероятно, самый низкий уровень, с которым вы хотите идти. Но, учитывая более высокие затраты и меньшую пропускную способность, вам, вероятно, в любом случае придется снизить это соотношение.

Что касается «фаз записи и чтения», правильно ли я читаю, что после записи запись редко обновляется («перезаписывается»)? Если это так, возможно, стоит разместить два кластера; обычный кластер записи и оптимизированный для чтения кластер для «устаревших» данных, которые не были изменены в течение [периода X] . Я определенно включил бы ведомое чтение на этом кластере. (Лично я бы справился с этим, включив значение даты в объектные документы вашей базы данных.)

Если у вас есть возможность провести нагрузочное тестирование, прежде чем заходить в Prod, просто следите за этим. MongoDB была написана с предположением, что она будет часто развертываться в виртуальных машинах (их эталонные системы в EC2), поэтому не бойтесь выделять виртуальные машины.

gWaldo
источник
Во время обработки создается исходная заглушка документа, которая затем постоянно обновляется различными подэтапами в первой части обработки. Мы взвесили возможность выполнения некоторого заполнения вручную при первоначальном создании, чтобы уменьшить количество выполняемых нами расширений, но наш текущий процент блокировки записи к счастью низок.
sysadmin1138
Совет прочитать запись перед тем, как записать ее в ОЗУ, не очень хороший совет. Начиная с версии 2.0 (середина 2011 г.) MongoDB уступал, если данные, к которым осуществляется доступ, не находятся в ОЗУ, поэтому вы просто вызываете дополнительное чтение и дополнительное обратное обращение к серверу без веской причины, если вы делаете это, поскольку блокировка не в любом случае не будет задержан
Ася Камская
13

Это предназначено как дополнение к другим ответам, опубликованным здесь, которые обсуждают многие из соответствующих элементов, которые должны быть рассмотрены здесь. Тем не менее, есть еще один, часто упускаемый из виду, фактор, когда речь идет об эффективном использовании ОЗУ в системе с произвольным доступом - чтение вперед.

Вы можете проверить текущие настройки readahead (в Linux), запустив blockdev --report(обычно требуются права sudo / root). Это распечатает таблицу с одной строкой для каждого дискового устройства. Столбец RA содержит значение для чтения. Это значение представляет собой число секторов по 512 байт (если размер сектора не является значением по умолчанию - обратите внимание, что на момент написания этого поста даже диски большего размера рассматриваются ядром как 512-байтовые сектора), которые читаются на каждом доступ к диску.

Вы можете установить параметр readahead для данного дискового устройства, выполнив:

blockdev --setra <value> <device name>

При использовании программной RAID-системы убедитесь, что настроено чтение на каждом дисковом устройстве, а также на устройстве, которое соответствует RAID-контроллеру.

Почему это важно? Ну, readahead использует тот же ресурс, который пытается использовать MongoDB для оптимизации чтения для последовательного доступа - RAM. Когда вы выполняете последовательное чтение на вращающихся дисках (или на устройствах, которые в любом случае ведут себя как вращающиеся диски - EBS, я смотрю на вас), загрузка соседних данных в ОЗУ может значительно повысить производительность, сэкономить при поиске и установить высокую скорость чтения в правильная среда может дать вам впечатляющие результаты.

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

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

Для объяснения: вы хотите убедиться, что уровень чтения достаточно высок, чтобы вытащить полностью один документ и не возвращаться на диск. Давайте возьмем упомянутый вами средний размер 8 КБ - поскольку секторы на диске обычно составляют 512 байт, потребуется 16 обращений к диску, чтобы прочитать весь документ без чтения. Если бы у вас было время чтения 16 секторов или более, вы читали бы весь документ с одной только поездкой на диск.

На самом деле, поскольку индексные сегменты MongoDB имеют размер 8 КБ, вы никогда не захотите устанавливать значение readahead ниже 16, иначе для чтения в одном сегменте индекса потребуется 2 обращения к диску. Общая хорошая практика - начинать с текущих настроек, делить их пополам, затем переоценивать использование ОЗУ и ввода-вывода и двигаться дальше.

Адам С
источник
1
Ценная информация, которая наверняка пригодится, как только мы получим оборудование. Благодарность!
sysadmin1138
3

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

Используя правило 1:10, вы ищете около 128 ГБ ОЗУ на 1 ТБ дискового пространства; В то время как некоторые доступные SSD сегодня утверждают, что достигают> 60K IOPS, реальные цифры могут немного отличаться, а также от того, используете ли вы RAID с вашими SSD или нет, и если да, то карта RAID также чрезвычайно важна ,

На момент написания этой статьи переход от 128 ГБ оперативной памяти DDR3 ECC к 256 ГБ, кажется, составляет около 2000 долларов дополнительно на сервере Intel 1U, и это даст вам соотношение 1: 5 с 1 ТБ данных, что, на мой взгляд, было бы еще лучшее соотношение. Если вам нужно как можно быстрее завершить рабочую нагрузку, определенно поможет больше оперативной памяти, но так ли это срочно?

Вам также потребуется выполнить некоторую настройку файловой системы, что-то вроде «noatime, data = writeback, nobarrier» в ext4, и вам, возможно, придется внести некоторые изменения в настройки ядра, чтобы выжать из своей максимальной производительности система.

Если вы работаете с RAID, RAID-10 будет довольно хорошим выбором, а с правильным RAID-контроллером вы сможете значительно повысить производительность, но при этом вдвое сократить доступное пространство. Вы также можете заглянуть в RAID50, если хотите получить приличное повышение производительности, не уменьшая вдвое доступное пространство. Риск использования RAID состоит в том, что у вас больше нет доступа к TRIM на ваших дисках, а это означает, что вам время от времени нужно перемещать данные, разбивать RAID, TRIM диски и заново создавать RAID.

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

gekkz
источник