本内容是对知名性能评测博主 Anton Putra Go (Golang) vs Python Performance Benchmark (Kubernetes - OpenTelemetry - Prometheus - S3/Postgres) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准
在本视频中,我们将比较 Golang 和 Python 的性能。
但我们不会采用纯粹的算法方法,而是使用真实场景的例子。我们将构建两个简单的 REST 应用程序,不使用像 Fiber 这样的最快库,而是使用当前最流行的库。其他在代码中使用的库也是如此,无论是官方库,比如 Prometheus 客户端,还是最受欢迎的第三方库。
接下来,我们将比较每个应用程序的 CPU 使用情况,然后比较内存使用情况。最重要的是,我们将比较每个请求的延迟,并从客户端侧进行测量,这比仅仅对应用程序进行监测更准确。我们将在两个测试中分别测量每秒请求数。
在第二个测试中,我们将测量 Python 和 Golang 从 S3 存储桶中下载一张图片所花费的时间。最后,我们将测量将最后修改日期存储到 Postgres 数据库中所需的平均延迟。
此外,我还将向您展示如何使用 OpenTelemetry 对 Python 和 Golang 应用进行监控,并在本地通过 Grafana 可视化追踪信息,无需使用任何外部服务。

例如,从这个追踪信息中你可以看到,整个请求大约耗时 7 毫秒,其中有 5 毫秒用于从 S3 下载图片,1.5 毫秒用于将图片元数据存储到 Postgres 数据库中。Python 应用也有相同的追踪可显示。
源代码已发布在我的 GitHub 公共仓库中。我将在下一期视频中做一个逐步教程,演示如何使用 OpenTelemetry 项目对 Python 应用进行追踪并暴露指标。
为了运行这些测试,我使用了一个拥有 8 核处理器和 64GB 内存的 VMware。我使用 kubeadm 工具安装了最新版的 Kubernetes,并额外创建了一个专用 VM 用于 Postgres 数据库。所有这些虚拟机都有 2 个虚拟 CPU 和 4GB 内存,除了 Postgres,它有 4 个 CPU 和 8GB 内存。

现在,我来解释一下测试配置。
在第一个测试中,我们会将这两个应用部署到 Kubernetes 中。为了运行测试,我们将使用一个客户端应用,它将作为 Kubernetes Job 部署,用于生成流量。
首先,我们将使用 /api/devices
端点,它返回一个硬编码的设备数组。因此,第一个测试将纯粹比较 Python Flask 应用和 Golang Gin 应用。
然后,每个客户端都在 /metrics
端点暴露 Prometheus 指标,我们将使用 Prometheus 来抓取它们的数据。通过这些数据,我们可以在 Grafana 仪表盘中可视化请求时长。

我们将使用 summary 类型的 Prometheus 指标来自动生成百分位数指标。
顺便提醒一下,如果您的应用是水平扩展的,您无法跨实例聚合 summary 类型的指标,这种情况下需要使用带有硬编码桶的 histogram 类型。
在第二个测试中,我们将使用相同的应用,但使用的是 /api/images
端点。当客户端访问该端点时,每个应用将从 S3 存储桶中下载一张图片。我将使用 MinIO,它是一个兼容 S3 的对象存储系统。
应用下载图片后,将提取其最后修改日期,并将其保存在 Postgres 数据库中。
在这个示例中,我们还将从应用本身暴露用于测量 S3 和 Postgres 请求延迟的指标。
此外,我们会使用 OpenTelemetry 创建追踪数据,并通过 OTLP 协议将其导出到同样部署在 Kubernetes 中的 Tempo。然后我们将使用 Grafana 中的数据源 Tempo 来查询追踪数据。

这就是本视频的整个配置过程。
为了部署所有这些开源组件,如 Grafana、Prometheus、Tempo 和 MinIO,我使用了 Terraform 结合 Helm 和 kubectl 提供器。

你也可以在 GitHub 仓库中找到 Golang 应用、Python 应用和客户端。视频中用到的所有内容都包含在该仓库中,我还会在 README 文件中添加一些命令。
好了,我们开始运行第一个测试。
我们将逐渐增加请求数量,直到每个应用达到大约每秒 400 个请求。
一开始你就可以注意到,Python 应用的内存使用明显更高。

顺便说一下,我对两个应用设置了相同的请求和限制:512MB 内存和 2 个核心的限制。

同样的情况也出现在 CPU 使用上,Python Flask 应用使用了更多的 CPU。
但最重要的是,Python 的延迟几乎是 Golang 应用的 4 倍,Python 大约是 4 到 5 毫秒,而 Golang 是 1 毫秒左右。

提醒一下,这些测试都是在同一台服务器上运行的,因此请求中没有网络延迟。
好了,我将这个测试再运行几秒钟。整个测试大约花了 20 分钟。
接下来,我会停止客户端并重置 Prometheus。
接下来运行第二个测试,我们将从 S3 下载图片并将数据存储到 Postgres。
在这个测试中,我只向每个应用发送大约 20 个并发请求。
你可以看到内存使用基本不变。CPU 使用在这样的低负载下也差不多。
但我们从客户端侧测得的总延迟,Python 依然明显更高,大约为 20 到 25 毫秒,而 Golang 为 10 到 12 毫秒。

你还可以注意到,S3 下载函数的平均延迟差不多,但将数据保存到数据库的时间几乎少了一半。
我也会将这个测试再运行几秒钟。
现在,用 Python 开发应用更加容易,尤其是在你需要快速创建一个概念验证项目时。你完全可以使用 Python。
Python 广泛用于大数据和机器学习领域,如果这是你的使用场景,你当然继续使用 Python。
但如果你需要实现更低的延迟和更高的效率,尤其是服务端应用,Golang 会是更好的选择。
Rust 的效率更高,但它还未完全成熟,而且开发和维护都更困难。
如果你喜欢这类基准测试,我还有一个播放列表,比较不同语言和开源项目。