Краткий ответ здесь: «Метод проб и ошибок, основанный на показателях мониторинга и производительности».
Есть несколько общих практических правил, которые должны помочь вам найти неопределенную область, с которой вы должны начать, но они очень общие. Часто приводятся общие рекомендации «количество процессоров плюс количество независимых дисков», но это только невероятно грубая отправная точка.
Что вам действительно нужно, так это установить надежные показатели производительности для вашего приложения. Начать запись статистики.
Для этого не так много интегрированных инструментов. Существуют такие вещи, как check_postgres
сценарий nagios , ведение журнала счетчика производительности системы Cacti, сборщик статистики PostgreSQL и т. Д., Но не так много, что объединяет все это. К сожалению, вам придется сделать это самостоятельно. Что касается PostgreSQL, см. Мониторинг в руководстве PostgreSQL. Существуют некоторые сторонние варианты, такие как Postgres Enterprise Monitor от EnterpriseDB .
Для метрик уровня приложения, упомянутых здесь, вы захотите записать их в общих структурах данных или во внешнюю недолговечную БД, такую как Redis, и агрегировать их либо во время записи, либо перед записью их в базу данных PostgreSQL. Попытка войти непосредственно в Pg исказит ваши измерения с накладными расходами, созданными записью измерений, и усугубит проблему.
Самым простым вариантом, вероятно, является одиночный файл на каждом сервере приложений, который вы используете для записи статистики приложений. Вы, вероятно, хотите постоянно обновлять min, max, n, total и mean; Таким образом, вам не нужно хранить каждую статистическую точку, только агрегаты. Этот синглтон может записывать свои статистические данные в Pg каждые x минут, что является достаточно низким показателем, чтобы влияние на производительность было минимальным.
Начните с:
Какова задержка запроса? Другими словами, сколько времени приложение получает от получения запроса от клиента, пока оно не ответит клиенту. Запишите это в совокупности за период времени, а не как отдельные записи. Группируйте его по типу запроса; скажем, по странице.
Какая задержка доступа к базе данных для каждого запроса или типа запроса, выполняемого приложением? Сколько времени требуется от запроса к БД информации / хранения информации, пока это не будет сделано и может перейти к следующей задаче? Опять же, агрегируйте эту статистику в приложении и записывайте только агрегированную информацию в БД.
Какова ваша пропускная способность? За какие x минут сколько запросов каждого основного класса, выполняемых вашим приложением, обслуживается БД?
За тот же промежуток времени х минут, сколько было запроса клиента?
Выборка каждые несколько секунд и агрегирование по тем же x минутным окнам в БД, сколько было подключений к БД? Сколько из них были простаивают? Сколько было активных? Во вставках? Обновления? выбирает? удаления? Сколько транзакций было проведено за этот период? Видеть документацию сборщика статистики
Опять же, выборка и агрегация за один и тот же промежуток времени, каковы показатели производительности хост-системы? Сколько читают и сколько пишут дисковые операции ввода-вывода / секунду? Мегабайт в секунду диска читает и пишет? Загрузка процессора? Нагрузка средняя? ОЗУ использовать?
Теперь вы можете начать изучать производительность вашего приложения, сопоставляя данные, составляя их график и т. Д. Вы начнете видеть шаблоны, начнете находить узкие места.
Возможно, вы узнаете, что ваша система имеет узкое место INSERT
и работает UPDATE
с высокой скоростью транзакций, несмотря на довольно низкий дисковый ввод-вывод в мегабайтах в секунду. Это будет подсказкой о том, что вам нужно улучшить производительность очистки диска с помощью RAID-контроллера кэширования с обратной записью с резервным питанием от батареи или некоторых высококачественных твердотельных накопителей с защитой питания. Вы также можете использовать, synchronous_commit = off
если все нормально, чтобы потерять несколько транзакций при сбое сервера, и / или a commit_delay
, чтобы снять часть нагрузки синхронизации.
Когда вы будете отображать количество транзакций в секунду в зависимости от количества одновременных подключений и корректируете изменяющуюся частоту запросов, которую видит приложение, вы сможете лучше понять, в каком месте находится ваша пропускная способность.
Если у вас нет быстро сбрасываемого хранилища (BBU RAID или быстродействующие твердотельные накопители), вам не нужно больше, чем достаточно небольшое количество активно записывающих соединений, возможно, самое большее, в два раза больше дисков, которые у вас есть, возможно, меньше в зависимости от расположения RAID производительность диска и т. д. В этом случае это даже не стоит проб и ошибок; просто обновите свою подсистему хранения до одной с быстрой очисткой диска .
Найдите pg_test_fsync
инструмент, который поможет вам определить, может ли это быть проблемой для вас. Большинство пакетов PostgreSQL устанавливают этот инструмент как часть contrib, поэтому вам не нужно его компилировать. Если вы получаете менее пары тысяч операций в секунду, pg_test_fsync
вам необходимо срочно обновить систему хранения. Мой ноутбук с SSD получает 5000-7000. Моя рабочая станция при работе с 4-дисковым массивом RAID 10 с 7200 об / мин дисками SATA и сквозной записью (без кэширования при записи) получает около 80 операций в секунду f_datasync
, а для 20 операций в секунду fsync()
; это в сотни раз медленнее . Сравните: ноутбук с рабочей станцией ssd vs с сквозной записью (без кэширования записи) RAID 10, SSD этого ноутбука дешев, и я не обязательно доверяю ему, чтобы очистить кэш записи при отключении питания; Я сохраняю хорошие резервные копии и не буду использовать их для данных, которые меня волнуют. Твердотельные накопители хорошего качества работают так же хорошо, если не лучше, и долговечны при записи.
В случае вашей заявки я настоятельно рекомендую вам изучить:
- Хорошая подсистема хранения с быстрыми сбросами. Я не могу подчеркнуть это достаточно. Высококачественные отказоустойчивые твердотельные накопители и / или RAID-контроллер с защищенным кешем обратной записи.
- Используя
UNLOGGED
таблицы для данных, вы можете позволить себе потерять. Периодически объединяйте его в зарегистрированные таблицы. Например, ведите игры в незанятых таблицах и записывайте результаты в обычные таблицы длительного пользования.
- Использование
commit_delay
(менее полезно с быстрой промывкой хранилища - подсказка)
- Выключать
synchronous_commit
для транзакций, которые вы можете позволить себе потерять (менее полезно с быстрой очисткой хранилища - подсказка)
- Таблицы секционирования, особенно таблицы, в которых данные «стареют» и очищаются. Вместо удаления из многораздельной таблицы удалите раздел.
- Частичные индексы
- Сокращение количества создаваемых вами индексов. Каждый индекс имеет стоимость записи.
- Пакетная работа в большие транзакции
- Использование реплики горячего резервирования только для чтения для снятия нагрузки чтения с основной БД
- Использование слоя кэширования, такого как memcached или redis, для данных, которые изменяются реже или могут позволить себе устаревать. Вы можете использовать
LISTEN
и NOTIFY
для аннулирования кэша, используя триггеры для таблиц PostgreSQL.
Если есть сомнения: http://www.postgresql.org/support/professional_support/
synchronous_commit = off
илиcommit_delay
?