FastAPI单条插入CPU耗时1-2ms是否正常?性能优化咨询
高性能FastAPI应用的SQLAlchemy vs asyncpg性能优化疑问
我正在构建一款可扩展的FastAPI应用,目标是支持每秒10000次以上请求(RPS)。当前应用逻辑复杂,但已定位到核心扩容瓶颈:单条数据库插入操作的CPU耗时约1-2毫秒,这直接限制了单个worker的性能——包含多次插入的接口在单pod/worker下仅能达到约300 RPS,必须大量扩容worker才能提升RPS,效率极低。需要说明的是,我不关注数据库侧延迟,核心矛盾是CPU耗时限制了扩容能力。
我搭建了简化的可复现示例,测试结果显示单条插入的CPU耗时确实在1-2毫秒区间。我想确认这个性能表现对于FastAPI是否正常,或是我的配置存在问题?之前看过性能更优的基准测试,所以想明确是否还有优化空间。
SQLAlchemy版本测试代码(app.py)
import time from contextlib import asynccontextmanager from fastapi import FastAPI from sqlalchemy import AsyncAdaptedQueuePool, text from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.orm import sessionmaker db_username = "****" db_password = "****" host = "****" async def setup_database(): dsn = f"postgresql+asyncpg://{db_username}:{db_password}@{host}:5432/postgres" engine = create_async_engine( dsn, pool_size=20, poolclass=AsyncAdaptedQueuePool, ) return sessionmaker(engine, class_=AsyncSession) @asynccontextmanager async def lifespan(app: FastAPI): # Setup the database connection pool app.state.db_session = await setup_database() yield # Close the database connection pool await app.state.db_session.close() app = FastAPI(lifespan=lifespan) @app.get("/test-insert") async def test_insert(): start_time = time.time() start_cpu_time = time.process_time() insert_query = text("INSERT INTO simple_text (text) VALUES (:text) RETURNING id") params = {"text": "Test"} async with app.state.db_session.begin() as sess: result = await sess.execute(insert_query, params) text_id = result.scalar_one() await sess.commit() end_time = time.time() end_cpu_time = time.process_time() duration = end_time - start_time cpu_duration = end_cpu_time - start_cpu_time print( f"Test Insert: {duration:.6f} seconds, CPU time: {cpu_duration:.6f} CPU seconds" ) return {"id": text_id, "duration": duration, "cpu_duration": cpu_duration} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
Dockerfile
# Use an official Python 3.12 runtime as a parent image FROM python:3.12-slim # Set the working directory in the container WORKDIR /app # Copy the current directory contents into the container at /app COPY . /app # Install the dependencies RUN pip install --no-cache-dir -r requirements.txt # Expose port 8000 to the outside world EXPOSE 8000 # Command to run the FastAPI application CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
requirements.txt
fastapi uvicorn[standard] sqlalchemy asyncpg
asyncpg版本优化代码片段
绕过SQLAlchemy直接使用asyncpg后,核心代码如下:
async def setup_database(): return await asyncpg.create_pool( user=db_username, password=db_password, database="postgres", host=host, port=5432, min_size=20, max_size=20, ) @app.get("/test-insert") async def test_insert(): start_time = time.time() start_cpu_time = time.process_time() insert_query = """ INSERT INTO simple_text (text) VALUES ($1) RETURNING id """ params = ("Test",) async with app.state.connection_pool.acquire() as connection: text_id = await connection.fetchval(insert_query, *params) end_time = time.time() end_cpu_time = time.process_time() duration = end_time - start_time cpu_duration = end_cpu_time - start_cpu_time print( f"Test Insert: {duration:.6f} seconds, CPU time: {cpu_duration:.6f} CPU seconds" ) return {"id": text_id, "duration": duration, "cpu_duration": cpu_duration}
测试结果与疑问
测试显示,直接使用asyncpg时,单条插入的平均CPU耗时约0.0004秒,性能比SQLAlchemy版本提升了约3倍。我想咨询:
- 这个asyncpg的性能表现是否是当前场景下的最优水平?
- SQLAlchemy与asyncpg之间的这种性能差距是否符合预期?
补充背景:PostgreSQL中的simple_text表仅包含主键id和字符列text;测试环境包括MacBook Pro M3+Colima+Rosetta,且该性能差异同样出现在GCP K8s的Linux Pod中。
内容的提问来源于stack exchange,提问作者Reyflex
相关产品推荐
相关产品推荐

