Litefs 项目包含全面的性能测试和压力测试,用于验证系统在高负载下的表现和稳定性。
使用 wrk 对 LiteFS 的不同部署模式进行 HTTP 基准测试,对比 LiteFS 原生服务器、ASGI、WSGI 和 FastAPI 的性能表现。
| 项目 | 配置 |
|---|---|
| CPU | 13th Gen Intel(R) Core(TM) i7-1355U (12 线程, 10 核心) |
| 内存 | 62 GiB |
| 操作系统 | Linux x86_64 (6.12.65-amd64) |
| Python | 3.10.9 |
| wrk | 4.2.0 [epoll] |
- 进程数:1 / 6
- 并发连接:500 / 1000
- 测试时长:10s/组
- wrk 线程数:4
| 服务器 | 1P-c500 | 1P-c1000 | 6P-c500 | 6P-c1000 |
|---|---|---|---|---|
| LiteFS-Greenlet | 8,077 | 6,669 | 14,922 | 15,687 |
| LiteFS-ASGI/Uvicorn | 4,795 | 5,023 | 9,589 | 11,634 |
| LiteFS-WSGI/Gunicorn | 6,176 | 6,839 | 14,026 | 13,239 |
| FastAPI/Uvicorn | 4,858 | 4,804 | 9,316 | 10,499 |
| 服务器 | 1P-c500 | 1P-c1000 | 6P-c500 | 6P-c1000 |
|---|---|---|---|---|
| LiteFS-Greenlet | 121.36 | 303.95 | 91.51 | 158.77 |
| LiteFS-ASGI/Uvicorn | 230.11 | 250.45 | 74.95 | 178.98 |
| LiteFS-WSGI/Gunicorn | 1,460.00 | 1,770.00 | 1,380.00 | 1,530.00 |
| FastAPI/Uvicorn | 158.07 | 264.92 | 92.01 | 170.18 |
cd benchmarks
PATH=~/.pyenv/shims:~/.pyenv/bin:~/Installed:/usr/local/bin:/usr/bin:/bin python run_benchmark.py结果自动保存到 results/{timestamp}/data.json,HTML 报告在 results/latest/report.html。
tests/
├── performance/
│ └── test_performance.py # 性能测试
├── stress/
│ └── test_stress.py # 压力测试
└── requirements-performance.txt # 性能测试依赖
性能测试用于测量各个模块在正常负载下的性能表现。
-
put 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 ops/s
-
get 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 0.5 秒
- 预期吞吐量:> 20,000 ops/s
-
delete 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 ops/s
-
LRU 淘汰性能
- 测试目标:10,000 次操作,缓存大小 1,000
- 性能要求:< 1.0 秒
- 验证:保留 1,000 个缓存项
-
put 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 2.0 秒
- 预期吞吐量:> 5,000 ops/s
-
get 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 ops/s
-
delete 操作性能
- 测试目标:10,000 次操作
- 性能要求:< 5.0 秒
- 预期吞吐量:> 2,000 ops/s
-
简单表单解析
- 测试目标:10,000 次解析
- 表单大小:3 个参数
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 ops/s
-
复杂表单解析
- 测试目标:10,000 次解析
- 表单大小:包含数组和字典
- 性能要求:< 2.0 秒
- 预期吞吐量:> 5,000 ops/s
-
大表单解析
- 测试目标:1,000 次解析
- 表单大小:100 个参数
- 性能要求:< 5.0 秒
- 预期吞吐量:> 200 ops/s
-
会话创建性能
- 测试目标:10,000 次创建
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 sessions/s
-
会话数据访问性能
- 测试目标:10,000 次访问
- 性能要求:< 0.1 秒
- 预期吞吐量:> 100,000 ops/s
压力测试用于验证系统在高并发和极端负载下的稳定性和性能。
-
并发 put 操作
- 线程数:10
- 每线程操作数:1,000
- 总操作数:10,000
- 性能要求:< 5.0 秒
- 预期吞吐量:> 2,000 ops/s
-
并发 get 操作
- 线程数:10
- 每线程操作数:1,000
- 总操作数:10,000
- 性能要求:< 2.0 秒
- 预期吞吐量:> 5,000 ops/s
-
并发混合操作
- 线程数:10
- 每线程操作数:500
- 总操作数:5,000
- 操作类型:put、get、delete
- 性能要求:< 5.0 秒
- 预期吞吐量:> 1,000 ops/s
-
并发 put 操作
- 线程数:5
- 每线程操作数:500
- 总操作数:2,500
- 性能要求:< 10.0 秒
- 预期吞吐量:> 250 ops/s
-
并发 get 操作
- 线程数:10
- 每线程操作数:1,000
- 总操作数:10,000
- 性能要求:< 5.0 秒
- 预期吞吐量:> 2,000 ops/s
- 并发解析
- 线程数:10
- 每线程操作数:1,000
- 总操作数:10,000
- 性能要求:< 2.0 秒
- 预期吞吐量:> 5,000 ops/s
-
并发会话创建
- 线程数:10
- 每线程会话数:1,000
- 总会话数:10,000
- 性能要求:< 5.0 秒
- 预期吞吐量:> 2,000 sessions/s
-
并发会话访问
- 线程数:10
- 每线程操作数:1,000
- 总操作数:10,000
- 性能要求:< 1.0 秒
- 预期吞吐量:> 10,000 ops/s
-
MemoryCache 内存泄漏
- 操作数:10,000 次 put
- 缓存大小:1,000
- 验证:对象增长 < 5,000
-
TreeCache 内存泄漏
- 操作数:10,000 次 put
- 验证:对象增长 < 15,000
pip install -r requirements-performance.txt# 运行所有性能测试
python tests/performance/test_performance.py
# 运行特定测试类
python -m unittest tests.performance.test_performance.TestMemoryCachePerformance
# 运行特定测试方法
python -m unittest tests.performance.test_performance.TestMemoryCachePerformance.test_put_performance# 运行所有压力测试
python tests/stress/test_stress.py
# 运行特定测试类
python -m unittest tests.stress.test_stress.TestMemoryCacheStress
# 运行特定测试方法
python -m unittest tests.stress.test_stress.TestMemoryCacheStress.test_concurrent_puts# 安装 pytest-benchmark
pip install pytest-benchmark
# 运行基准测试
pytest tests/performance/test_performance.py --benchmark-only
# 生成基准测试报告
pytest tests/performance/test_performance.py --benchmark-only --benchmark-autosave创建 Locust 测试文件:
from locust import HttpUser, task, between
class LitefsUser(HttpUser):
wait_time = between(1, 3)
@task
def index(self):
self.client.get("/")
@task
def api_test(self):
self.client.get("/api/test")运行 Locust:
locust -f locustfile.py --host=http://localhost:9090| 操作 | 单线程吞吐量 | 并发吞吐量 | 延迟 (P50) | 延迟 (P99) |
|---|---|---|---|---|
| put | > 10,000 ops/s | > 2,000 ops/s | < 0.1ms | < 1ms |
| get | > 20,000 ops/s | > 5,000 ops/s | < 0.05ms | < 0.5ms |
| delete | > 10,000 ops/s | - | < 0.1ms | < 1ms |
| 操作 | 单线程吞吐量 | 并发吞吐量 | 延迟 (P50) | 延迟 (P99) |
|---|---|---|---|---|
| put | > 5,000 ops/s | > 250 ops/s | < 0.2ms | < 2ms |
| get | > 10,000 ops/s | > 2,000 ops/s | < 0.1ms | < 1ms |
| delete | > 2,000 ops/s | - | < 0.5ms | < 5ms |
| 表单类型 | 吞吐量 | 延迟 (P50) | 延迟 (P99) |
|---|---|---|---|
| 简单表单 | > 10,000 ops/s | < 0.1ms | < 1ms |
| 复杂表单 | > 5,000 ops/s | < 0.2ms | < 2ms |
| 大表单 | > 200 ops/s | < 5ms | < 50ms |
| 操作 | 单线程吞吐量 | 并发吞吐量 | 延迟 (P50) | 延迟 (P99) |
|---|---|---|---|---|
| 创建 | > 10,000 sessions/s | > 2,000 sessions/s | < 0.1ms | < 1ms |
| 访问 | > 100,000 ops/s | > 10,000 ops/s | < 0.01ms | < 0.1ms |
- 调整缓存大小:根据实际需求设置合适的 max_size
- 监控命中率:定期检查缓存命中率,优化缓存策略
- 预热缓存:在系统启动时预加载常用数据
- 调整过期时间:根据数据特性设置合理的 expiration_time
- 优化清理周期:根据数据更新频率调整 clean_period
- 使用路径前缀:合理设计缓存键的路径结构
- 限制表单大小:设置合理的 max_request_size
- 缓存解析结果:对重复的表单数据进行缓存
- 使用异步解析:对于大表单使用异步处理
- 设置会话超时:根据业务需求设置合理的过期时间
- 压缩会话数据:对大型会话数据进行压缩
- 使用分布式缓存:在多服务器环境中使用分布式缓存
# 安装 memory-profiler
pip install memory-profiler
# 运行内存分析
python -m memory_profiler tests/performance/test_performance.py# 安装 line-profiler
pip install line-profiler
# 在代码中添加装饰器
@profile
def your_function():
pass
# 运行行级性能分析
kernprof -l -v your_script.py# 安装 py-spy
pip install py-spy
# 实时监控 CPU 使用
py-spy top --pid <PID>
# 生成火焰图
py-spy record -o profile.svg --pid <PID>name: Performance Tests
on: [push, pull_request]
jobs:
performance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install -r requirements-performance.txt
- name: Run performance tests
run: python tests/performance/test_performance.py
- name: Run stress tests
run: python tests/stress/test_stress.py- 测试环境:在类似生产环境的硬件上运行测试
- 预热:在正式测试前进行预热,避免冷启动影响
- 多次运行:多次运行测试取平均值,减少误差
- 资源监控:监控 CPU、内存、磁盘 I/O 等资源使用情况
- 基准对比:与历史基准对比,及时发现性能退化
- 检查是否有内存泄漏
- 检查是否有锁竞争
- 检查是否有不必要的对象创建
- 检查是否有低效的算法
- 检查是否有死锁
- 检查是否有竞态条件
- 检查是否有线程安全问题
- 检查是否有资源争用
- 使用 memory-profiler 分析内存使用
- 检查是否有循环引用
- 检查是否有大对象未释放
- 检查是否有缓存未清理
建议定期运行性能测试和压力测试:
- 每次代码提交后运行性能测试
- 每周运行完整的压力测试
- 在发布前进行全面的性能验证
- 建立性能基准和监控指标
- 及时发现和解决性能问题