Kona JDK 在騰訊大數據領域內的實踐與發展

  • 2020 年 1 月 20 日
  • 筆記

導語 | 近日,雲+社區技術沙龍「騰訊開源技術」圓滿落幕。本次沙龍邀請了多位騰訊技術專家,深度揭秘了騰訊開源項目TencentOS tiny、TubeMQ、Kona JDK、TARS以及MedicalNet。本文是楊曉峰老師關於騰訊基於OpenJDK的自研Kona JDK開源項目的詳細介紹。

一、Tencent Kona 緣起

1. OpenJDK

經常聽人談到 OpenJDK,那它到底是什麼呢?相信大家都聽說過 Java SE、ME、EE等規範, 通常意義上對 Open JDK 的定義指:Java SE規範的一個免費和開源參考實現。

最早在2006年時,Sun承諾逐步開源核心 Java Platform,包括hotspot、Complier和類庫等;第二年,Redhat加入,並發佈IcedTea,也就是完全基於GNU自由軟件構建的版本。

2010年時發生了一個非常大的變化,Oracle從Sun手中接過Stewardship,IBM加入並放棄Apache Harmony,Apple也加入OpenJDK。

2014年,JDK 8發佈,它是迄今為止採納速度最快和接受程度最高的版本,至今仍是生產環境的主力。業界今年的調查統計顯示, JDK8 仍然是幾乎所有廠商最主要的生產版本JDK。

2017年,經過三年的研發,JAVA 9發佈了,這一年發生了一系列令人目不暇接的變化。

首先,從技術層面, JDK引入了原生的模塊化系統,也就是 Jigsaw 項目 – JPMS(Java Platform Module System),JPMS為未來Java語言和JDK快速發展驅除了一些障礙,但是也帶來了一些兼容性的問題,JDK 9並未像預期一般成為JDK 8的廣泛替代者。

其次,Java從特性驅動轉變為時間驅動的發佈模式。這是由於雲計算等領域的快速發展,給Java帶來了非常大的挑戰。

傳統的發佈模式,理想情況下大概以兩年為一個發佈周期,但是我們在實際的JDK 9開發中,又拖了一年左右,即使是這樣仍然有一些計劃的工作沒有做完。

長開發周期導致大量已經就緒的技術,遲遲不能進入生產階段,大大降低了Java發展和迭代的速度。為了適應這個變化,JDK切換為以半年為周期的新發佈模式。

第三,Oracle JDK開源商業特性,並且變更Oracle JDK收費策略,大大縮短了JDK免費支持周期。

令人欣慰的是,雖然Java經歷了「收費」風波,事實上,今天 OpenJDK 社區的活躍度和參與度都大大提高了。騰訊、微軟等廠商都加入了社區,並且開始積極貢獻OpenJDK。

2. Oracle JDK

Oracle JDK和OpenJDK之間是什麼關係呢?簡單做個對比,Oracle JDK 8可以認為是OpenJDK的一個超集,包含了其自身的商業特性。

但發展到JDK11之後,整個JDK的產品形態發生了一個很大的變化,從一個大的單體應用,作了一定的解耦,JMC、OpenJFX等以軟件包的形式獨立於JDK之外,Oracle也將其商業特性都開源了出來,所以Oracle JDK 11和OpenJDK 11僅存在License的不同。

3. Tencent Kona JDK

Tencent Kona JDK是基於OpenJDK主分支開發的JDK發行版,並堅持下面幾個基本原則。

第一,它是免費的,大家可以放心使用。

第二,我們會針對JDK8、JDK11這樣的LTS版本,提供長期、可靠的支持。

第三, Kona JDK經過騰訊海量的負載驗證,確保生產環境就緒的能力。

那麼,Tencent Kona 和Open JDK之間是什麼關係?有哪些優勢和發展思路呢?

首先,我們承諾Kona是一個「friend-Fork」,並會最大化地保證Kona兼容性。Kona團隊與大量內部JDK使用者和合作夥伴團隊等進行了廣泛溝通,提供高標準的兼容性和穩定性、可靠性、性能。

