本內容是對知名性能評測博主 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 的效率更高,但它還未完全成熟,而且開發和維護都更困難。
如果你喜歡這類基準測試,我還有一個播放列表,比較不同語言和開源項目。