我的应用该选择什么样的内存大小?

我的应用,是应该运行在比较少的大内存实例(即:机器)上,还是比较多的小内存实例上呢?哪一种策略才是最优解决方案?这个问题可能大家经常遇到。在积累了 20 年的应用程序开发经验后,在构建了 JVM 性能工程/故障排除工具(GCeasyFastThreadHeapHero)后,我仍然不知道这个问题的正确答案。与此同时,我也相信这个问题没有什么非此即彼的选择。在本文中,我将分享自己对于这一主题的看法以及一些经验。

两家市值数十亿美元的公司的故事

因为我们的 JVM 性能工程/故障排除工具已得到了各大企业的广泛应用,所以我有机会亲眼目睹世界级企业应用程序的实际实现过程。最近,我很荣幸地观察了两家飞速成长的技术公司(各位读者一定都不陌生)。这两家公司的总部都位于硅谷。他们的业务都与技术有关,所以对于软件工程十分熟悉的。他们也都深受华尔街的青睐,估值都很不错。他们的市值都高达数十亿美元。他们是现代蓬勃发展的企业的典范。在本文中,我将用公司 A 和公司 B 来分别称呼他们。

这两家公司在内存大小方面采用了两种*截然相反*的方式,这给了我带来了极大的惊喜。公司 A 将其堆内存大小(即:-Xmx)设置为了 250 GB,公司 B 则将堆内存大小设置为 2 GB。也就是说,公司 A 的堆内存大小是公司 B 的 125 倍。两家公司对于自己的内存大小设置都很有信心。老话说得好:“实践是检验真理的唯一标准”,而这两家企业又都需要处理数十亿的业务关键交易。

这两家公司都在从事着相同的业务,或多或少也有着相同的收入/市值,且位于同一地理区域,还在同一时间点采取了两种极端不同的内存大小策略。那么从这样的真实例子来看,正确的答案是什么呢?大内存还是小内存?我的结论是:如果您的团队成员十分可靠的话,那么任意一种策略都是可行的。

大内存的成本可能会比较高

大内存、少实例(即:机器)一般会比小内存、多实例的方案要贵一些。下面是一些以及美国东部地区(北弗吉尼亚) AWS EC2 实例进行的简单计算:

m4.16xlarge – 256GB 内存 – Linux 按需实例成本:$3.2/小时

T3a small – 2GB 内存 – Linux 按需实例成本:$0.0188/小时

所以,如果想要拥有 256GM 内存,我们就需要 128 个“T3a small”实例(即:128 个实例 x 2GB = 256GB)。

128 x T3a small – 2GB 内存 – Linux 按需实例成本:$2.4064/小时(即:128 x $0.0188/小时)

这意味着大内存少实例的方案,要比小内存多实例的方案成本高 $0.793/小时(即:$3.2 – $2.4064)。也就是说,大内存少实例的方案要 33%

当然,也可以提出相反的观点:如果机器数量较少,那么所需的工程师就较少,耗电量和机房大小也会较小。服务器的补丁、升级工作可能也会更简单。

业务需求

在某些情况下,业务本身的性质决定了应用程序的内存大小。比如这样的一个现实情形:在构建 HeapHero(堆内存转储文件分析工具)时,我们工具的内存就必须大于其所解析的堆内存转储文件。假设堆内存转储文件的大小是 100GB,那么 HeapHero 的工具内存就必须大于 100GB。这一点是无法妥协的。

假设您需要缓存大量数据(比如:200GB)才能实现应用程序性能的最大化,那么内存的大小就必须超过 200GB。这一点也是无法妥协的。因此在某些情况下,业务需求将决定您的内存大小。

性能与故障排除

如果内存比较大,那么通常而言垃圾回收停顿的时间也就越长。垃圾回收是应用程序中运行的一个进程,用于清理内存中的未引用对象。内存很大,内存中的垃圾量也不会小。所以清理垃圾所花费的时间也会比较长。垃圾回收运行时程序会出现停顿。但这一问题也有解决方案:

  • 使用无停顿 JVM(如“Azul”)
  • 进行适当的 GC 调优来降低停顿时间

类似的,如果您需要解决任何内存问题,就需要捕获程序的堆内存转储文件。堆内存转储文件中包含与程序内存相关的一切信息,例如其中有哪些对象、各对象的引用状况如何、各个对象所占据的内存大小等等…大内存程序的堆内存转储文件会比较大。对大转储文件进行分析也会比较有难度。即使是世界最优秀的堆内存转储文件工具(如:Eclipse MATHeapHero)也会在解析 100GB 的转储文件时遇到一些困难。对于此类转储文件,在测试环境中复现其中的问题、存储和分享转储文件都是不小的挑战。

情感第一,理性第二

在阅读了 Jonah Lehrer 的著作《我们如何决定》(How we decide)等书之后,我相信经验和情感会在决定应用程序内存大小的过程中扮演关键角色。之前我曾经在一家大型金融机构工作。这家机构的首席架构师建议我们以非常大的内存运行 JVM,他给出的理由是:“我们之前用过内存很大的大型主机”。

结论

如果您在规模很大的公司工作,那么有 99.99% 的几率您决定不了程序的内存大小。因为这些决定已经由那些端坐象牙塔之中的“精英和半神”决定了。他们所作出的决定或许很难改变。

但如果您能够去做出这样的决定,那在这一过程中您也很可能会收到过往经验以及自身情感的影响 :)。但无论如何,只要团队成员靠谱,内存怎么选都没关系(大内存少实例,和小内存多实例,都行)。

视频

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: