当前位置:首页 > 科技  > 软件

理解Go、容器以及Linux调度器

来源: 责编: 时间:2023-12-18 09:46:08 354观看
导读Go开发的应用程序通常部署在容器中。在容器中运行时,重要的一点是要设置CPU限制以确保容器不会耗光主机上的所有CPU。但Go运行时不知道容器上设置的CPU限制,因此有可能会把所有可用的CPU都用光,从而造成应用延迟很高。这

Go开发的应用程序通常部署在容器中。在容器中运行时,重要的一点是要设置CPU限制以确保容器不会耗光主机上的所有CPU。但Go运行时不知道容器上设置的CPU限制,因此有可能会把所有可用的CPU都用光,从而造成应用延迟很高。这个问题曾经困扰过我,在这篇文章中,我将解释发生了什么以及如何修复。F1b28资讯网——每日最新资讯28at.com

F1b28资讯网——每日最新资讯28at.com

Go垃圾收集器是如何工作的

这是对Go垃圾收集器(GC)的概要介绍,想要更深入了解,建议阅读Go文档[2]以及Will Kennedy的系列文章[3]。F1b28资讯网——每日最新资讯28at.com

绝大多数情况下,Go运行时在执行程序的同时执行垃圾收集,这意味着GC会与程序同时运行。然而,在GC过程中有两个点需要Go运行时暂停所有Goroutine,从而确保数据完整性。在GC标记阶段(Mark Phase)之前,运行时将暂停所有Goroutine,用以启用写屏障(write barrier),确保在此之后创建的任何对象都不会被GC,这个阶段称为扫描终止(Sweep Termination)。在标记阶段完成后,还有一个STW(stop the world)阶段,被称为标记终止(Mark Termination),并且也是删除写屏障的过程。整个流程通常需要几十微秒。F1b28资讯网——每日最新资讯28at.com

我创建了一个简单的web应用,分配了大量内存,并使用以下命令在一个限制为4个CPU核的容器中运行,源代码在Github[4]上。F1b28资讯网——每日最新资讯28at.com

docker run --cpus=4 -p 8080:8080 $(ko build -L main.go)

值得注意的是,docker CPU限制是硬性限制。可以设置--CPU-shares,表示只在主机CPU受限时强制执行。这意味着如果主机有空闲容量,容器可以使用超出分配的CPU核。但是如果主机资源受限,那么应用程序也将受到限制。F1b28资讯网——每日最新资讯28at.com

可以使用runtime/trace[5]包收集trace,然后用go tool trace对其进行分析。下面的trace显示了在我的机器上捕获的一个GC周期,可以看到在Proc 5中STW阶段的扫描终止和标记终止。F1b28资讯网——每日最新资讯28at.com

F1b28资讯网——每日最新资讯28at.com

这个GC周期只花了不到2.5ms,但我们在STW阶段花费了近10%的时间。这是相当长的一段时间,特别是对于延迟敏感应用来说。F1b28资讯网——每日最新资讯28at.com

Linux调度器

完全公平调度程序(Complete Fair Scheduler, CFS)[6]是在Linux 2.6.23中引入的,在2023年10月份发布的Linux 6.6之前一直是默认调度程序,很可能你正在使用CFS。F1b28资讯网——每日最新资讯28at.com

CFS是一个比例共享调度器[7],意味着进程权重与允许使用的CPU内核数量成正比。例如,如果允许一个进程使用4个CPU核,那么它的权重将为4。如果一个进程被允许使用2个CPU核心,它的权重将为2。F1b28资讯网——每日最新资讯28at.com

CFS通过分配一小部分CPU时间来实现,一个4核系统每秒钟有4秒的CPU时间可以分配。当我们为容器分配多个CPU内核时,实际上是要求Linux调度器给它n个CPU的时间。F1b28资讯网——每日最新资讯28at.com

在上面的docker run命令中,指定了4个CPU,意味着容器每秒将获得4秒的CPU时间。F1b28资讯网——每日最新资讯28at.com

问题

当Go运行时启动时,为每个CPU内核创建一个操作系统线程。这意味着如果有一个16核的机器,Go运行时将创建16个操作系统线程,不管任何CGroup CPU限制。然后Go运行时使用这些操作系统线程来调度程序。F1b28资讯网——每日最新资讯28at.com

问题是Go运行时不知道CGroup的CPU限制,而是在所有16个操作系统线程上调度goroutine,意味着Go运行时预计每秒能够使用16秒的CPU时间。F1b28资讯网——每日最新资讯28at.com

