MySQL连接池调优实战经验总结
一、核心参数速查表
参数名 | 建议值 | 说明 |
---|---|---|
pool_size | 20-50 | 基础连接池大小 |
max_overflow | 10-20 | 最大溢出连接数 |
pool_recycle | 600-1800 | 连接回收时间(秒) |
pool_timeout | 10-30 | 获取连接超时时间 |
pool_pre_ping | True | 连接预检 |
二、常见问题与解决方案
1. 连接池耗尽
# 症状:大量 "TimeoutError: QueuePool limit of size 5 overflow 10 reached"
# 解决方案:
engine = create_async_engine(
DATABASE_URL,
pool_size=30, # 增加基础连接数
max_overflow=15, # 适当增加溢出连接
pool_timeout=20, # 减少等待时间
pool_pre_ping=True # 开启预检
)
2. 连接超时
# 症状:MySQL server has gone away
# 解决方案:
engine = create_async_engine(
DATABASE_URL,
pool_recycle=1800, # 设置合理的回收时间
pool_pre_ping=True, # 必须开启预检
# 添加重试机制
connect_args={
"connect_timeout": 10,
"retry_count": 3
}
)
3. 高并发下性能下降
# 优化配置
engine = create_async_engine(
DATABASE_URL,
pool_size=50,
max_overflow=20,
pool_recycle=600, # 高并发场景缩短回收时间
use_lifo=True, # 使用LIFO策略提高性能
echo=False # 关闭SQL日志
)
三、实战经验总结
1. 连接池大小计算公式
# 推荐公式
pool_size = min(
cpu核心数 * 2,
预估最大并发请求数 * 0.1
)
# 示例
if cpu_cores = 8:
pool_size = 16 # 8 * 2
if max_concurrent_requests = 1000:
pool_size = 100 # 1000 * 0.1
2. 回收时间设置原则
def get_pool_recycle(scenario):
if scenario == "high_concurrency":
return 600 # 10分钟
elif scenario == "normal":
return 1800 # 30分钟
else:
return 3600 # 1小时
3. 监控必看指标
class PoolMetrics:
@staticmethod
async def collect():
return {
"连接使用率": "已用连接/总连接数",
"连接等待时间": "获取连接的平均等待时间",
"连接回收频率": "单位时间内回收的连接数",
"连接创建频率": "单位时间内创建的新连接数"
}
四、最佳实践Check List
1. 基础配置检查
- pool_size 是否合理设置
- pool_recycle 是否符合业务场景
- pool_pre_ping 是否开启
- 是否配置了错误重试机制
2. 性能优化检查
- 是否根据CPU核心数调整pool_size
- 是否启用了LIFO策略
- 是否关闭了不必要的日志
- 是否设置了合理的超时时间
3. 监控告警检查
- 是否监控连接池使用率
- 是否设置了连接超时告警
- 是否监控连接创建/销毁频率
- 是否有连接池溢出告警
五、踩坑记录
1. 常见错误
# 错误示范
engine = create_async_engine(
DATABASE_URL,
pool_size=100, # ❌ 设置过大
pool_recycle=7200, # ❌ 回收时间过长
echo=True # ❌ 生产环境开启日志
)
# 正确示范
engine = create_async_engine(
DATABASE_URL,
pool_size=30, # ✅ 适中的池大小
pool_recycle=1800, # ✅ 合理的回收时间
echo=False # ✅ 生产环境关闭日志
)
2. 性能陷阱
# 避免的做法
async def bad_practice():
async with engine.connect() as conn:
# ❌ 长时间占用连接
await asyncio.sleep(10)
await conn.execute(query)
# 推荐的做法
async def good_practice():
# ✅ 最小化连接占用时间
await prepare_data() # 预处理数据
async with engine.connect() as conn:
await conn.execute(query)
六、调优建议
-
循序渐进
- 从默认配置开始
- 根据监控数据逐步调整
- 保持观察和记录
-
场景匹配
- 低并发:保守配置
- 中等并发:平衡配置
- 高并发:激进配置
-
安全措施
- 总是启用连接预检
- 实现错误重试机制
- 设置合理的超时时间
-
监控先行
- 建立基准指标
- 持续监控变化
- 及时调整参数
记住:没有一劳永逸的配置,需要根据实际情况持续优化调整。
#数据库优化 #MySQL #连接池 #性能调优 #Python