看看你的Go應用是否用了正確CPU核數(shù)
Go 的調(diào)度模型
Go 的調(diào)度模型是 GMP,其中 G 是 goroutine,M 是線程,P 是可用的 CPU 核數(shù)。多個 G 會共用一個 M。M 作為操作系統(tǒng)層面上的調(diào)度單位,在執(zhí)行時需要綁定到 P。如果操作系統(tǒng)認為的某個 Go 進程可用的 CPU 數(shù),和該進程認為的可用的 CPU 數(shù)不一致,那么即使把 M 綁定到某個 P 上,操作系統(tǒng)也不一定會執(zhí)行這個線程。所以能否獲取準確的可用 CPU 核數(shù)會影響 Go 的調(diào)度效率。
k8s 設置資源限制
當用戶在 k8s 中設置了資源限制:
spec: containers: - name: app_written_by_go resources: limits: cpu: "4"
Go 會不會識別到可用的 CPU 為 4 呢?讀者可能會認為,Go 作為一個云原生時代炙手可熱的語言,應該內(nèi)置了對 k8s 的支持,所以能夠識別出來。但事實并非如此。
小實驗
如果啟動 Go 進程時沒有指定 GOMAXPROCS 環(huán)境變量,那么會以 runtime.NumCPU()
的輸出作為可用的 CPU 核數(shù)(也即 P 的值)。讓我們加一下打印 NumCPU 的代碼,會發(fā)現(xiàn)實際上輸出的是 Node 上的 CPU 數(shù)目,跟 limits.cpu
無關。
runtime.NumCPU()
在 Linux 上是通過系統(tǒng)調(diào)用 sched_getaffinity
實現(xiàn)的,但這個系統(tǒng)調(diào)用只考慮綁定 CPU 核的情況,不涉及容器環(huán)境下 cgroup 對 CPU 資源的限制。以 docker 為例,docker run 時指定 --cpuset-cpus
可以設置容器運行時可以使用的 CPU 核的編號,但限制 CPU 的資源數(shù)主要用 --cpus=
。只有前者(cpuset)是能被 sched_getaffinity
識別的。
具體見 https://docs.docker.com/config/containers/resource_constraint...。如果要想計算后者,那么需要讀取機器上的 cgroup fs 文件。
有一個 Go 庫支持讀取 cgroup fs 并計算出準確的 GOMAXPROCS:
https://github.com/uber-go/automaxprocs它支持兩種不同的 cgroup fs (cgroup v1 和 v2):
其中 v1 是讀取文件 cpu.cfs_quota_us
和 cpu.cfs_period_us
,并求兩者的商。這兩個文件通常位于 /sys/fs/cgroup/cpu/ 下面(automaxprocs 會讀掛載信息來獲取實際位置)。
v2 則是讀取文件 cpu.max
里面對應表示 quota 和 period 的字段,并求兩者的商。除法的結(jié)果不一定是整數(shù),所以還有一個向下取整的過程。
存在“應該能夠識別可用 CPU 數(shù)但在容器環(huán)境下實際辦不到”這種問題的并不只有 Go 一個。Nginx / Envoy 也有無法識別 cgroup 配置的問題。據(jù)說 Rust 和 Java (OpenJDK 實現(xiàn))有專門處理過 cgroup 配置。如果你的應用符合下面兩點:
- 計算密集型或主要業(yè)務邏輯在若干個固定的 worker 中完成
- 會部署到容器環(huán)境中
那么不妨看看所用的框架是否能正確處理 cgroup 配置。
附注:IBM 的員工曾經(jīng)提過一個 CPU Namespace 的設計,封裝每個進程可以看得到的 CPU 信息,避免諸如 CPU 分配不一致這樣的“抽象泄漏”。不過后續(xù)就沒有下文了。
以上就是看看你的Go應用真的用了正確的CPU核數(shù)嗎的詳細內(nèi)容,更多關于Go應用CPU核數(shù)的資料請關注腳本之家其它相關文章!
相關文章
Golang使用DuckDB查詢Parquet文件數(shù)據(jù)的操作代碼
本文介紹DuckDB查詢Parquet文件的典型應用場景,掌握DuckDB會讓你的產(chǎn)品分析能力更強,相反系統(tǒng)運營成本相對較低,為了示例完整,我也提供了如何使用Python導出MongoDB數(shù)據(jù),需要的朋友可以參考下2025-01-01golang中struct和[]byte的相互轉(zhuǎn)換示例
這篇文章主要介紹了golang中struct和[]byte的相互轉(zhuǎn)換示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07