前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Kona CodeRevive:高性能JIT缓存方案及在腾讯大数据应用

Kona CodeRevive:高性能JIT缓存方案及在腾讯大数据应用

作者头像
腾讯大数据
发布2025-02-05 11:03:40
发布2025-02-05 11:03:40
1241
举报
文章被收录于专栏:腾讯大数据的专栏

| 导语 Kona JDK是经过腾讯大规模生产实践验证的JDK发行版本,并且提供长期稳定的支持,CodeRevive是Kona JDK针对大数据实际应用中Just-In-Time(JIT)编译开销进行优化的新特性。通过在线的缓存和聚合JIT编译的结果,大幅度减少腾讯大数据现网JIT编译的开销并且提升整体吞吐量。

Kona JDK介绍

Tencent Kona JDK( TencentKona-8/11/17/21)是经过腾讯大规模生产实践验证的JDK发行版本,提供稳定、高性能、包含前沿特性的版本,并且提供长期稳定的支持,支持主流的操作系统和硬件。在新特性方面,KonaFiber是兼容Java原生Loom协程的Kona JDK方案,在JDK8/11生产版本上可以使用JDK21发布的特性[4],KonaSM是Kona JDK自带的高性能国密Java实现,实现了从基础算法簇,到公钥基础设施(PKI),再到安全通信协议的全链路国密特性[5]。在安全方面,团队联合腾讯安全实验室进行定期扫描、漏洞的挖掘和修复,在2021年发现和修复了当前CVE评分最高的Java漏洞,也是国内首次提交Java CVE[2][3]。团队成员包括两名OpenJDK社区reviewer以及多名commiter和author,在OpenJDK社区贡献长期位居全球第五,国内第一[1]。

大数据JIT编译开销&Kona CodeRevive

Just-In-Time(JIT即时编译)使Java程序拥有较高的计算效率和运行速度[6],通过动态收集的运行时信息,编译效果可以持平甚至超过静态编译。但其运行时编译对资源消耗和需要一定时间预热才能达到峰值性能的问题一直被诟病,当应用执行时间足够长时(例如后台服务),冷启动问题相对会不明显,但与之相对,在短任务场景中,这个弊端就尤为突出。大数据离线计算是典型的短时任务场景。

Java生态已有一些针对JIT开销和冷启动的优化,这些方案主要针对某个硬件上单一的应用、服务,在大数据离线场景应用面临很大的挑战。例如没有考虑大数据平台对Java特性使用的广泛性(用到各种动态特性)、任务可能会调度到不同硬件上执行;上图列举了一些大数据离线计算的实际复杂情况;下表列举了Java在JIT开销和冷启动上的一些典型的方案、实现以及它们在大数据领域应用遇到的问题;

Kona CodeRevive借鉴了一部分业界方案思想,采用保存JIT编译的结果并复用解决JIT编译的开销问题,并且加入了创新的方案解决前面提到业界方案的不足,主要包括:

  1. 通过检查保存和复用时刻Java Class的一致性(包括字节码、依赖类等信息),保证了对各种Java动态特性支持和通用性;
  2. JIT编译时额外记录编译优化的信息,在恢复时基于当前的Profiling信息重新评估优化效果,确保恢复版本的高性能;
  3. 聚合多个进程JIT编译结果,并对相近的结果进行合并,提高了编译结果复用的有效性;

Kona CodeRevive方案在业界主流大数据Benchmark以及腾讯实际应用中的效果,基本可以减少80%以上的JIT编译的CPU开销。

Kona CodeRevive方案介绍

CodeRevive基于JIT编译结果本地保存与复用的思想。如下图在第一次执行的时候加入java命令行参数 -XX:+CodeReviveOptions=save,file=xxx.csa参数,JIT编译的结果会被保存到相应的csa文件(Code Shareing Archive),csa文件除了包含JIT编译的binary,还额外记录代码恢复信息,主要恢复metadata的地址(类、函数),JVM中的数据结构(Java堆的起始地址、内部函数的地址)等。在后续执行中加入java命令行参数-XX:+CodeReviveOptions=restore,file=xxx.csa,在触发JIT编译的时候会尝试先从csa文件中加载匹配的binary,达成复用的效果,减少JIT编译消耗的CPU资源。当前CodeRevive仅针对C2编译进行了保存和复用,因为C2编译开销占了总体编译开销的90%[9];

