Golang Go语言中约束 GOMAXPROCS 带来的收益

发布于 1周前 作者 phonegap100 来自 Go语言

最近看了一遍 runtime ,去尝试了之前遗留的一个工作:调整 k8s 中容器的 GOMAXPROCS ,效果还不错。

在 11:35 左右, 我们将应用的 GOMAXPROCS 从默认的 32/64 主动设置为 4, 对比 14:30 和 11:30 的数据可以看到:

  • go version: 1.17
  • 线程数量从 49 下降到 13, 符合预期
  • 受业务影响, QPS +13%
  • 接口平均响应时间 -9%, CPU -5%
  • GC 的耗时 -59%, STW(StopTheWorld) 的时间 -12%
  • goroutine 在 Runnable 停留的时间 +50%

gomaxprocs_heavy_gc.png


Golang Go语言中约束 GOMAXPROCS 带来的收益

更多关于Golang Go语言中约束 GOMAXPROCS 带来的收益的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

24 回复

那就需要分析一下原因了
降低并发度之后反而提高了处理能力,说明并发的时候内耗比较大?

更多关于Golang Go语言中约束 GOMAXPROCS 带来的收益的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


说明当前场景下并发调度开销比较大?

可以细说一下主要啥类型的业务么🧐

你这是 k8s 吧,golang 这种不应该是一个进程吃满的吗,又不是 python 那种

go scheduler 调度的成本,和 os thread 上下文切换的成本

是容器运行吗?
runtime.NumCPU()和容器的核数是否一致?

k8s node 上还有其他 pod 吧,都想吃满机器 ,肯定有反效果

典型的 web 服务呗

pod 是坑定有的,吃满不至于,我们一般是控制实际使用率在 40%以内,突然的情况下会到 60%

要压榨单机性能最好就别用 k8s (:

个人实践,丢在 k8s 上的东西都是无状态的应用,开了自动扩缩容其他的就不需要操心了。
对于有状态或者需要压榨单机性能的,例如数据库都不在 k8s 内。

另,试着升下版本,GOGC 和 GOMEMLIMIT 还能对程序有进一步的提升。

自然,但是资源能节约要节约,成本核算都是 OKR

CI/CD 里面直接注入环境变量也行,可控性更高

针对 Docker 运行 Go 确实有取宿主机的 CPU 来设置 MAXPROCS.
当使用 Pod 限制资源的配置时,就不建议手动去调整 MAXPROCS , 这样做不好运维,所以可以选择 Uber 的一个库


https://github.com/uber-go/automaxprocs

这库的原理就是取读取 容器里 /sys/fs/cgroup/cpu 里面的值,然后计算出一个合理的 MAXPROCS
在你 main 函数执行之前通过 import 这个过程去初始化 MAXPROCS

你是站在业务开发的角度来看

嗯,k8s 里面进程数是要手动设置下,除非单 pod ,不然 pod 自动扩展物理机进程数 X^n 上升

物理机和 k8s 还是有很多细微的差别要处理

一直还没去关注,k8s/vm 分配 cpu 时间片的时候会不会主动尽量将单个 pod 聚集到某个 物理 c 上

物理 C 是物理 node 还是物理 cpu core ,前者可以用 statefulset 、node selector 和 affility 处理,后者 k8s 没有这个能力也不应该有这个能力

真实的、物理的 CPU
情理上我也觉得 k8s 没有这个能力,但是 resources limit 也在 pod spec 中,所以可能还是可以揣测下

没配置对,uber 有个库就可以根据 limit 去设置 maxprocs ,jvm 也有相识的内置参数。

op 这用的是什么监控呢?

prometheus+grafana

在Go语言中,GOMAXPROCS 是一个用于设置程序运行时可以同时使用的逻辑处理器(Logical Processor,即OS线程)数量的环境变量或运行时参数。正确约束 GOMAXPROCS 可以带来多方面的收益:

  1. 性能优化:通过合理设置 GOMAXPROCS,可以确保Go程序充分利用多核CPU资源,提高并发执行效率。对于CPU密集型任务,适当增加 GOMAXPROCS 可以显著提升性能;对于IO密集型任务,则可能需要根据具体情况调整,以避免过度竞争CPU资源。

  2. 资源控制:在资源受限的环境中,如容器化部署或云环境中,合理设置 GOMAXPROCS 可以避免程序过度占用系统资源,从而确保系统的稳定性和其他应用的正常运行。

  3. 能耗管理:在移动设备或低功耗服务器上运行Go程序时,通过限制 GOMAXPROCS 可以降低CPU使用率,减少能耗,延长设备续航时间或提高系统能效。

  4. 简化调试:在调试并发问题时,通过减少 GOMAXPROCS 的值,可以简化问题的复现和排查过程,有助于开发者更清晰地理解程序的并发行为。

需要注意的是,GOMAXPROCS 的设置应根据具体应用场景和系统环境进行调整,以达到最佳的性能和资源利用率。在大多数情况下,Go语言的运行时系统会根据系统资源自动进行一定程度的优化,但手动调整 GOMAXPROCS 仍然是一个有效的性能调优手段。

回到顶部