GraalVM在Facebook的实战

793 阅读5分钟

翻译自medium.com/graalvm/gra…

Facebook正在使用GraalVM来加速其Spark的工作负载,并减少内存和CPU的使用。请继续阅读,了解它们的迁移故事、性能改进结果和未来计划。

image.png

Facebook背后的技术

拥有28亿月活跃用户的Facebook是世界上访问量最大的平台之一。为了保证在这种负载下的可靠性和高性能,工程团队采用了多种技术,包括Java、JavaScript、Flow Hack、PHP、Python、c++等。

Facebook在一些关键领域使用了Java,如大数据(Spark、Presto等)、后端服务和移动设备。在迁移到GraalVM之前,该团队在Java 8和Java 11上使用了Oracle JDK和OpenJDK。

在这种规模下,任何性能改进都会带来显著的价值——它们改善了用户体验并降低了基础设施成本。这就是为什么工程团队一直在寻找改进应用程序性能的方法,并决定评估GraalVM,以确定它是否是一个更快的Java运行时。

为什么是GraalVM

  • 由于性能是一个主要考虑因素,Facebook团队决定评估GraalVM作为他们的Java运行环境,看看它是否会提高他们的Java应用程序的性能。GraalVM提供了高级优化,比如部分转义分析和内联启发式。多亏了这一点,许多Java/JVM应用程序只要切换到GraalVM,就能立即获得性能提升。Facebook团队还观察到,与C2相比,GraalVM在SpecJVM2008和DaCapo等基准测试中显示出了显著的年进步。
  • 此外,GraalVM编译器是以模块化和可扩展的方式使用Java从头开始编写的。这使得维护变得很容易,同时还增加了增量改进。这对Facebook来说很重要,因为该团队正在考虑对GraalVM进行长期投资。
  • 社区。GraalVM项目拥有一个充满活力的开源社区,许多组织和个人都为该项目做出了贡献,并形成了它的路线图。在社区中也很容易找到帮助和支持。

在GraalVM上运行Java和Spark

Facebook团队使用了GraalVM社区作为OpenJDK的替代品。在这个场景中,迁移到GraalVM非常简单——只需要切换运行环境,不需要更改应用程序代码。这种转换使得应用程序运行得更快,这得益于GraalVM的高级性能优化,无需任何手动调优。

Apache Spark是一个统一的大数据处理分析引擎,内置流、SQL、机器学习和图形处理模块。它处理数据的速度非常快,但许多团队正在寻找进一步优化其性能的方法。最简单的方法之一是在GraalVM上运行Spark工作负载。多亏了一组特定的编译器优化(我们稍后将详细讨论),GraalVM可以显著加快Spark的工作负载。Renaissance基准测试套件的Apache Spark基准测试显示,社区的平均加速速度为1.1倍,企业的平均加速速度为1.42倍,有些基准测试的速度高达4.84倍。

image.png

对于Facebook来说,Spark是其数据仓库中最大的SQL查询引擎,运行在聚合计算存储集群上。由于数据量巨大,效率和成本的降低是当务之急。

他们从2020年初开始进行评估。由于最初的基准测试显示了良好的结果,团队将gralvm推向了生产,并一直监控其性能和可靠性。

image.pngimage.png

在性能方面,他们观察到CPU使用减少了约10%,而且自推出以来,CPU的减少一直保持一致。

GraalVM如何加速Spark工作负载

对Spark性能提升贡献最大的一些优化是:

  • 多态内联。只有当编译器能够确定方法调用的目标方法时,传统内联才能工作。GraalVM通过收集额外的分析信息(允许也内联抽象方法),使内联超越了这一点。
  • 部分逸出分析。部分转义分析的思想是通过在对象没有转义的分支中执行标量替换来删除不必要的对象分配,并确保对象存在于必须转义的分支中的堆中。这既减少了应用程序的内存占用,又减少了GC引起的CPU负载。这种优化在Spark这样的数据密集型应用程序中更加重要。特别是,根据Facebook的观察,GraalVM在java/lang/Double.valueOf等方法中减少了5倍的CPU消耗。
  • GraalVM中的高级推测性优化通过利用动态运行时反馈产生更快的机器码。通过推测程序的某些部分不会在程序执行期间运行,GraalVM编译器能够专门化代码并使其更高效。对于Spark,通过消除分支(如长if-then-else链)、简化控制流、减少循环体中的动态检查数量以及建立别名约束,这种优化工作得特别好,从而实现进一步的优化。

根据评估结果,Facebook团队将大部分cpu密集型的大数据服务迁移到了GraalVM。他们还观察到,在切换到GraalVM后,Presto的>5%的CPU和GC暂停时间提高了。接下来,该团队计划将GraalVM推到其他内存绑定服务,以从escape分析优化中获益。该团队还计划为项目和社区做出贡献。

他们还在探索使用其他gralvm特性的机会,如Native Image和Truffle Framework。

结论

多亏了高级编译器优化,GraalVM可以显著加快许多Java和Scala工作负载。特别是,通过将GraalVM转换为JDK发行版,Spark的工作负载有望提高10%-42%。

有趣的是,另一个流行的社交媒体平台Twitter的工程师也分享了类似的旅程和观察结果。在将Scala的工作负载转移到GraalVM之后,他们观察到显著的性能改进,例如,多亏了GraalVM编译器,P99延迟降低了19.9%。对于像Twitter或Facebook这样的平台,这种性能改进会随着平台规模的扩大而进一步扩大。

要开始在您的应用程序中使用GraalVM,请访问graalvm.org/docs/getting-started/。

最近开始了自己的开源项目 itwanger/JavaLearnSource: LearnJava在线学习网站的开源代码 (github.com) 欢迎大家start