Меню

Настройки postgresql под ssd



Настройка Postgres для быстрого SSD

Взял у Селектела в тест сервак для тестирования хваленого SSD Intel P4800X.

Написал тест, который в многопотоке делает INSERTы в PostgreSQL по одному (не batch). Получил прирост производительности относительно HDD RAID10 примерно в два раза. Тесты чтения будут позже.

Как выжать все соки из SSD с помощью Postgres? iostat -dx показывает утилизацию SSD

20%. Предполагаю что проблема с конфигом PostgreSQL,

на либрусеке вроде есть

Файловым кэшом заведует ОС, так что конфиг PostgreSQL вряд кардинально ситуацию поменяет.

вообще-то СУБД давно пишут с O_DIRECT.

Ээээ, в случае PostgreSQL это не так, так как это всего навсего СУБД и его целью не является полная замена ОС. Возможно, я отстал от жизни, но ещё пару-тройку лет по-моему было именно так.

как минимум WALпишется с O_DIRECT/fsync. иначе — это не СУБД а решето с вероятностным сохранением данных.

что в логах? в один поток инсертишь?

Я не понял ремарки. O_DIRECT/fsync делается по окончанию транзакции для записи изменений и единственный способ ускорить это «в конфиге» это отключить её, что смысла действительно не имеет.

процессор насколько грузится ?
упирается ядром ?

процессор насколько грузится ?
упирается ядром ?

Ни одним ядром не упирается в 100%.

что в логах? в один поток инсертишь?

Пробовал 100, 200, 500, 2000 потоков. Ситуация не сильно отличается. При 2000 потоках нагрузка на диск уменьшается. Ни один поток не упирается в 100%, cpu idle от 20-30%.

С помощью утилиты fio удалось в random 4k утилизировать диск на 100%. Позже попробую провести fio поверх ФС.

ай ай спасибо добрый человек

Да ничего ты из постгреса не вытащишь, проходили уже. Он сам по себе такой, поломанный при проектировании, не может утилизировать высокопроизводительный диск на 100%.

Чтобы постгрес получал все преимущества быстрых дисков его надо перепроектировать с нуля.

Учитывая большинство рекомендаций по использованию SSD, оптимизация будет сведена к созданию пользователя с правами read-only и работой только из-под него.

А как, если не секрет? Статья на хабре будет? 😉

А как, если не секрет? Статья на хабре будет? 😉

Запустил fio с конфигом:

Только чтение или только запись также утилизируют накопитель на 100%. Получается около 440kIOPS, что соответствует заявлению производителя. Если сменить libaio на что-то другое (sync, psync, mmap), производительность падает в разы, при этом утилизация близка к 100%.

Также удалось утилизировать диск на 90% в тесте PostgreSQL с двумя чтениями из двух таблиц и записью во вторую таблицу.

Была идея написать статью на хабре, но материала для мало. Все тезисы уместились в эту тему на форуме.

Источник

Настройки PostgreSQL для работы с 1С:Предприятием. Часть 2


Общие положения

В документе описывается настройка PostgreSQL версий 9.2-9.4 на максимальную производительность для платформы 1С. Предполагается, что сервер, используемый для PostgreSQL является достаточно производительным и имеет приблизительно:

  • 4 — 512 Gb RAM
  • 2 — 256 CPU cores
  • RAID 0-1 или SSD

Данный документ подразумевает хотя бы поверхностное знакомство с архитектурой PgSQL. Приведенные в документе параметры являются приблизительными и стартовыми для тонкой настройки.

Настройки сервера для PostgreSQL


  • Рекомендуется отключать HyperThreading. Для программ типа систем управления базами данных от него скорее вред чем польза.
  • Также рекомендуется отключать Energy Saving, поскольку в противном случае могут непредсказуемо вырастать задержки ответов БД.
  • Надо запретить своппинг разделяемой памяти SYSV/posix (FreeBSD: kern.ipc.shm_use_phys=1)

Обозначения


  • RAM — объем оперативной памяти сервера. Если сервер используется не только для PostgreSQL, то надо уменьшить эту величину на объем занятой памяти.
  • NCores — суммарное число ядер на всех CPU сервера
  • max_connections — максимальное число коннектов (или сессий) к PgSQL. Задается в конфигурационном файле.
  • WAL — Write Ahead Log, опережающий лог действий с таблицами и индексами. Основная задача — целостность и отказоустойчивость базы данных при одновременном росте производительности.
  • checkpoint — точка восстановления база данных. Все WAL данные, записанные до checkpoint становятся не нужны.
  • X..Y — диапазон значений от X до Y включительно

Параметры производительности

Количество памяти, выделенной PgSQL для совместного кеша страниц. Эта память разделяется между всеми процессами PgSQL.

Максимальное количество страниц для временных таблиц. Т.е. это верхний лимит размера временных таблиц в каждой сессии.

work_mem = RAM/32..64 или 32MB..128MB

