Найти - Пользователи
Полная версия: Долгий коннект к Postgresql
Начало » Базы данных » Долгий коннект к Postgresql
1 2 3
AlexanderDanilov
Всем привет, пожалуйста, подскажите, с чем может быть связан столь долгий коннект к базе.

import psycopg2
import psycopg2.extras as DBExtra
import psycopg2.extensions
from time import time

cursor_factory = DBExtra.DictCursor


class TimeProfiler():
_started = []
labels = {}

def start(self, label):
self._started.append(label)
self.labels[label] = time()

def stop(self, label):
if self.labels.has_key(label):
if label in self._started: self._started.remove(label)
self.labels[label] = '%.4f' % (time() - self.labels[label])
else: self.labels[label] = 0

def get_list(self):
labels = {}
for key in self.labels.keys():
if key not in self._started: labels[key] = self.labels[key]
return labels

T = TimeProfiler()
T.start('connect')
c = psycopg2.connect('host=127.0.0.1 user=postgres dbname=shopmaker')
T.stop('connect')

print T.get_list()
Время выполнения
 python /home/alex/test.py
{'connect': '0.1348'}
Александр Кошелев
Chuck
с чем может быть связан столь долгий коннект к базе.
С тем что это постгрес?
slav0nic
pgbouncer поставь или смени хостера В)
DcDr
slav0nic
pgbouncer поставь или смени хостера В)
Хостера? В смысле - это для веб-сайта?
Вы для каждого запроса заново к базе данных подключаетесь? Зачем так жестоко?
AlexanderDanilov
Это для вебсайта.

Что вы имеете в виду? Для каждого нового пользователя я заново подключаюсь к базе. Не для каждого запроса в движке сайта, разумеется.
DcDr
Chuck
Всем привет, пожалуйста, подскажите, с чем может быть связан столь долгий коннект к базе.

import psycopg2
import psycopg2.extras as DBExtra
import psycopg2.extensions
from time import time

cursor_factory = DBExtra.DictCursor


class TimeProfiler():
_started = []
labels = {}

def start(self, label):
self._started.append(label)
self.labels[label] = time()

def stop(self, label):
if self.labels.has_key(label):
if label in self._started: self._started.remove(label)
self.labels[label] = '%.4f' % (time() - self.labels[label])
else: self.labels[label] = 0

def get_list(self):
labels = {}
for key in self.labels.keys():
if key not in self._started: labels[key] = self.labels[key]
return labels

T = TimeProfiler()
T.start('connect')
c = psycopg2.connect('host=127.0.0.1 user=postgres dbname=shopmaker')
T.stop('connect')

print T.get_list()
Время выполнения
 python /home/alex/test.py
{'connect': '0.1348'}
А другие приложения с того же компьютера (например, утилиты, идущие в комплекте с PostgreSQL) также долго это делают? Или это проблем только вашей программы?

А еще коннекшн-пулы существуют. У psycopg2 - есть свой встроенный. И даже не один.
Если речь идет о веб-сервере - то большая подмога.
DcDr
Chuck
Это для вебсайта.

Что вы имеете в виду? Для каждого нового пользователя я заново подключаюсь к базе. Не для каждого запроса в движке сайта, разумеется.
У меня получается:

{'connect': ‘0.0920’}

{'connect': ‘0.0250’}

{'connect': ‘0.0250’}

То есть первый раз значительно дольше.

Я имею ввиду то, что быстрый веб-сайт после первого веб-запроса должен держать подключение к базе данных.
В течение сколько-нибудь длительного времени - заведомо превышающего время в течение которого шарится по сайту посетитель.

Посему сколько времени занимает коннект - программиста не должно заботить. Ну подождет он первую страничку чуть дольше на долю секунды. Остальные - то уже быстро будут.
Тем более, что у Вас вполне разумные показатели.

Ответ где то здесь: “psycopg2.pool”.

А зачем Вы на КАЖДОГО пользователя подключаетесь? Не доверяете организации безопасности на уровне веб-приложения?
DcDr
DcDr
У меня получается:

{'connect': ‘0.0920’}

{'connect': ‘0.0250’}

{'connect': ‘0.0250’}

То есть первый раз значительно дольше
Повторил спустя минут двадцать. Получил уже задержку 0.052, а последующие опять 0.026-0.026

Очевидно, что разница между первым и последующими запусками тестирующей утилиты - это кэширование на уровне операционной системы (файловой системы), PostgreSQL.

То есть psycopg2 и Python здесь не причем.

В принципе у Вас не такие уж большие задержки - я на весьма жирном железе свои замеры производил - если ваши замеры с реального хостинга, то довольно хорошие показатели.
DcDr
DcDr
DcDr
У меня получается:

{'connect': ‘0.0920’}

{'connect': ‘0.0250’}

{'connect': ‘0.0250’}

То есть первый раз значительно дольше
Повторил спустя минут двадцать. Получил уже задержку 0.052, а последующие опять 0.026-0.026

Очевидно, что разница между первым и последующими запусками тестирующей утилиты - это кэширование на уровне операционной системы (файловой системы), PostgreSQL.

То есть psycopg2 и Python здесь не причем.

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

Предыдущие тесты выполнял каждый раз заново запуская программу.

Переместил 3 подключения-отключения подряд в одну программу.
Замеры те же самые - 0.025-0.26.

То есть быстрее уже не получается, особых тормозов уже не наблюдается…
DcDr
Переделал на пулы:

Один запуск:
{'create pool': '0.1290'}
{'connect 1': '0.0000', 'create pool': '0.1290'}
{'connect 2': '0.0000', 'connect 1': '0.0000', 'create pool': '0.1290'}
{'connect 3': '0.0000', 'connect 2': '0.0000', 'connect 1': '0.0000', 'create pool': '0.1290'}
Второй запуск:
{'create pool': '0.1150'}
{'connect 1': '0.0000', 'create pool': '0.1150'}
{'connect 2': '0.0000', 'connect 1': '0.0000', 'create pool': '0.1150'}
{'connect 3': '0.0000', 'connect 2': '0.0000', 'connect 1': '0.0000', 'create pool': '0.1150'}
Переделанный код:
T.start('create pool')
#pool = psycopg2.pool.ThreadedConnectionPool(5, 10, 'host=127.0.0.1 user=test dbname=test password=test')
pool = psycopg2.pool.PersistentConnectionPool(5, 10, 'host=127.0.0.1 user=test dbname=test password=test')
T.stop('create pool')

print T.get_list()

T.start('connect 1')
c = pool.getconn()
T.stop('connect 1')

print T.get_list()


T.start('connect 2')
c = pool.getconn()
T.stop('connect 2')

print T.get_list()


T.start('connect 3')
c = pool.getconn()
T.stop('connect 3')

print T.get_list()
Как видно пул создается заметно дольше чем соединение, но зато потом соединения из пула можно взять мгновенно.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB