为什么服务器负载测试中异步实现比同步写法性能慢数百倍?
核心问题
- 错误复用AsyncSession执行并发查询
SQLAlchemy的AsyncSession是非并发安全对象,同一时间只能执行一个异步操作。你将4个同session的查询丢给asyncio.gather执行,会触发大量内部锁等待、状态校验开销,甚至会导致查询排队超时,性能远低于同步顺序执行。 - 开启了调试日志
两个数据库引擎都配置了echo=True,会打印所有SQL执行日志,异步pg驱动asyncpg的日志打印开销远高于同步驱动psycopg2,高并发下会严重拖慢性能。 - 连接池配置不足
默认异步引擎的连接池大小仅为5,你用100并发压测时,大量请求拿不到数据库连接排队等待,进一步拉低性能,甚至导致请求超时。
优化方案
- 第一步:关闭调试日志
修改两个引擎的echo=True为echo=False。 - 第二步:修正异步查询逻辑
如果不需要并行查询,直接按同步逻辑的顺序执行即可,不要强行用asyncio.gather,修正后的代码如下:
async def get(self): async with async_session() as session: result1 = await session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1')) self.write(json.dumps(result1.fetchall(), default=str)) result2 = await session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1')) self.write(json.dumps(result2.fetchall(), default=str)) result3 = await session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')) self.write(json.dumps(result3.fetchall(), default=str)) result4 = await session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')) self.write(json.dumps(result4.fetchall(), default=str))
如果要实现真正的并行查询,需要每个查询单独创建Session:
async def exec_query(query: text, params: dict): async with async_session() as session: res = await session.execute(query.bindparams(**params)) return res.fetchall() async def get(self): results = await asyncio.gather( exec_query(text('SELECT * from *** where client_id = :bis_id'), {"bis_id": "bis1"}), exec_query(text('SELECT * from *** where bis_id = :bis_id'), {"bis_id": "bis1"}), exec_query(text('SELECT * from *** where abs_id = :abs_id'), {"abs_id": "abs1"}), exec_query(text('SELECT * from *** where abs_id = :abs_id'), {"abs_id": "abs1"}), ) for res in results: self.write(json.dumps(res, default=str))
- 第三步:调整连接池配置
创建异步引擎时调整连接池参数匹配压测并发数:
async_engine = create_async_engine( "postgresql+asyncpg://***:***@localhost:5431/***", echo=False, pool_size=20, max_overflow=100 )
优化完成后重新压测,异步接口的QPS会恢复到至少和同步接口持平的水平,更高并发场景下性能会优于同步实现。
内容的提问来源于stack exchange,提问作者user2732686
相关产品推荐
相关产品推荐