由于Go运行时需要在等待Linux调度器调度的线程上停止gooutine,因此将面临长时间的STW时间,因为一旦容器使用超过了CPU配额,线程就不会被调度。F1b28资讯网——每日最新资讯28at.com

解决方案

Go通过设置GOMAXPROCS环境变量限制运行时将创建的CPU线程数量。这一次,使用以下命令来启动容器:F1b28资讯网——每日最新资讯28at.com

docker run --cpus=4 -e GOMAXPROCS=4 -p 8080:8080 $(ko build -L main.go)

下面是从与上面相同的应用程序捕获的trace,现在使用与CPU配额匹配的GOMAXPROCS环境变量。F1b28资讯网——每日最新资讯28at.com

F1b28资讯网——每日最新资讯28at.com

在这个trace中,尽管负载完全相同,但垃圾收集时间要短得多。GC周期小于1ms,STW时间为26μs,约为无限制时的1/10。F1b28资讯网——每日最新资讯28at.com

GOMAXPROCS应该设置为容器允许使用的CPU核数,通常情况应该向下取整,如果分配的CPU内核少于1个,则向上取整。可以用GOMAXPROCS=max(1, floor(cpu))来计算。Uber开源了一个库automaxprocs[8]来自动从容器的cgroups中计算这个值。F1b28资讯网——每日最新资讯28at.com

有一个Github问题[9]支持将这个特性添加到Go运行时中,使其开箱即用,希望最终会被Go运行时接受!F1b28资讯网——每日最新资讯28at.com

结论

在容器化应用程序中运行Go时,设置CPU限制非常重要。通过设置合理的GOMAXPROCS值或使用像automaxprocs这样的库,确保Go运行时意识到这些限制也很重要。F1b28资讯网——每日最新资讯28at.com

参考资料

[1]Go, Containers, and the Linux Scheduler: https://www.riverphillips.dev/blog/go-cfsF1b28资讯网——每日最新资讯28at.com

[2]Go文档: https://tip.golang.org/doc/gc-guideF1b28资讯网——每日最新资讯28at.com

[3]Garbage Collection In Go: https://www.ardanlabs.com/blog/2018/12/garbage-collection-in-go-part1-semantics.htmlF1b28资讯网——每日最新资讯28at.com

[4]示例代码: https://github.com/RiverPhillips/go-cfs-blogF1b28资讯网——每日最新资讯28at.com

[5]runtime/trace package: https://golang.org/pkg/runtime/traceF1b28资讯网——每日最新资讯28at.com

[6]完全公平调度程序(Complete Fair Scheduler, CFS): https://docs.kernel.org/scheduler/sched-design-CFS.htmlF1b28资讯网——每日最新资讯28at.com

[7]Proportional share scheduling: https://en.wikipedia.org/wiki/Proportional_share_schedulingF1b28资讯网——每日最新资讯28at.com

[8]automaxprocs: https://github.com/uber-go/automaxprocsF1b28资讯网——每日最新资讯28at.com

[9]Github问题: https://github.com/golang/go/issues/33803F1b28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-48340-0.html理解Go、容器以及Linux调度器

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 浅析 Preact Signals 及实现原理

下一篇: C++17中的if和switch语句初始化

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • 企业采用CRM系统的11个好处

    客户关系管理(CRM)软件可以为企业提供很多的好处,从客户保留到提高生产力。  CRM软件用于企业收集客户互动,以改善客户体验和满意度。  CRM软件市场规模如今超过580
  • 一文掌握 Golang 模糊测试(Fuzz Testing)

    模糊测试(Fuzz Testing)模糊测试(Fuzz Testing)是通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。可以用来发现应用程序、操作系统和网络协议等中的漏洞或
  • 2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的“头腾
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 认真聊聊东方甄选:如何告别低垂的果实

    来源:山核桃作者:财经无忌爆火一年后,俞敏洪和他的东方甄选依旧是颇受外界关心的“网红”。7月5日至9日,为期5天的东方甄选“甘肃行”首次在自有App内直播,
  • 小米MIX Fold 3配置细节曝光:搭载领先版骁龙8 Gen2+罕见5倍长焦

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 华为举行春季智慧办公新品发布会 首次推出电子墨水屏平板

    北京时间2月27日晚,华为在巴塞罗那举行春季智慧办公新品发布会,在海外市场推出之前已经在中国市场上市的笔记本、平板、激光打印机等办公产品,并首次推出搭载
Top