Оптимальная / лучшая практика для поддержания непрерывной связи между Python и Postgresql с использованием Psycopg2 - PullRequest
2 голосов
/ 13 ноября 2009

Я пишу приложение на Python с Postgresql 8.3, которое работает на нескольких машинах в локальной сети.

Все машины

1) извлекает огромное количество данных с сервера базы данных (скажем, база данных получает 100 различных запросов с машины за 2 секунды), и это делают около 10 или 11 машин.

2) После обработки данных машинам приходится обновлять определенные таблицы (около 3 или 4 запросов на обновление / вставку на машину за 1,5 секунды).

Что я заметил, так это то, что база данных иногда отключается из-за ненормальной работы прерванного сервера или остановки сервера (требующего полной перезагрузки).

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

Каков наилучший / оптимальный способ обработки большого количества соединений в приложении, если они будут уничтожены после каждого запроса?

Во-вторых, я должен увеличить max_connections?

Буду очень признателен за любые советы по этому вопросу.

Ответы [ 2 ]

1 голос
/ 14 ноября 2009

Наиболее вероятная причина действительно звучит как нехватка памяти. Если это серверы Linux, то при запуске условия нехватки памяти вызывается «OOM-killer», который просто завершает процессы захвата памяти (следовательно, «сервер прервал процесс ненормально»). Ситуация с нехваткой памяти часто означает очень высокую загрузку дисков / подкачку, из-за чего сервер кажется не отвечающим.

См. Ваши файлы журнала ядра (или команду dmesg) для чего-то похожего на "Out of Memory: Killed process 1234 (postgres)". Это вызвано тем, что по умолчанию ядро ​​разрешает перегружать память. Первое, что вы должны сделать, это отключить overcommit, чтобы обеспечить плавную обработку ситуаций нехватки памяти:

echo 2 > /proc/sys/vm/overcommit_memory

План A:

Вероятным виновником является настройка work_mem, которая указывает, сколько памяти может выделять каждая отдельная операция. Один запрос может состоять из нескольких этапов, интенсивно использующих память, поэтому каждый сервер может выделить несколько раз work_mem объема памяти, в дополнение к глобальной настройке shared_buffers. Кроме того, вам также понадобится немного свободной памяти для кэша операционной системы.

Для получения дополнительной информации см. Руководство PostgreSQL по настройкам потребления ресурсов: Документация PostgreSQL 8.3, потребление ресурсов

План B:

Возможно, сокращение этих параметров настолько замедлит ваши запросы, что вы все равно не сможете выполнить свою работу. Альтернативой этому является искусственное ограничение количества запросов, которые могут выполняться параллельно. Многие пулы соединений промежуточного программного обеспечения для PostgreSQL могут ограничивать количество параллельных запросов и вместо этого предоставлять очереди. Примерами этого программного обеспечения являются pgbouncer (более простой) и pgpool-II (более гибкий).

РЕДАКТИРОВАТЬ : Отвечая на ваши вопросы:

Каков наилучший / оптимальный способ обработки большого количества соединений в приложении, если они будут уничтожены после каждого запроса?

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

Промежуточное ПО для пулов соединений, о котором я упоминал в Plan B , позаботится о сохранении разумного количества соединений с Postgres - независимо от того, когда и как часто вы подключаетесь или отключаетесь от пула. Поэтому, если вы выберете этот маршрут, вам не нужно беспокоиться об открытии / закрытии соединений вручную.

Во-вторых, я должен увеличить max_connections?

Если ваш сервер баз данных не имеет большого объема ОЗУ (более 8 ГБ), я бы не стал превышать ограничение по умолчанию в 100 подключений.

1 голос
/ 13 ноября 2009

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

Если вы открываете все соединения в начале и держите их открытыми, max_connections не является виновником. То, как вы обрабатываете соединения с БД, должно быть в порядке, и ваш сервер не должен этого делать независимо от того, как он настроен.

...