与业界方案相比Kona CodeRevive添加了合并多次保存结果的方案以支持真实大数据现网的多版本、不同运行参数、负载特征区别大等问题;添加了Class校验信息,支持Java的动态类修改等各种特性,以及能够支持大数据现网不同版本的平台、业务jar包和合法性验证;添加优化校验信息,帮助在复用时找到性能最优的版本进行复用;后续会对这两方面进行详细地介绍。

下面展开介绍相关的技术点:

平衡开销和收益,JIT编译结果聚合

针对大数据业务通常存在多个版本、任务参数配置复杂、机型不同等问题,Kona CodeRevive采取了在单台服务器上保存本地JIT编译结果,聚合后本地再复用的方案:

  1. 添加参数-XX:CodeReviveOptions=save,file=xxx.csa,percent=1,可以控制现网1%的Java进程保存JIT编译的结果,减少在收集阶段对于现网任务的影响;
  2. 收集之后运行java -XX:CodeReviveOptions=merge,input_list_file=yyy,coverage=90,file=merged.csa将多个csa合并一个大的csa;如下图所示,合并的结果会包含多个Container,每个Container里面的Binary都有兼容的JVM参数,例如不同GC算法下的Binary在不同的Container中,压缩和非压缩指针等;每个Method会按需保存多个版本,以保证热点版本都会保存,例如在1000个csa文件中,foo函数出现800次,对这些版本进行合并到最热的8个版本进行保留,以保证复用的生效概率;整个合并过程会满足合并后的文件大小的限制;
  3. 在后续复用过程中,JVM会根据当前运行参数选择匹配的Container,在container中找到对应的函数,遍历所有的版本找到收益最高的版本进行复用,后续会介绍如何评估收益最高的版本;

合法性、通用性保证,Java动态特性支持

复用JIT编译的二进制代码,首先要保证编译时的所有的类和复用时的一致(包括引用使用的类、以及相关的父类、接口),如果存在差异,复用就可能有行为差异导致正确性问题。业界方案通常会使用基于classpath和jar包的检查,保证前后两次执行classpath和jar包一致,那么其中引用的类肯定一致,这种方式在实际大数据业务中使用会有很大的限制:

  1. 大数据每个任务都有classpath,jar包差异:每个任务的app.jar不同,classpath在不同机器上都可能因为存储差异而不同;
  2. 大数据现网有一些安全、增强功能的agent会打开JVMTI Class Redefine/Transform的功能,启动时classpath检查会失效;

Kona CodeRevive基于此提出了适合大数据现网的类一致性检查方法,不依赖classpath同时支持动态类修改:

  1. 每一个类、接口都会记录一个基于CRC计算的Identity,包其含父类、接口的Identity以及自身的内容;保存编译结果时会记录Java Class对应的Identity,在复用前检查当前同名类的Identity是否和保存时一致;
  2. 使用Epoch记录Identity的计算时刻,当有类动态修改更新全局的Epoch;类的Identity按需计算,检查Epoch判断是否需要重新计算;如下图所示,首先计算Foo的Identity会计算所有父类、接口的Identity并记录Epoch为1;然后当SuperFoo类被动态修改,SuperFoo以及其父类会重新计算Identity并更新Epoch到2,但Foo本身不更新;最后Foo再次读取Identity时在重新计算并更新Epoch到2;

高性能保证,恢复时JIT binary性能评估

前期保存的版本可能在后续使用时可能会不适用,主要问题包括:

  1. JIT编译会使用大量当前运行时采样的信息,做激进的基于假设的优化[7],例如在编译时一个方法没有被重载,那么虚函数调用可以替换成直接的函数调用(Devirtual优化);如果后续加载了新的类方法被重载了,JVM会取消掉原有的JIT编译结果保证正确性;希望在恢复代码的时就能判断保存的版本是否适用当前的JVM状态(类加载、Profiling信息);
  2. 存在多个可用版本,怎么选择最优的版本进行复用;

为了解决上述问题Kona CodeRevive在常见的复用恢复信息外额外记录了所有基于Profiling的优化动作,用于复用版本时估算编译优化收益,在保存时将优化信息写入下图中csa文件的优化校验信息部分。例如Devritual优化会记录直接跳转函数对应的类标识符,下图中在编译时概率最大两个类时c和d,且如果出现其它类会走slow path;Unstable If优化会记录编译时这个branch永远不会taken,就可以省略编译if分支的内容,如果后续实际走到if分支那么整个JIT编译会失效。

