性能比拼: Go标准库 vs Python FastAPI

本内容是对知名性能评测博主 Anton Putra Python (FastAPI) vs Go (Golang) Performance Benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准

在本视频中,我们将对比 FastAPI (Python 生态中最快的 Web 框架之一)和 Golang 标准库的性能。


第一轮测试

为了建立基准,我们的第一轮测试仅测试框架本身的性能:

  • 每个应用程序都会返回 硬编码对象 ,并以 JSON 格式 响应客户端。

  • 我们将测量以下关键指标:

    • 99% 分位数的延迟
    • 每秒请求数(Requests per Second, RPS)
    • CPU 使用率
    • 内存使用率
    • 错误率(可用性)
    • CPU 限流(CPU Throttling)

由于我们会在 AWS 上的生产级 Kubernetes 集群 部署这些应用程序,因此测试环境尽可能贴近真实生产环境。


第二轮测试

第二轮测试更加有趣:

  • 当应用程序收到 POST 请求 时:
    • 解析请求体。
    • 生成 UUID 和时间戳。
    • 将记录插入 关系型数据库(PostgreSQL)
    • (新增)使用缓存系统:在插入数据库后,将对象(包括数据库生成的 ID)存入缓存。

本次测试首次加入了缓存 ,我选择了 Memcached ,因为它的性能更高。但如果你感兴趣,可以在另外的视频中看到它与 Redis 的对比。

为了更细致地分析性能,我使用 Prometheus 监测每个应用的关键操作,例如 数据库插入缓存存取。此外,我们还会测量:

  • PostgreSQL 和 Memcached 的 CPU 使用率
  • 每个应用程序创建的数据库连接池大小

测试环境

所有测试都在 AWS 运行:

  • Memcached 部署在 m7a.xlarge 实例
  • PostgreSQL 部署在 2xlarge 专用 EC2 实例
  • EKS 集群
    • 第一组节点 :使用 m7a.large 通用实例 运行应用程序。
    • 第二组节点 :使用 Graviton 计算优化实例 部署 PrometheusGrafana 和用于生成负载的客户端。

计算优化实例的硬件与通用实例相同,但 内存更少,每小时价格便宜 $0.10。由于测试不需要太多内存,所以我尽可能优化成本。


第一轮测试

开始执行第一轮测试

这轮测试没有任何依赖项,甚至没有业务逻辑,仅仅是返回硬编码的数据给客户端。

从一开始,你就能看到 性能上的巨大差异

  • 客户端测量的延迟 :FastAPI的延迟至少是Go 应用程序 的 两倍
  • CPU 使用率
    • 在过去的测试中,Python 应用的 CPU 使用率通常远高于其他语言
    • FastAPI 在 13,000 RPS 左右开始跟不上,无法处理更多请求。
    • 由于 CPU 资源耗尽,Kubernetes 开始对 FastAPI 进行限流,导致其延迟大幅上升。
  • Go 应用在 25,000 RPS 时,FastAPI 彻底崩溃
    • Python 服务器过载,导致 可用性降至 0
    • 客户端请求要么超时,要么返回 500 错误
    • 在 FastAPI 彻底崩溃期间,客户端不会收到响应,因此延迟图表上会出现空白

从性能表现来看,FastAPI 的表现类似于 Django,甚至只稍微好一点

如果你有优化方案,欢迎提交 Pull Request ,我会重新测试。但到目前为止,我对 FastAPI 的表现感到失望,本来期望它的性能会更好。

接下来,我让测试继续运行,直到 Go 应用达到极限

  • Go 应用的 RPS 在 60,000 - 62,000 之间,和我之前的基准测试非常一致。
  • Kubernetes 运行 Go 应用 时,建议限制 Go 用户线程数,这样 Kubernetes 就不会对其进行过多的限流。

第一轮测试结果

1. 每秒请求数(RPS)

  • FastAPI 最高达到 13,000 RPS
  • Go 最高达到 62,000 RPS

2. 客户端延迟

  • FastAPI 失败时,延迟图表会出现空白
  • Go 的整体延迟远低于 FastAPI

3. CPU 使用率

  • FastAPI 在前 10-15 分钟内就达到 CPU 上限,并开始性能下降

4. 可用性

  • 计算方式:成功请求数 / 总请求数
  • FastAPI 崩溃后,可用性直接降为 0

5. 内存使用

  • Go 在崩溃前,内存使用量会激增

6. CPU 限流

  • FastAPI 的 CPU 限流现象更严重 ,因为它很快就耗尽了 CPU 资源

第二轮测试

在这轮测试中,我们首次引入缓存

  • 每当应用收到请求:
    • 解析请求体。
    • 插入 PostgreSQL
    • 将数据存入 Memcached

为什么选 Memcached 而不是 Redis?

  • Memcached 更高效,可以使用更小的实例,节省基础设施成本。

第二轮测试结果

第一次运行测试时

  • FastAPI 仅使用 60% 的 CPU(2 个 Worker 进程)
  • 由于大量 I/O 操作 (数据库 & 缓存),我增加 Worker 进程至 4 ,CPU 使用率提升至 80%

1. RPS

  • FastAPI 仅能处理 800 RPS,表现远远落后于 Go。

2. 数据库 & 缓存操作

  • Go 的数据库和缓存操作延迟明显更低
  • POST 请求的整体延迟也更低

3. 资源限制

  • FastAPI 在 10-15 分钟内达到极限 ,而 Go 需要运行 1 小时才能达到极限

4. PostgreSQL 和 Memcached 监控

  • 测量 PostgreSQL 和 Memcached 的 CPU 使用率
  • 应用程序数据库连接池大小
    • 每个应用的连接池限制为 500
    • 数据库最大连接数增加到 1000+

5. Go 在 35,000 RPS 时失败

  • 原因 :我忘了增加 Linux 服务器的 文件描述符限制(file descriptor limit)。

  • 若优化文件描述符,Go 还能处理更多请求 ,但FastAPI 远远不在同一水平线上,所以我没必要重新测试。


最终结果

打开测试图表:

  • 每秒请求数
  • POST 请求延迟

Go最后的延迟峰值是由于文件描述符造成的

  • 数据库延迟
  • Memcached 延迟
  • 应用程序 CPU 使用率
  • PostgreSQL 和 Memcached CPU 使用率
  • 连接池大小
  • 内存使用情况

如果你有优化方案,欢迎查看视频描述中的源代码链接
我原本期待 FastAPI 的性能更好,希望有人能优化它。

如果你对 Rust vs Go 等其他基准测试感兴趣,可以查看我的频道。

谢谢观看,我们下次见!

相关推荐
yzx991013几秒前
Gensim 是一个专为 Python 设计的开源库
开发语言·python·开源
麻雀无能为力18 分钟前
python自学笔记2 数据类型
开发语言·笔记·python
Ndmzi22 分钟前
matlab与python问题解析
python·matlab
懒大王爱吃狼28 分钟前
怎么使用python进行PostgreSQL 数据库连接?
数据库·python·postgresql
猫猫村晨总29 分钟前
网络爬虫学习之httpx的使用
爬虫·python·httpx
web1508541593530 分钟前
Python线性回归:从理论到实践的完整指南
python·机器学习·线性回归
ayiya_Oese32 分钟前
[训练和优化] 3. 模型优化
人工智能·python·深度学习·神经网络·机器学习
抽风的雨61036 分钟前
【python基础知识】Day 27 函数专题2:装饰器
开发语言·python
漫谈网络3 小时前
Python logging模块使用指南
python·logging·日志
言之。3 小时前
Python3 简易DNS服务器实现
python·dns