跳轉到主要內容
工程的博客

Apache項目鎢:將引發更接近裸金屬

2015年4月28日 工程的博客

分享這篇文章

在之前的博客調查,我們回頭和性能改進Apache火花在過去的一年。在這篇文章中,我們期待著與你們分享下一章,我們調用項目鎢。2014年見證了火花設置世界紀錄在大型排序和看到重大改進整個引擎從Python SQL機器學習。然而,性能優化,是一個永無止境的過程。

項目會以來的最大變化引發的執行引擎項目的《盜夢空間》。它關注大幅提高效率內存和CPU火花的應用程序,推動現代硬件性能接近的極限。這種努力包括三個項目:

  1. 內存管理和二進製處理:利用應用程序語義顯式地管理內存和消除JVM對象模型和垃圾收集的開銷
  2. 支持緩存計算:算法和數據結構,利用內存層次結構
  3. 代碼生成:使用代碼生成利用現代編譯器和cpu

專注於CPU效率是出於這一事實引發工作負載越來越瓶頸的CPU和內存使用,而不是IO和網絡通信。這一趨勢顯示最近的研究在大數據的工作負載的性能(Ousterhout等)我們到了類似的發現我們正在進行調優和優化的努力的一部分磚雲beplay体育app下载地址客戶。

為什麼新CPU瓶頸?這有很多原因。一個是硬件配置提供總IO帶寬越來越大,如10 gbps鏈接網絡和高帶寬SSD或條紋硬盤陣列的存儲。從軟件的角度來看,火花的優化器現在允許許多工作負載,避免重大的磁盤IO修剪不需要輸入數據,在給定的工作。在火花的洗牌子係統、序列化和散列(CPU綁定)已被證明是關鍵的瓶頸,而不是原始的底層硬件的網絡吞吐量。所有這些趨勢意味著火花今天是經常受到CPU和內存壓力而不是IO效率。

1。內存管理和二進製處理

應用程序在JVM上通常依賴於JVM的垃圾收集器來管理內存。JVM是一個令人印象深刻的工程壯舉,作為一般設計為許多工作負載運行時。然而,當火花應用程序性能的邊界,JVM對象和GC變得不小的開銷。

Java對象有很多固有的內存開銷。考慮一個簡單的字符串“abcd”,需要4個字節來存儲使用utf - 8編碼。JVM的原生字符串實現,然而,這種不同的商店促進更常見的工作負載。每個字符用2字節進行編碼utf - 16編碼,並且每個字符串對象還包含一個12字節的頭和8字節散列碼,如以下輸出所示Java對象的布局工具。

. lang。字符串對象內部:抵消類型描述值大小04(對象標題)…44(對象標題)…84(對象標題)…124char []字符串value []164int字符串.hash020.4int字符串.hash320實例大小:24字節(由儀表API報道)

一個簡單的4字節字符串在JVM中變得共48字節對象模型!

JVM對象模型的另一個問題是垃圾收集的開銷。在高級別上,分代垃圾收集的對象分為兩類:那些有高速率分配/回收(年輕一代)的保持在(舊一代)。年輕一代的垃圾收集器利用瞬態自然對象來有效地管理它們。這是當GC可以可靠地估計對象的生命周期,但低於如果估計(即一些瞬態對象泄漏到年老代)。因為這種方法最終是基於啟發式和估計,唷性能要求的“黑魔法”GC調優,許多參數給JVM更多關於對象的生命周期的信息。

火花,然而,不僅僅是一個通用的應用程序。火花理解如何通過不同階段的數據流計算和工作的範圍和任務。因此,引發更多的信息比JVM垃圾收集器了解內存塊的生命周期,因此應該能夠更有效地管理內存比JVM。

處理對象的開銷和GC的效率低下,我們引入一個顯式的內存管理器將大多數火花操作操作直接對二進製數據,而不是Java對象。這建立在sun.misc.UnsafeJVM提供的高級功能,使c風格的內存訪問(例如明確的分配、回收、指針算法)。此外,不安全的方法內在,這意味著每個方法調用由JIT編譯成一條機器指令。

在某些地區,火花已經開始使用顯式地管理內存。去年,磚貢獻了一個新的Netty-based網絡傳輸,顯式地管理所有網絡緩衝區使用jemalloc像內存管理器。關鍵在擴大引發的洗牌操作和贏得基準。

第一件會出現在火花1.4中,其中包括一個哈希表,操作直接對二進製數據與記憶明確由火花。與標準的JavaHashMap,這個新的實現更間接開銷和垃圾收集器是無形的。

屏幕截圖2015-04-27 6.08.39點

這仍然是半成品,但最初的性能結果令人鼓舞。如上所示,我們比較的吞吐量聚合操作使用不同的散列映射:一堆我們的新散列映射的模式,與offheap, java.util.HashMap。新的哈希表支持每秒100萬聚合操作在一個線程,2 x java.util.HashMap的吞吐量。沒有任何參數調優,更重要的是,它幾乎沒有性能下降隨著內存利用率增加,雖然最終JVM默認一個抽搐由於GC。