Лимит памяти для обработки одного запроса. Эта память индивидуальна для каждой сессии. Теоретически, максимально потребная память равна max_connections * work_mem, на практике такого не встречается потому что большая часть сессий почти всегда висит в ожидании. Это рекомендательное значение используется оптимайзером: он пытается предугадать размер необходимой памяти для запроса, и, если это значение больше work_mem, то указывает экзекьютору сразу создать временную таблицу. work_mem не является в полном смысле лимитом: оптимайзер может и промахнуться, и запрос займёт больше памяти, возможно в разы. Это значение можно уменьшать, следя за количеством создаваемых временных файлов:

Лимит памяти для обслуживающих задач, например вакуум, автовакуум или создания индексов.

Оценка размера кеша файловой системы. Увеличение параметра увеличивает склонность системы выбирать IndexScan планы. И это хорошо.

Оценочное значение одновременных запросов к дисковой системе, которые она может обслужить единовременно. Для одиночного диска = 1, для RAID — 2 или больше.

Стоимость чтения рандомной страницы (по-умолчанию 4). Чем меньше seek time дисковой системы тем меньше (но > 1.0) должен быть этот параметр. Излишне большое значение параметра увеличивает склонность PgSQL к выбору планов с сканированием всей таблицы (PgSQL считает, что дешевле последовательно читать всю таблицу, чем рандомно индекс). И это плохо.

Включение автовакуума. Не выключайте его!

Количество процессов автовакуума. Общее правило — чем больше write-запросов, тем больше процессов. На read-only базе данных достаточно одного процесса.

Время сна процесса автовакуума. Слишком большая величина будет приводить к тому, что таблицы не будут успевать вакуумиться и, как следствие, вырастет bloat и размер таблиц и индексов. Малая величина приведет к бесполезному нагреванию.

Время сна между циклами записи на диск фонового процесса записи. Данный процесс ответственен за синхронизацию страниц, расположенных в shared_buffers с диском. Слишком большое значение этого параметра приведет к возрастанию нагрузки на checkpoint процесс и процессы, обслуживающие сессии (backend). Малое значение приведет к полной загрузке одного из ядер.

Параметры, управляющие интенсивностью записи фонового процесса записи. За один цикл bgwriter записывает не больше, чем было записано в прошлый цикл, умноженное на bgwriter_lru_multiplier, но не больше чемbgwriter_lru_maxpages.

Выключение синхронизации с диском в момент коммита. Создает риск потери последних нескольких транзакций (в течении 0.5-1 секунды), но гарантирует целостность базы данных, в цепочке коммитов гарантированно отсутствуют пропуски. Но значительно увеличивает производительность.

Максимальное количество сегментов WAL между checkpoint. Слишком частые checkpoint приводят к значительной нагрузке на дисковую подсистему по записи. Каждый сегмент имеет размер 16MB.

Степень «размазывания» checkpoint’a. Скорость записи во время checkpoint’а регулируется так, что бы время checkpoint’а было равно времени, прошедшему с прошлого, умноженному на checkpoint_completion_target.

Минимальное и максимальный объем WAL файлов. Аналогично checkpoint_segments.

Выключение шифрования. Для защищенных ЦОД-ов шифрование бессмысленно, но приводит к увеличению загрузки CPU.

Выключение параметра приводит к росту производительности, но появляется значительный риск потери всех данных при внезапном выключении питания. Внимание: если RAID имеет кеш и находиться в режиме write-back, проверьте наличие и функциональность батарейки кеша RAID контроллера! Иначе данные записанные в кеш RAID могут быть потеряны при выключении питания, и, как следствие, PgSQL не гарантирует целостность данных.

Групповой коммит нескольких транзакций. Имеет смысл включать, если темп транзакций превосходит 1000 TPS. Иначе эффекта не имеет.

Дисковое пространство для временных таблиц/индексов. Помещение временных таблиц/индексов на отдельные диски может увеличить производительность. Предварительно надо создать tablespace командой CREATE TABLESPACE. Если характеристики дисков отличаются от основных дисков, то следует в команде указать соответствующий random_page_cost. См. статью.

Отключение контроля разрешения уровня записи.

Максимальное количество открытых файлов на один процесс PostreSQL. Один файл это как минимум либо индекс либо таблица, но таблица/может состоять из нескольких файлов. Если PostgreSQL упирается в этот лимит, он начинает открывать/закрывать файлы, что может сказываться на производительности. Диагностировать проблему под Linux можно с помощью команды lsof.

Параметры для платформы 1С:Предприятия

Разрешить использовать символ \ для экранирования.

Не выдавать предупреждение о использовании символа \ для экранирования.

Максимальное число блокировок индексов/таблиц в одной транзакции.

Количество одновременных коннектов/сессий.

Параметры для PgBadger

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

Примечание. Здесь пока никак не рассматриваются вопросы ротации логов и использования самого PgBadger’a.

Параметры дополнительных модулей


plantuner

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

online_analyze

Автоматически анализировать временные таблицы при их изменении. Фоновый analyze может заметно отставать, и, как результат, планер ошибается.

Отключение излишней болтливости автоматического analyze.

Источник

Про износ SSD на реальных примерах

Год назад мы добавили в наш агент сбор метрик из S.M.A.R.T. атрибутов дисков на серверах клиентов. В тот момент мы не стали добавлять их в интерфейс и показывать клиентам. Дело в том, что метрики мы снимаем не через через smartctl, а дергаем ioctl прямо из кода, чтобы этот функционал работал без установки smartmontools на серверы клиентов.
Агент снимает не все доступные атрибуты, а только самые значимые на наш взгляд и наименее вендор-специфичные (иначе пришлось бы поддерживать базу дисков, аналогичную smartmontools).
Сейчас наконец дошли руки до того, чтобы проверить, что мы там наснимали. А начать было решено с атрибута «media wearout indicator», который показывает в процентах оставшийся ресурс записи SSD. Под катом несколько историй в картинках о том, как расходуется этот ресурс в реальной жизни на серверах.

Существуют ли убитые SSD?

Бытует мнение, что новые более производительные ssd выходят чаще, чем старые успевают убиться. Поэтому первым делом было интересно посмотреть на самый убитый с точки зрения ресурса записи диск. Минимальное значение по всем ssd всех клиентов — 1%.

Мы сразу же написали клиенту об этом, это оказался дедик в hetzner. Поддержка хостера сразу же заменила ssd:

Очень интересно было бы посмотреть, как выглядит с точки зрения операционной системы ситуация, когда ssd перестает обслуживать запись (мы сейчас ищем возможность провести умышленное издевательство над ssd, чтобы посмотреть на метрики этого сценария:)

Как быстро убиваются SSD?

Так как сбор метрик мы начали год назад, а метрики мы не удаляем, есть возможность посмотреть на эту метрику во времени. К сожалению сервер с наибольшей скоростью расхода подключен к okmeter только 2 месяца назад.

На этом графике мы видим, как за 2 месяца сожгли 8% ресурса записи. То есть при таком же профиле записи, этих ssd хватит на 100/(8/2) = 25 месяцев. Много это или мало не знаю, но давайте посмотрим, что за нагрузка там такая?

Видим, что с диском работает только ceph, но мы же понимаем, что ceph это только прослойка. В данном случае у клиента ceph на нескольких нодах выступает хранилищем для кластера kubernetes, посмотрим, что внутри k8s генерирует больше всего записи на диск:

Абсолютные значения не совпадают скорее всего из-за того, что ceph работает в кластере и запись от redis приумножается из-за репликации данных. Но профиль нагрузки позволяет уверенно говорить, что запись иницирует именно redis. Давайте смотреть, что там в редисе происходит:

тут видно, что в среднем выполняется меньше 100 запросов в секунду, которые могут изменять данные. Вспоминаем, что у redis есть 2 способа записывать данные на диск:

  • RDB — периодические снэпшоты всей баз на диск, при старте redis читаем последний дамп в память, а данные между дампами мы теряем
  • AOF — пишем лог всех изменений, при старте redis проигрывает этот лог и в памяти оказываются все данные, теряем только данные между fsync этого лога

Как все наверное уже догадались в данном случае используется RDB с периодичность дампа 1 минута:

SSD + RAID

По нашим наблюдениям существуют три основных конфигурации дисковой подсистемы серверов с присутствием SSD:

  • в сервере 2 SSD собраные в raid-1 и там живет всё
  • в сервере есть HDD + raid-10 из ssd, обычно используется для классических РСУБД (система, WAL и часть данных на HDD, а на SSD самые горячие с точки зрения чтения данные)
  • в сервере есть отдельностоящие SSD (JBOD), обычно используется для nosql типа кассандры

В случае, если ssd собраны в raid-1, запись идет на оба диска, соответственно износ идет с одинаковой скоростью:

Но на глаза попался сервер, в котором картинка другая:

При этом cмонтированы только партиции mdraid (все массивы raid-1):

По метрикам записи тоже видно, что на /dev/sda долетает больше записи:

Оказалось, что одна из партиций на /dev/sda используется в качестве swap, а swap i/o на этом сервере достаточно заметно:

Износ SSD и PostgreSQL

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

Износ двух ssd в raid-1 за 3 месяца составил 4%, но судя по скорости записи WAL данный постгрес пишет меньше 100 Kb/s:

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

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

Как вы видите тут, это какой-то конкретный SELECT порождает кучу временных файлов. А вообще в постгресе SELECT’ы иногда порождают запись и без всяких временных файлов — вот тут мы уже про это рассказывали.

Итого

  • Количество записи на диск, которую создает Redis+RDB зависит не от количества модификаций в базе, а от размера базы + интервала дампов (и вообще, это наибольший уровень write amplification в известных мне хранилищах данных)
  • Активно используемый swap на ssd — плохо, но если вам нужно внести jitter в износ ssd (для надежности raid-1), то может сойти за вариант:)
  • Помимо WAL и datafiles базы данных могут ещё писать на диск всякие временные данные

Источник

Читайте также:  Поставить стандартные настройки монитора