MongoDB и наборы данных, которые не помещаются в оперативной памяти, независимо от того, как сильно вы пихаете
Это сильно зависит от системы, но шансы почти наверняка пройдут мимо произвольного обрыва и мы попадем в реальную проблему. Мне любопытно, какие практические правила существуют для хорошего соотношения RAM и дискового пространства. Мы планируем следующий раунд систем, и нам нужно будет сделать выбор в отношении оперативной памяти, твердотельных накопителей и количества каждого нового узла.
Но теперь о некоторых деталях производительности!
Во время нормального рабочего процесса одного запуска проекта, MongoDB имеет очень высокий процент записей (70-80%). Как только наступает второй этап конвейера обработки, его чтение становится чрезвычайно высоким, так как требуется дедуплицировать записи, идентифицированные в первой половине обработки. Это рабочий процесс, для которого "держите ваш рабочий набор в оперативной памяти", и мы строим это предположение.
Весь набор данных постоянно подвергается случайным запросам из источников, полученных от конечных пользователей; хотя частота нерегулярна, размер обычно довольно маленький (группы из 10 документов). Так как это связано с пользователем, ответы должны быть ниже порога "скучно сейчас" 3 секунды. Этот шаблон доступа с меньшей вероятностью будет находиться в кэше, поэтому весьма вероятно, что попадет на диск.
Вторичный рабочий процесс обработки - это высокая скорость чтения предыдущих прогонов обработки, которые могут быть днями, неделями или даже месяцами, и он запускается нечасто, но все же должен быть быстрым. До 100% документов в предыдущем прогоне обработки будут доступны. Я подозреваю, что никакое потепление кеша не может помочь с этим.
Размеры готовых документов варьируются в широких пределах, но средний размер составляет около 8К.
Большая часть обычной обработки проекта настоятельно рекомендует использовать реплики для распределения трафика чтения. Я читал в другом месте, что от 1:10 RAM-GB до HD-GB - хорошее эмпирическое правило для медленных дисков. Поскольку мы серьезно рассматриваем возможность использования гораздо более быстрых твердотельных накопителей, я хотел бы знать, существует ли подобное правило большого пальца для быстрых дисков.
Я знаю, что мы используем Mongo таким образом, чтобы кэшировать все не получалось, поэтому я ищу способы спроектировать систему, способную выдержать такое использование. Весь набор данных, скорее всего, будет составлять большую часть туберкулеза в течение полугода и будет продолжать расти.
3 ответа
Это будет куча маленьких очков. К сожалению, нет единого ответа на ваш вопрос.
MongoDB позволяет ядру ОС обрабатывать управление памятью. Помимо использования как можно большего объема оперативной памяти для решения проблемы, есть только несколько вещей, которые можно сделать, чтобы "активно управлять" вашим рабочим набором.
Единственное, что вы можете сделать, чтобы оптимизировать записи, - это сначала запросить эту запись (выполнить чтение), чтобы она оказалась в рабочей памяти. Это позволит избежать проблем с производительностью, связанных с глобальной блокировкой всего процесса (которая должна стать per-db в v2.2)
Не существует строгого правила для соотношения ОЗУ и SSD, но я думаю, что необработанные операции ввода-вывода в SSD должны позволить вам использовать намного более низкое соотношение. Сверху в голове, 1:3, вероятно, самый низкий уровень, с которым вы хотите идти. Но, учитывая более высокие затраты и меньшую пропускную способность, вам, вероятно, придется все равно поддерживать это соотношение.
Что касается "фаз записи и чтения", правильно ли я читаю, что после записи запись редко обновляется ("перезаписывается")? Если это так, возможно, стоит разместить два кластера; обычный кластер записи и оптимизированный для чтения кластер для "устаревших" данных, которые не были изменены в течение [периода X]. Я определенно включил бы ведомое чтение на этом кластере. (Лично я бы справился с этим, включив значение даты в объектные документы вашей базы данных.)
Если у вас есть возможность провести нагрузочное тестирование, прежде чем заходить в Prod, просто следите за этим. MongoDB была написана с предположением, что она будет часто развертываться в виртуальных машинах (их эталонные системы в EC2), поэтому не бойтесь выделять виртуальные машины.
Это предназначено как дополнение к другим ответам, опубликованным здесь, которые обсуждают многие из соответствующих элементов, которые должны быть рассмотрены здесь. Тем не менее, есть еще один, часто упускаемый из виду, фактор, когда речь идет об эффективном использовании ОЗУ в системе с произвольным доступом - чтение вперед.
Вы можете проверить текущие настройки для чтения (в 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:10, вы ищете около 128 ГБ ОЗУ для 1 ТБ дискового пространства; В то время как некоторые доступные SSD сегодня заявляют о том, что они достигают>60K IOPS, реальные цифры могут немного отличаться, а также от того, используете ли вы RAID с вашими SSD или нет, и если да, то карта RAID также чрезвычайно важна.,
На момент написания этой статьи переход от 128 ГБ оперативной памяти DDR3 ECC к 256 ГБ, кажется, на 1U-сервере Intel составляет около 2000 долларов, и это даст вам соотношение 1:5 с 1 ТБ данных, что, я думаю, было бы еще лучшее соотношение. Если вам нужно как можно быстрее завершить рабочую нагрузку, определенно поможет больше оперативной памяти, но так ли это срочно?
Вам также потребуется выполнить некоторую настройку файловой системы, что-то вроде "noatime,data=writeback,nobarrier" в ext4, и вам, возможно, потребуется внести некоторые изменения в настройки ядра, чтобы выжать из своей максимальной производительности система.
Если вы работаете с RAID, RAID-10 будет довольно хорошим выбором, а с правильным RAID-контроллером вы сможете значительно повысить производительность, но при этом вдвое сократить доступное пространство. Вы также можете заглянуть в RAID50, если хотите получить приличное повышение производительности, не уменьшая вдвое доступное пространство. Риск запуска RAID заключается в том, что у вас больше нет доступа к TRIM на ваших дисках, а это означает, что время от времени вам нужно перемещать данные, разбивать RAID, TRIM диски и воссоздавать RAID.
В конечном счете, вам нужно решить, какую сложность вы хотите, сколько денег вы хотите потратить и как быстро вы хотите, чтобы ваша рабочая нагрузка обрабатывалась. Я также оценил бы, является ли MongoDB идеальной базой данных для использования, поскольку вы все равно можете использовать Mongo для запросов конечных пользователей, которые требуют быстрых ответов, но использовать что-то другое для обработки ваших данных, которые не должны быть готовы через несколько секунд. и это также может позволить вам с большей легкостью распределить рабочую нагрузку между несколькими компьютерами.