在复用时将根据当前Profiling信息判断版本是否可用,例如当前Profiling中Unstable If对应的taken概率不为0,实际会走到,那么就不能复用这个版本,反之则可以。判断Devirtual收益的时候会根据当前Profiling中实际执行函数的类,计算节省的虚函数调用的代价;最终合并所有优化的收益效果,选择没有失效且收益最大的版本进行恢复;

大数据BenchMark测试

HiBench[8]是常用的大数据基准套件,可以帮助评测不同大数据平台的性能、吞吐量和系统资源利用率,包含一组Hadoop、Spark的测试。因为聚焦测试JIT编译的影响,选择了单机standalone的模式进行测试(128线程256G内存,HiBench huge规模下测试),主要步骤包括

  1. 所有java任务配置参数-XX:CodeReviveOptions=save,file=xxx%p.csa;
  2. 聚合所有产生的csa文件;
  3. 所有java任务配置参数-XX:CodeReviveOptions=restore,file=merged.csa;

从测试表现看Kona CodeRevive对几乎所有测试用例都有比较好的提升效果。Hadoop任务普遍有10%-35%的性能提升,因为Hadoop任务每个task一个Java进程,JIT编译开销更大CodeRevive效果更好;Spark任务也普遍有提升但幅度在5%左右,有个别任务有性能下降,分析是关键函数复用的版本不如JIT编译优化效果好;

腾讯天穹大数据应用

在实际现网应用中随着线上业务版本的迭代、工作负载的变化,前期保存的JIT编译结果效果会逐渐降低。大数据任务可能会在不同集群迁移,任务特征不同会导致前期保存的JIT版本在新负载上效果不佳;如果Hadoop、spark、hive版本有升级,那么保存JIT编译结果就直接不匹配了。为了解决这些问题必须具备判断当前csa在现网应用效果的能力,以及及时更新csa的能力。

为了达成上面的目标,首先Kona JDK提供轻量统计CodeRevive效果的功能,添加Java参数-XX:CodeReviveOptions=perf,logfile=xxx.log 会在程序退出时打印Revive生效的比例。下图是日志示例,总共642次尝试C2JIT编译,其中559次命中了csa,命中率87%,12次复用失败是找不到保存的函数,71次复用没有成功是因为复用失败(类不匹配、Profiling信息判断不可用等)。

其次我们和腾讯大数据运维团队一起在线上部署了轻量级的有效性监测和重新采集生成csa的机制。每天大概会采集100个进程的上述有效性信息,判断整体的有效率;如果低于阈值,那么就会触发重新采集和聚合生成csa的流程。下图是一段时间内现网机器的CodeRevive有效率的监测,在有效率降低后能及时发现再更新csa重新提高了生效率。

未来展望

Java社区针对JIT编译开销降低,快速预热一直在持续投资,例如最新Leyden项目聚焦这个方向。Kona CodeRevive已经在腾讯大数据全量落地并取得明显的优化效果,后续主要有几个方向:

  1. 深入当前的实现:构建更精确的评估模型,提高优化效果评估的准确率;覆盖C1编译支持;
  2. 前沿版本的迁移:当前已经启动了Kona JDK17的迁移并已经跑通大部分功能;
  3. 更多场景的尝试:对启动时延、预热和通用性都有较高要求的后台服务、微服务等场景;

参考资料

[1] https://blogs.oracle.com/java/post/the-arrival-of-java-21

[2] https://www.oracle.com/security-alerts/cpujul2021.html

[3] https://nvd.nist.gov/vuln/detail/cve-2021-2388

[4] https://cloud.tencent.com/developer/article/2008086

[5] https://cloud.tencent.com/developer/article/2180713

[6] https://www.infoq.cn/article/openjdk-hotspot-what-the-jit

[7] https://cr.openjdk.org/~vlivanov/talks/2015_JIT_Overview.pdf

[8] https://github.com/Intel-bigdata/HiBench

[9] https://zhuanlan.zhihu.com/p/355304828

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯大数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大数据JIT编译开销&Kona CodeRevive
  • Kona CodeRevive方案介绍
    • 平衡开销和收益,JIT编译结果聚合
    • 合法性、通用性保证,Java动态特性支持
    • 高性能保证,恢复时JIT binary性能评估
  • 大数据BenchMark测试
  • 腾讯天穹大数据应用
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档