У нас проблемы с обработкой трафика в часы пик на наш сервер базы данных. Мы пытаемся улучшить аппаратное обеспечение (см. Этот вопрос об этой стороне вещей ), но мы также хотим поработать над настройкой пула и настройкой сервера.
Приложение, над которым мы работаем, представляет собой пошаговую многопользовательскую игру для смартфонов, где бэкэнд состоит из Rails с единорогом и PostgreSQL 9.1 в качестве базы данных. В настоящее время у нас зарегистрировано 600 000 пользователей, и, поскольку состояние игры хранится в базе данных, каждые несколько секунд производится несколько тысяч записей. Мы проанализировали файлы журналов из PostgreSQL, используя PgBadger, и в критические часы мы получаем много
FATAL: remaining connection slots are reserved for non-replication superuser connections
Наивным решением этой проблемы было бы увеличение max_connections (которое в настоящее время равно 100) в postgresql.conf . Я прочитал http://wiki.postgresql.org/wiki/Number_Of_Database_Connections, где указано, что это может быть неправильно. В вышеупомянутой статье говорится о том, чтобы найти точку между max_connections и размером пула .
Что можно сделать, чтобы найти это сладкое место? Есть ли хорошие инструменты для измерения производительности ввода-вывода для различных значений max_connections и размера пула ?
Наша текущая настройка - 4 игровых сервера, каждый из которых имеет 16 рабочих-единорогов и размер пула 5.
Вот нестандартные настройки postgres, которые мы используем:
version | PostgreSQL 9.1.5 on x86_64-unknown-linux-gnu,compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
checkpoint_completion_target | 0.9
checkpoint_segments | 60
checkpoint_timeout | 6min
client_encoding | UTF8
effective_cache_size | 2GB
lc_collate | en_US.UTF-8
lc_ctype | en_US.UTF-8
log_destination | csvlog
log_directory | pg_log
log_filename | postgresql-%Y-%m-%d_%H%M%S.log
log_line_prefix | %t
log_min_duration_statement | 200ms
log_rotation_age | 1d
log_rotation_size | 10MB
logging_collector | on
max_connections | 100
max_stack_depth | 2MB
server_encoding | UTF8
shared_buffers | 1GB
ssl | on
TimeZone | localtime
wal_buffers | 16MB
work_mem | 8MB
источник
synchronous_commit = off
илиcommit_delay
?INSERT
с? Как выглядит ваша схема - она разделена? Каковыexplain analyze
некоторые примеры запросов? Как часто ваши контрольно-пропускные пункты и сколько времени они занимают? (см. параметры регистрации контрольных точек). А если серьезно, какая у вас версия PostgreSQL ? (Обновление: кажется, вы перечислите свое оборудование здесь: dba.stackexchange.com/questions/28061/… )synchronous_commit = off
Ответы:
Краткий ответ здесь: «Метод проб и ошибок, основанный на показателях мониторинга и производительности».
Есть несколько общих практических правил, которые должны помочь вам найти неопределенную область, с которой вы должны начать, но они очень общие. Часто приводятся общие рекомендации «количество процессоров плюс количество независимых дисков», но это только невероятно грубая отправная точка.
Что вам действительно нужно, так это установить надежные показатели производительности для вашего приложения. Начать запись статистики.
Для этого не так много интегрированных инструментов. Существуют такие вещи, как
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
если все нормально, чтобы потерять несколько транзакций при сбое сервера, и / или acommit_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 этого ноутбука дешев, и я не обязательно доверяю ему, чтобы очистить кэш записи при отключении питания; Я сохраняю хорошие резервные копии и не буду использовать их для данных, которые меня волнуют. Твердотельные накопители хорошего качества работают так же хорошо, если не лучше, и долговечны при записи.В случае вашей заявки я настоятельно рекомендую вам изучить:
UNLOGGED
таблицы для данных, вы можете позволить себе потерять. Периодически объединяйте его в зарегистрированные таблицы. Например, ведите игры в незанятых таблицах и записывайте результаты в обычные таблицы длительного пользования.commit_delay
(менее полезно с быстрой промывкой хранилища - подсказка)synchronous_commit
для транзакций, которые вы можете позволить себе потерять (менее полезно с быстрой очисткой хранилища - подсказка)LISTEN
иNOTIFY
для аннулирования кэша, используя триггеры для таблиц PostgreSQL.Если есть сомнения: http://www.postgresql.org/support/professional_support/
источник