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

MongoDB и наборы данных, которые не помещаются в ОЗУ, как бы сильно вы ни толкали

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

А теперь подробнее о производительности!

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

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

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

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

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

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

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

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

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

blockdev --setra <value> <device name>

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

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

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

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

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

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

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

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

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

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

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

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

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

Используя эмпирическое правило 1:10, вы получаете примерно 128 ГБ ОЗУ на 1 ТБ дискового хранилища; В то время как некоторые доступные твердотельные накопители сегодня заявляют, что достигают> 60 тыс. Операций ввода-вывода в секунду, реальные цифры могут немного отличаться, а также от того, используете ли вы RAID со своими твердотельными накопителями или нет, и если да, то карта 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 для запросов конечных пользователей, требующих быстрых ответов, но использовать что-то еще для обработки ваших данных, которые не должны быть готовы за несколько секунд. , и это также может позволить вам более легко распределить рабочую нагрузку между несколькими машинами.