在火花1.4中,將使用這個散列映射為聚合DataFrames和SQL,並在1.5,我們將準備好數據結構對於大多數其他操作,如排序和連接。在很多情況下這將消除需要調整GC實現高績效。

2。支持緩存計算

在我們支持緩存解釋計算之前,讓我們重新審視“內存”計算。引發廣泛的被稱為一個內存中的計算引擎。這個詞到底是什麼意思,火花可以利用內存資源集群上有效地處理數據的速度遠高於基於磁盤的解決方案。然而,火花也可以處理數據訂單大小大於可用內存,透明地溢出到磁盤並執行外部排序和散列等操作。

同樣,支持緩存計算提高了數據處理的速度通過更有效地利用L1 / L2和L3 CPU緩存,因為它們是數量級的速度比主存。剖析引發用戶應用程序時,我們發現大部分的CPU時間等待獲取數據從主內存。作為項目鎢的一部分,我們正在設計緩存友好算法和數據結構,所以引發應用程序將花費更少的時間等待取回數據從內存和更多的時間做有用的工作。

考慮排序的記錄作為一個例子。標準排序程序將存儲數組的指針記錄和使用快速排序交換指針,直到所有的記錄進行排序。分類一般有很好的緩存訪問率由於順序掃描訪問模式。排序的列表指針,然而,有一個貧窮的緩存命中率,因為每個比較操作需要非關聯化兩個指針指向隨機位置記錄在內存中。

那麼我們如何提高緩存的位置排序?一個非常簡單的方法來存儲每個記錄的排序關鍵字並排的指針。例如,如果排序鍵是一個64位整數,然後我們使用128位(64位指針和64位的密鑰)來存儲指針數組中的每個記錄。這樣,每一個快速排序比較操作隻查找pointer-key對以線性方式並且不需要隨機內存查找。希望上麵的說明給你一些想法關於我們如何重新設計基本操作,以實現更高的緩存位置。

這適用於火花呢?大多數分布式數據處理可以歸結為一個小列表的操作如聚合、排序和連接。通過改善這些操作的效率,我們可以提高引發效率的應用程序作為一個整體。我們已經建立了一個支持緩存版本的那種,比之前的版本快3倍。這個新類將用於事洗牌,高基數聚合、分類合並連接操作符。到今年年底,大多數火花的算法支持緩存將被升級的最低水平,增加所有應用程序的效率從機器學習SQL。

3所示。代碼生成

大約一年前火花表達式求值的代碼生成在SQL和DataFrames。表達式求值的過程是計算一個表達式的值(說“年齡> 35歲& &”)在一個特定的記錄。在運行時,火花動態生成字節碼來評估這些表達式,而不是為每一行步進通過較慢的翻譯。與解釋相比,代碼生成減少原始數據類型的拳擊,更重要的是,避免了昂貴的多態函數分派

在一個早些時候博客,我們證明了代碼生成可以加速很多TPC-DS查詢近一個數量級。我們現在擴大代碼生成覆蓋大多數內置的表達式。此外,我們計劃增加代碼生成的水平record-at-a-time表達式求值,矢量化表達式求值,利用JIT的能力更好地利用現代cpu指令流水線所以我們可以處理多個記錄。

我們也無法表達評估領域的應用代碼生成優化CPU內部組件的效率。一個領域,我們非常興奮應用代碼生成是加速數據從內存中二進製格式的轉換為洗牌連接協議。如前所述,洗牌通常是由數據序列化,而不是底層的網絡瓶頸。代碼生成,我們可以增加序列化的吞吐量,進而增加洗牌網絡吞吐量。

上麵的圖對比800萬年洗牌的性能複雜的行生成一個線程使用Kryo序列化器和代碼自定義序列化器。序列化器利用生成的代碼中所有行的一個洗牌的事實有相同的模式和生成專門的代碼。這使得生成的版本快/ 2倍比Kryo版本洗牌。

鎢和超越

項目鎢是一個寬泛的倡議,將影響火花的核心引擎的設計在未來幾個版本。第一塊土地在火花1.4中,其中包括顯式地管理內存聚合操作在火花DataFrame API以及定製的序列化器。覆蓋了二進製支持緩存內存管理和數據結構將出現在1.5火花。項目利用鎢DataFrame模型的幾個部分。我們還將改造盡可能改進到火花的抽樣API。

也有少數長期鎢的可能性。特別是,我們計劃調查編譯LLVM或OpenCL,所以應用程序可以利用SSE /火花SIMD指令的現代的cpu和gpu加速的寬並行操作在機器學習和圖像計算。

火花的目標一直是提供一個平台,用戶可以得到最好的分布式算法的數據處理任務。Beplay体育安卓版本性能是一個關鍵的目標的一部分,和項目旨在讓火花鎢金屬裸提供的應用程序的運行速度。請繼續關注長期的磚的博客文章的組件項目鎢作為他們的船。

  • 注意:手繪圖的靈感來自我們的朋友在支流(Martin Kleppmann)
免費試著磚

相關的帖子

看到所有工程的博客的帖子
Baidu
map