Kona JDK不會為了創新而創新,因為傷害JDK兼容性其實是對企業技術投資的不負責任,也會給使用者帶來未來的生產遷移和維護成本。

另外,基於騰訊海量的大數據、雲等各種Java/JVM負載,我們會將如此規模場景下的實踐心得和技術沉澱分享出來,並逐步以Bugfix、Enhancement或者是Feature的形式開源給大家使用。

從社區參與的角度,我們已經與Open JDK社區和Oracle Java產品團隊作了溝通,並且整個社區溝通郵件中明確了上面的原則,嚴格按照社區的治理標準來要求自己,不做食利者。

二、OpenJDK技術趨勢

回到OpenJDK本身,現在有哪些值得關注的主要趨勢呢?

在這裡引用John Rose(Oracle JVM Architect)的總結。

1. Java-on-Java

Java-on-Java,指的是以Java語言開發JVM虛擬機。

例如,目前C1/C2 JIT(Just-In-Time)編譯器,主要是用C++開發的,代碼已經非常難以改進,Oracle在GraalVM等項目中,逐步實踐了基於Java的JVM虛擬機,其技術將逐步成為未來JVM的核心。

目前總體還處於實驗性階段,但是已經表現出非常可觀的成果。例如,利用其native-machine和SubstrateVM,在啟動速度和內存Footprint等方面能夠有非常突破性的提高,甚至簡單程序可以看到30倍的改進。

雖然這是基於Close-World-Assumption,對Java的動態特性有所取捨,廣泛實踐仍存在距離,但未來可期。

2. 償還Java語言或者JVM設計實現的一些欠賬

Java設計中,除了原始數據類型,其他都是對象。對象頭、多態支持等開銷明顯,而這些對於數據(Data),往往是一種overhead,而不是數據本身的需求。

於此同時,複雜的引用關係帶來着內存布局上的複雜性,難以充分利用現代CPU的緩存結構。Java語言也難以高效、優雅地表達部分複雜數據結構和范型等,這些問題將在Valhalla等項目中得到解決。

3. Java語法的改變

Java的語法在Amber/Valhalla等項目中逐步演進,提高了代碼開發的效率和代碼質量。比如JAVA 10中提供的本地變量類型推斷,通過上下文推斷簡化代碼編寫,提高代碼可讀性。後續正在預覽階段的Switch Expression等,通過expression代替statements,大大提高語言表達能力,提高開發效率和良好實踐。

4. 操作硬件層次能力提升

OpenJDK 可以更快、更直接地去操作硬件層次,主要是用於Panama等項目開發中。例如為大數據、機器學習提供算力的支持,提供更好的本地代碼交互能力、向量計算能力等等。

當然,還有提高並發編程和運行效率的Project Loom,引入Fiber/Continuation,解決目前Java並發開發/運行效率問題。還有廣受期待的Pauseless GC等等,總的來說JVM正變得更加智能、高效。

三、大數據領域實踐與發展

大家知道,主流大數據技術棧,要麼是基於Java,要麼是運行在JVM之上。Java和JVM提供的易用的語法、跨平台能力、廣泛的工具、類庫等等,讓JVM成為大數據領域的無冕之王,目前來看幾乎沒有同等競爭對手。

但是,當我們真正開發維護超大規模集群、處理海量數據的時候,JVM就逐漸有些局限性了。

例如,在主流的Hadoop技術棧,NM等節點的堆大小直接影響到集群和數據規模,GC穩定性又與SLA密切相關,目前JVM在大堆GC方面,還遠不算完美,需要進一步改進。

從大數據負載特點來看,經典GC算法存在一定程度的水土不服。我們知道目前的年代等設計,本就是基於一個實踐經驗「大部分對象較小並且生命短暫「,但是,在Spark SQL等大數據負載,經常可以見到大量的長生命周期大對象甚至超大對象分配。

