带有 TB RAM 的 go 1.5 gc 有多快? [英] How fast is the go 1.5 gc with terabytes of RAM?

查看:24
本文介绍了带有 TB RAM 的 go 1.5 gc 有多快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 无法使用 TB 的 RAM,因为 GC 暂停时间太长(几分钟).随着最近对 Go GC 的更新,我想知道它的 GC 暂停是否足够短,可以用于大量 RAM,例如几 TB.

目前有这方面的基准吗?我们现在可以使用具有这么多 RAM 的垃圾收集语言吗?

解决方案

tl;dr:

  • 目前,您无法在单个 Go 进程中使用 TB 的 RAM.Linux 上的最大容量为 512 GB,而我所见测​​试的最大容量为 240 GB.
  • 在当前的后台 GC 下,GC 工作量往往比 GC暂停更重要.
  • 您可以将 GC 工作负载理解为 指针 * 分配率/备用 RAM.在使用大量 RAM 的应用程序中,只有那些指针少或分配少的应用程序的 GC 工作量才会低.
<小时>

我同意 inf 的评论,即大堆值得向其他人询问(或测试).JimB 指出,Go 堆目前的硬限制为 512 GB,而 18 240 GB 是我所见过的最大测试.

我们从

运行几个最初有大约 300 毫秒暂停的生产应用程序的人报告下降到

在 1.5 下有 20 毫秒暂停时间的同一应用在 1.6 下有 3-4 毫秒暂停,大约8GB 堆和 150M 分配/分钟.

使用 Go 作为聊天服务的 Twitch 报告说 通过 Go 1.7 的暂停时间已减少到 1 毫秒,有很多正在运行的 goroutines.

1.8 使堆栈扫描脱离了 stop-the-world 阶段,即使在大堆上,大多数暂停都在 1 毫秒以下.早期数字看起来不错.有时应用程序仍然具有使 goroutine 难以暂停的代码模式,从而有效地延长了所有其他线程的暂停时间,但通常可以公平地说 GC 的后台工作现在通常比 GC 重要得多 暂停.

<小时>

关于垃圾收集的一些一般性观察,不特定于 Go:

换个说法,如果应用程序访问大量内存,如果它只有几个指针(例如,它处理相对较少的大 []byte 缓冲区)并且收集发生的次数较少,它可能仍然没有 GC 问题通常在分配率较低的情况下(例如,因为您应用 sync.Pool 以在您最快速地咀嚼 RAM 的任何地方重用内存).

因此,如果您正在查看涉及数百 GB 堆的东西,而这些堆对 GC 不友好,我建议您考虑任何一个

  1. 用 C 或类似语言编写
  2. 将大量数据移出对象图.例如,您可以管理嵌入式数据库中的数据,如 bolt,将它在外部数据库服务中,或者使用类似 groupcache 或 memcache 如果你需要更多的缓存而不是数据库
  3. 运行一组较小的堆而不是一个大的进程
  4. 只需仔细进行原型设计、测试和优化以避免内存问题.

Java cannot use terabytes of RAM because the GC pause is way too long (minutes). With the recent update to the Go GC, I'm wondering if its GC pauses are short enough for use with huge amounts of RAM, such as a couple of terabytes.

Are there any benchmarks of this yet? Can we use a garbage-collected language with this much RAM now?

解决方案

tl;dr:

  • You can't use TBs of RAM with a single Go process right now. Max is 512 GB on Linux, and most that I've seen tested is 240 GB.
  • With the current background GC, GC workload tends to be more important than GC pauses.
  • You can understand GC workload as pointers * allocation rate / spare RAM. Of apps using tons of RAM, only those with few pointers or little allocation will have a low GC workload.

I agree with inf's comment that huge heaps are worth asking other folks about (or testing). JimB notes that Go heaps have a hard limit of 512 GB right now, and 18 240 GB is the most I've seen tested.

Some things we know about huge heaps, from the design document and the GopherCon 2015 slides:

  • The 1.5 collector doesn't aim to cut GC work, just cut pauses by working in the background.
  • Your code is paused while the GC scans pointers on the stack and in globals.
  • The 1.5 GC has a short pause on a GC benchmark with a roughly 18GB heap, as shown by the rightmost yellow dot along the bottom of this graph from the GopherCon talk:

Folks running a couple production apps that initially had about 300ms pauses reported drops to ~4ms and ~20ms. Another app reported their 95th percentile GC time went from 279ms to ~10ms.

Go 1.6 added polish and pushed some of the remaining work to the background. As a result, tests with heaps up to a bit over 200GB still saw a max pause time of 20ms, as shown in a slide in an early 2016 State of Go talk:

The same application that had 20ms pause times under 1.5 had 3-4ms pauses under 1.6, with about an 8GB heap and 150M allocations/minute.

Twitch, who use Go for their chat service, reported that by Go 1.7 pause times had been reduced to 1ms with lots of running goroutines.

1.8 took stack scanning out of the stop-the-world phase, bringing most pauses well under 1ms, even on large heaps. Early numbers look good. Occasionally applications still have code patterns that make a goroutine hard to pause, effectively lengthening the pause for all other threads, but generally it's fair to say the GC's background work is now usually much more important than GC pauses.


Some general observations on garbage collection, not specific to Go:

Rephrased, an application accessing lots of memory might still not have a GC problem if it only has a few pointers (e.g., it handles relatively few large []byte buffers), and collections happen less often if the allocation rate is low (e.g., because you applied sync.Pool to reuse memory wherever you were chewing through RAM most quickly).

So if you're looking at something involving heaps of hundreds of GB that's not naturally GC-friendly, I'd suggest you consider any of

  1. writing in C or such
  2. moving the bulky data out of the object graph. For example, you could manage data in an embedded DB like bolt, put it in an outside DB service, or use something like groupcache or memcache if you want more of a cache than a DB
  3. running a set of smaller-heap'd processes instead of one big one
  4. just carefully prototyping, testing, and optimizing to avoid memory issues.

这篇关于带有 TB RAM 的 go 1.5 gc 有多快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