Я реализовал pgbouncer с помощью asyncpg, а также реализацию собственного пула asyncpg. Хотя я могу отправить много одновременных запросов через pgbouncer, но мой p95 близок к 8se c для 1000 одновременных запросов, где, как и в случае реализации собственного пула asyncpg, p95 чуть выше 1.5se c.
Почему такая большая разница в производительности? Это правильный способ подключения к pgbouncer из asyncpg?
Пример кода:
- С asyncpg и pgbouncer:
pgbouncer_creds = {
"user": "myuser",
"password": "password",
"host": "localhost",
"port": "16432",
"database": "db1"
}
async def test():
async def db():
start = time.time()
connection = await asyncpg.connect(**pgbouncer_creds)
await connection.fetchrow("SELECT * FROM test WHERE id=$1;", "5db03111822547b59c3edaa324e0f829")
await connection.close()
end = time.time()
times.append((end - start))
tasks = [db() for _ in range(1000)]
await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(test())
loop.close()
Реализация собственного асинхронного пула
creds = {
"user": "myuser",
"password": "password",
"host": "*.*.*.*",
"port": "5432",
"database": "db1"
}
async def test():
pool = await asyncpg.create_pool(**creds, max_size=100, min_size=100)
async def db():
start = time.time()
async with pool.acquire() as connection:
await connection.fetchrow("SELECT * FROM test WHERE id=$1;", "5db03111822547b59c3edaa324e0f829")
end = time.time()
times.append((end - start))
tasks = [db() for _ in range(1000)]
await asyncio.gather(*tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(test())
loop.close()
Файл pgbouncer.ini:
[databases]
db1 = host=*.*.*.* dbname=db1
[pgbouncer]
listen_addr = *
listen_port = 16432
auth_type = plain
auth_file = userlist.txt
default_pool_size = 100
max_db_connections = 200
max_client_conn = 10000
max_user_connections = 200
pool_mode = session