LINUX.ORG.RU

Пулл соединений с базой

 , , ,


0

1

Доброго всем.

Пробую на Питоне3 + uwsgi-сервер простое приложение, где естестественно нужно иметь пулл соединений с БД (Postgresql). Причем остановился на драйвере py-postgresql, потому, что в распространенном драйвере Psycopg была ошибка и речь сейчас не о ней. Сразу выяснилось, что драйвер py-postgresql не является threading safe и делаю попытку блокировки при извлечении соединения из пула.

#!/usr/bin/python3
import postgresql
import threading

lock = threading.Lock()
db = []
db.append(postgresql.open("pq://postgres@127.0.0.1/postgres"))
for i in range(10):
    db.append(db[0].clone())

class App(object): #threading.local
    def run(self, env, start_response):
        lock.acquire(1)
        self.db = db.pop()
        lock.release()
        self.st = self.db.prepare('select $1::text')
        resp = ['<h1>Работает</h1>'.encode('utf-8'), str(self.st('тест 1')).encode('utf-8')]
        lock.acquire(1)
        db.insert(0, self.db)
        lock.release()
        start_response('200 OK', [("Content-type", "text/html; charset=UTF-8"),])
        return resp

def application(env, start_response):
    return App().run(env, start_response)

Проблема драйвера py-postgresql для treading так и не решилась для числа worker`ов uwsgi больше чем 1 (processes=1 работает).

Поэтому хочу спросить, что еще можно попробовать сделать, чтобы нормально работать в тредах uwsgi с подготовленными соединениями таких драйверов и вообще общих разделяемых данных?

Что-то слышал еще про threading.local для моего класса App(), но тоже не работает.

Пробовал еще pgbouncer, но и тут py-postgresql не хотел соединяться с прокси.

Не ругайте, если в чем-то ошибаюсь, в терминологии.

Ответ на: комментарий от heisenberg

а вместо питона - php

Всё верно, потому что PHP - самый кошерный язык.

Test11 ()

Пока остановлюсь на решении запустить много одно-worker'ных uwsgi и на них нацепить nginx'овский upstream.

chegeware ()

А в чем проблема Psycopg?

MacBook-Pro:~ phasma$ pip-3.2 freeze
Beaker==1.6.3
Chameleon==2.8.5
Mako==0.7.0
MarkupSafe==0.15
PIL==1.1.7
PasteDeploy==1.5.0
Pygments==1.5
SQLAlchemy==0.7.7
WebOb==1.2b3
distribute==0.6.26
psycopg2==2.4.5
xpahos ★★★★★ ()
Ответ на: комментарий от xpahos

А в чем проблема Psycopg?

а там вообще дурь какая-то, в таблице 4 одинаковых по сути записи, 2 из них нормально select'ятся, а две другие crash'ат через драйвер все приложение, ошибку может завтра покажу.

chegeware ()
Ответ на: комментарий от chegeware

ок, покажи. Может не стоит пока его использовать. Хотя вот сейчас rpm'ки для CentOS 6 дособеру и уже выкачу приложение на тесты.

xpahos ★★★★★ ()
Ответ на: комментарий от xpahos

А в чем проблема Psycopg?

uwsgi: psycopg/cursor_type.c:334: _psyco_curs_merge_query_args: Assertion `((((((PyObject*)(str))->ob_type))->tp_flags & ((1L<<27))) != 0)' failed.
DAMN ! worker 1 (pid: 11346) died :( trying respawn ...
Respawned uWSGI worker 1 (new pid: 11383)

Пока с ошибкой разбираться не стал.

chegeware ()
Ответ на: комментарий от chegeware

причем, ошибка только проявляется с uwsgi, в интерактивной консоли все гладко.

chegeware ()
Ответ на: комментарий от heisenberg

лучше использовать pgbouncer

Он выдает:

Unsupported startup parameter: client_min_messages

Делаю:

ignore_startup_parameters = client_min_messages

Он сыплет в ответ:

postgresql.exceptions.StatementNameError: prepared statement «py:0x25643d0» does not exist

Питоновский дерибас с драйверами мучает сильно.

chegeware ()

А то что ты расставил блокировки ещё не решает проблему с многими тредами. Если либа кривая то это не поможет.

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

true_admin ★★★★★ ()
Ответ на: комментарий от chegeware
[root@xxxxx phasma]# pip-3.2 freeze
Beaker==1.6.3
Chameleon==2.8.5
Mako==0.7.0
MarkupSafe==0.15
PIL==1.1.7
PasteDeploy==1.5.0
Pygments==1.5
SQLAlchemy==0.7.7
WebOb==1.2b3
distribute==0.6.24
psycopg2==2.4.5
pyramid==1.3
pyramid-beaker==0.6.1
pyramid-debugtoolbar==1.0.2
pyramid-tm==0.4
repoze.lru==0.5
transaction==1.2.0
translationstring==1.1
uWSGI==1.2.2
venusian==1.0a6
virtualenv==1.7.1.2
waitress==0.8.1
wsgiref==0.1.2
zope.deprecation==3.5.1
zope.interface==3.8.0
zope.sqlalchemy==0.7

все запустилось с uWSGI. Проблема была с PgSQL 9.1, т.к. в CentOS стоит левый репозиторий, то нужно указать для psycopg2 pg_config. Для PasteDeploy нужно отслеживать в модуле loadwsgi какого типа передается uri.

if isinstance(uri, bytes):
        uri = uri.decode('utf8')
xpahos ★★★★★ ()
Ответ на: комментарий от xpahos

ну там еще нужно было исправить типы в beaker, т.к. HMAC использует bytes при генерации хэша.

xpahos ★★★★★ ()
Ответ на: комментарий от chegeware

это pgbouncer в режиме statement, который наверняка не отлажен. Хрень.

Вы о чём? В режиме statement так и должно быть. Переключите pgbouncer на Transaction pooling.

Eshkin_kot ★★ ()
Ответ на: комментарий от Eshkin_kot

Если либа кривая то это не поможет.

Пусть py-postgresql кривой для нитей, но нравится его prepared statement.

Бейте меня, но сделал кучу однонитевых процессов uwsgi под upstream nginx

for i in $(seq 5); do uwsgi --ini uwsgi.ini -s "/tmp/uwsgi$i.sock"; done

Переключите pgbouncer на Transaction pooling.

Там тоже эта же ошибка, только для pool_mode = session работало, но мне хотелось все же кэширования запросов и поэтому, раз драйвер py-postgresql умеет это делать, пока pgbouncer особо не нужен, соединяюсь напрямую к postgresql.

chegeware ()
Ответ на: комментарий от chegeware

Там тоже эта же ошибка, только для pool_mode = session работало

Значит в py-postgresql включен режим autocommit.

Eshkin_kot ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.