大對象分配和初始化成本高昂,而且在G1 GC等基於Region的設計中,達到或者超過Region 50%大小的對象會佔據一個或多個分區,剩餘空間則被浪費掉,這一點限制着寶貴的內存資源利用效率。

從大數據的業務特點來看,JVM機制也需要針對性修正和提高。例如,相當於一步大數據業務都是定時的離線計算,在一天中的不同時間段,應用行為變化較大,而目前JVM的自適應特性發生水土不服並不鮮見, G1 GC預測引擎連續預測失敗導致的GC長暫停,有時會傷害SLA,針對性改進必不可少。

因為上面的種種局限,很多大數據框架,不得不費力去操作堆外,帶來了研發和運維的效率問題。

我們在生產實踐中注意到,大數據應用中JNI進入臨界區,GC Locker觸發頻繁的無意義Young GC與大對象分配合力,會導致JVM意外OOM,這個問題在大數據場景比較頻繁,具體可以參考下圖。

另外,不管是大數據還是機器學習,終歸脫離不了一個核心,也就是算力。

大數據依賴於機器(集群)、線程(多核)和指令(SIMD)三種層次的數據並行計算。大概是2002年以後, CPU Core的頻率已經基本上沒有明顯上升,甚至有所下降,生產負載擴展性越來越依賴於堆CPU、堆機器。分佈式集群和多線程必不可少,但JVM層面在指令級別的優化尚未得到充分重視,充分利用指令並行能力是算力的保障之一。

JVM向量化/SIMD通常有三種手段

第一,JNI直接使用native代碼,但因為CPU的多變等原因而非常難以開發和維護。

第二,自己開發JVM Intrinsic,這對普通開發者來說並不不現實

第三,利用JVM提供的Auto-Vectorization能力,是比較可行的。

但是Auto-Vectorization能力局限性也很多,目前僅在C2提供 SupperWord Optimization,依賴於Counted Loop的Loop Unrolling,開發有難度且比較脆弱。

目前,OpenJDK孵化中的Vector API能夠大大提高開發效率,進而提高性能,未來我們將積極推動其發展和成熟。

在大數據場景診斷和調優方面,Kona內部集成的Java Flight Recorder(Oracle開源)提供了生產環境可用的全棧JVM Profiling能力,並且提供了可以不用Heap Dump診斷memory leak的可能,這對於海量分佈式集群、頻繁大堆/超大堆的大數據場景,非常有幫助。

也有助於我們進一步整體理解大數據負載的通用開銷,比如序列化/反序列化、內存(對象)分配等等。

我們會與社區一起增強jmap等SVC工具,優化通用開銷,並向社區回饋和分享我們的經驗。

四、Q&A

Q:楊老師,我想問一下騰訊雲現在做Open JDK和Kona JDK有什麼區別?做這個有什麼優勢呢?

A:Kona JDK是基於Open JDK主分支,基於海量的微服務、Serverless、大數據等實際應用場景的需求與痛點進行改進,目標定位於提供在相應場景的最佳Java運行環境和解決方案。

Kona JDK會盡量upstream特性,讓Java生態的收益最大化,並且在特性選取上,充分考慮兼容性、成熟度和生產價值,強調為用戶帶來實實在在的效率和生產力。如果確實有個別特性或bug fix,不符合upstream到主分支的通用性標準、工作思路等,但只要存在較大的生產意義,Kona可能仍會選擇提供。

我認為,從Java生態健康的角度,Kona JDK的意義和目的都不在於區別,而在於長期、可靠的支持,加速OpenJDK新特性生產化速度,增強數據科學、雲計算等領域的Java基礎實力。

 講師介紹

楊曉峰,騰訊高級技術專家,中國計算機協會(CCF)系統軟件專委委員,目前負責TEG JDK團隊、OpenJDK Committer。曾領導 Oracle Java Platform 北京核心類庫團隊、京東數據基礎平台智能化系統研發團隊等,出品專欄《Java核心技術36講》,聚焦於Java/JVM等基礎軟件在大數據、雲計算等前沿領域的演進和實踐。