最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Hbase調(diào)優(yōu):HBase 調(diào)整 Java 垃圾收集算法

2023-05-30 15:08 作者:滌生大數(shù)據(jù)  | 我要投稿

? ?本文整理來自英特爾 Java 性能架構師 Eric Kaczmarek 探討了如何針對 100% YCSB 讀取調(diào)整 Apache HBase 的 Java 垃圾回收 (GC)

背景:企業(yè)Hbase GC時間長,造成Hbase請求超時

圖片

? ? ?Apache HBase是一個提供 NoSQL 數(shù)據(jù)存儲的 Apache 開源項目。HBase 通常與 HDFS 一起使用,在世界范圍內(nèi)被廣泛使用。知名用戶包括 Facebook、Twitter、Yahoo 等。從開發(fā)人員的角度來看,HBase 是一個“分布式、版本化、非關系型數(shù)據(jù)庫,仿照 Google 的 Bigtable,一個用于結(jié)構化數(shù)據(jù)的分布式存儲系統(tǒng)”。HBase 可以通過縱向擴展(即部署在更大的服務器上)或橫向擴展(即部署在更多服務器上)輕松處理非常高的吞吐量。

? ? 從用戶的角度來看,每個查詢的延遲非常重要。當我們與用戶一起測試、調(diào)整和優(yōu)化 HBase 工作負載時,我們現(xiàn)在遇到了很多真正想要 99% 操作延遲的人。這意味著從客戶端請求到返回客戶端的響應的往返行程,全部在 100 毫秒內(nèi)完成。

? ? ?有幾個因素會導致延遲的變化。最具破壞性和不可預測的延遲入侵者之一是 Java 虛擬機 (JVM) 的“stop the world”垃圾收集(內(nèi)存清理)暫停。

? ? 為了解決這個問題,我們使用 Oracle jdk7u21 和 jdk7u60 G1 (Garbage 1st) 收集器嘗試了一些實驗。我們使用的服務器系統(tǒng)基于具有超線程(40 個邏輯處理器)的 Intel Xeon Ivy-bridge EP 處理器。它有 256GB DDR3-1600 RAM 和三個 400GB SSD 作為本地存儲。這個小型設置包含一個主站和一個從站,配置在一個節(jié)點上,負載適當縮放。我們使用 HBase 版本 0.98.1 和本地文件系統(tǒng)來存儲 HFile。HBase測試表配置為4億行,大小為580GB。我們使用默認的 HBase 堆策略:40% 用于 blockcache,40% 用于 memstore。YCSB 用于驅(qū)動 600 個工作線程向 HBase 服務器發(fā)送請求

? ? ?以下圖表顯示 jdk7u21 使用.?我們指定了要使用的垃圾收集器、堆大小和所需的垃圾收集 (GC)“停止世界”暫停時間。-XX:+UseG1GC?-Xms100g?-Xmx100g?-XX:MaxGCPauseMillis=100

圖片

在這種情況下,我們遇到了劇烈波動的 GC 暫停。在初始峰值達到 17.5 秒后,GC 暫停的范圍從 7 毫秒到 5 整秒。下圖顯示了穩(wěn)態(tài)期間的更多詳細信息:

圖片

圖 2 告訴我們 GC 暫停實際上分為三個不同的組:(1) 在 1 到 1.5 秒之間;(1) 在 1 到 1.5 秒之間;(2) 0.007秒至0.5秒之間;(3) 尖峰在 1.5 秒到 5 秒之間。這很奇怪,所以我們測試了最近發(fā)布的jdk7u60,看看數(shù)據(jù)是否有任何不同:

我們使用完全相同的 JVM 參數(shù)運行相同的 100% 讀取測試:.-XX:+UseG1GC?-Xms100g?-Xmx100g?-XX:MaxGCPauseMillis=100

圖片

? ???Jdk7u60 大大提高了 G1 在穩(wěn)定階段處理初始尖峰后的暫停時間尖峰的能力。Jdk7u60 在一小時的運行中產(chǎn)生了 1029 次年輕的和混合的 GC。GC 大約每 3.5 秒發(fā)生一次。Jdk7u21 進行了 286 次 GC,每次 GC 大約每 12.6 秒發(fā)生一次。Jdk7u60 能夠?qū)和r間控制在 0.302 到 1 秒之間,而沒有出現(xiàn)大的峰值。

下面的圖 4 讓我們更仔細地觀察了穩(wěn)定狀態(tài)下 150 次 GC 暫停:

圖片

在穩(wěn)定狀態(tài)下,jdk7u60 能夠?qū)⑵骄鶗和r間保持在 369 毫秒左右。比jdk7u21好很多,但是還是達不到我們給的100毫秒的要求Xx:MaxGCPauseMillis=100

為了確定我們還能做些什么來獲得 1 億秒的暫停時間,我們需要更多地了解 JVM 的內(nèi)存管理和 G1(垃圾優(yōu)先)垃圾收集器的行為。下圖顯示了 G1 如何進行 Young Gen 收集。

圖片

當 JVM 啟動時,根據(jù) JVM 啟動參數(shù),它要求操作系統(tǒng)分配一個大的連續(xù)內(nèi)存塊來托管 JVM 的堆。該內(nèi)存塊由 JVM 劃分為多個區(qū)域。

圖片

如圖 6 所示,Java 程序使用 Java API 分配的每個對象首先進入左側(cè)年輕代的 Eden 空間。一段時間后,Eden 變滿,觸發(fā)了 Young generation GC。仍然被引用(即“活著”)的對象被復制到 Survivor 空間。當對象在年輕代中存活了幾次 GC 后,它們就會被提升到老年代空間。當 Young GC 發(fā)生時,Java 應用程序的線程會停止,以便安全地標記和復制活動對象。這些停止是臭名昭著的“停止世界”GC 暫停,這使得應用程序在暫停結(jié)束之前沒有響應。

圖片

老一代也會變得擁擠。在某個級別(由默認為總堆的 45% 控制)會觸發(fā)混合 GC。它收集年輕一代和老一代。混合 GC 暫停由年輕代在混合 GC 發(fā)生時清理所需的時間控制。-XX:InitiatingHeapOccupancyPercent=?

所以我們可以在 G1 中看到,“停止世界”GC 暫停主要取決于 G1 標記和復制活動對象到 Eden 空間之外的速度。考慮到這一點,我們將分析 HBase 內(nèi)存分配模式將如何幫助我們調(diào)整 G1 GC 以獲得我們期望的 100 毫秒暫停。

在 HBase 中,有兩個內(nèi)存結(jié)構消耗了它的大部分堆:用于BlockCache讀取操作的緩存 HBase 文件塊,以及緩存最新更新的 Memstore。

圖片

新對象形成LruBlockCache,Memstore首先進入Young generation的Eden空間。如果它們存活的時間足夠長(即,如果它們沒有被逐出LruBlockCache或從 Memstore 中清除),那么在幾次 GC 之后,它們就會進入 Java 堆的老年代。當 Old generation 的可用空間小于給定threshOldInitiatingHeapOccupancyPercent開始)時,混合 GC 開始并清除 Old generation 中的一些死對象,從 Young gen 復制活動對象,并重新計算 Young gen 的 Eden 和 Old gen 的HeapOccupancyPercent.?最終,當HeapOccupancyPercent達到一定水平時,FULL GC會發(fā)生一個巨大的“停止世界” GC 暫停以清理 Old gen 中的所有死亡對象。

在研究了“”生成的 GC 日志之后,我們注意到在 HBase 100% 讀取期間,它從未增長到足以引發(fā)完整 GC 的程度。我們看到的 GC 暫停主要由年輕一代“停止世界”暫停和隨時間增加的引用處理所主導。-XX:+PrintGCDetails?-XX:+PrintGCTimeStamps?-XX:+PrintAdaptiveSizePolicyHeapOccupancyPercent

完成該分析后,我們對默認的 G1 GC 設置進行了三組更改:

  1. Use開啟該標志時,GC在Young和mixed GC時使用多線程處理不斷增加的引用。使用 HBase 的這個標志,GC 重新標記時間減少了 75%,整體 GC 暫停時間減少了 30%。-XX:+ParallelRefProcEnabled

  2. Set -XX:-ResizePLAB and -XX:ParallelGCThreads=8+(logical processors-8)(5/8)Promotion Local Allocation Buffers (PLAB) 在 Young 收集期間使用。使用了多個線程。每個線程可能需要在 Survivor 或 Old 空間中為正在復制的對象分配空間。PLAB 需要避免線程競爭管理空閑內(nèi)存的共享數(shù)據(jù)結(jié)構。每個 GC 線程都有一個 PLAB 用于 Survival 空間,一個用于 Old 空間。我們希望停止調(diào)整 PLAB 的大小,以避免 GC 線程之間的大量通信成本,以及每次 GC 期間的變化。我們希望將 GC 線程的數(shù)量固定為 8+(logical processors-8)( 5/8). 這個公式是 Oracle 最近推薦的。通過這兩個設置,我們能夠在運行期間看到更平滑的 GC 暫停。

  3. 將 100GB 堆的默認值從 5更改為 1 根據(jù) 的輸出,我們注意到 G1 未能滿足我們期望的 100GC 暫停時間的原因是處理 Eden 所花費的時間。換句話說,在我們的測試中,G1 平均需要 369 毫秒來清空 5GB 的 Eden。然后,我們使用標志將 Eden 大小從 5 降低到 1。通過此更改,我們看到 GC 暫停時間減少到 100 毫秒。-XX:G1NewSizePercent-XX:+PrintGCDetails and -XX:+PrintAdaptiveSizePolicy-XX:G1NewSizePercent=

    從這個實驗中,我們發(fā)現(xiàn) G1 清理 Eden 的速度約為每 100 毫秒 1GB,或者對于我們使用的 HBase 設置,每秒 10GB。

    基于該速度,我們可以設置Eden 大小可以保持在 1GB 左右。例如:-XX:G1NewSizePercent=

    • 32GB 堆,-XX:G1NewSizePercent=3

    • 64GB 堆,-XX:G1NewSizePercent=2

    • 100GB及以上堆,-XX:G1NewSizePercent=1

    • 所以我們最終的 HRegionserver 命令行選項是:

      • -XX:+UseG1GC

      • -Xms100g?-Xmx100g(我們測試中使用的堆大?。?/span>

      • -XX:MaxGCPauseMillis=100(測試中所需的 GC 暫停時間)

      • XX:+ParallelRefProcEnabled

      • -XX:-ResizePLAB

      • -XX:ParallelGCThreads=?8+(40-8)(5/8)=28

      • -XX:G1NewSizePercent=1

    這是運行 100% 讀取操作 1 小時的 GC 暫停時間圖表:

圖片

    在此圖表中,即使是最高的初始穩(wěn)定峰值也從 3.792 秒減少到 1.684 秒。最開始的峰值不到 1 秒。結(jié)算后,GC 能夠?qū)和r間保持在 100 毫秒左右。下圖比較了 jdk7u60 在穩(wěn)定狀態(tài)下使用和不使用調(diào)優(yōu)的運行情況:

圖片

    我們上面描述的簡單 GC 調(diào)整給出了理想的 GC 暫停時間,大約 100 毫秒,平均 106 毫秒和 7 毫秒標準偏差。

    經(jīng)驗總結(jié):

    HBase 是一個響應時間關鍵的應用程序,它要求 GC 暫停時間是可預測和可管理的。使用 Oracle jdk7u60,根據(jù)報告的 GC 信息,我們能夠?qū)?GC 暫停時間調(diào)低到我們想要的 100 毫秒。-XX:+PrintGCDetails?-XX:+PrintGCTimeStamps?-XX:+PrintAdaptiveSizePolicy



Hbase調(diào)優(yōu):HBase 調(diào)整 Java 垃圾收集算法的評論 (共 條)

分享到微博請遵守國家法律
庄浪县| 云霄县| 河源市| 明星| 天全县| 益阳市| 玉树县| 郯城县| 新绛县| 彭水| 台前县| 会理县| 蓬莱市| 湾仔区| 科尔| 洛川县| 久治县| 朝阳市| 广宗县| 惠东县| 灵寿县| 集贤县| 南木林县| 罗甸县| 富宁县| 浦东新区| 定州市| 旅游| 通化市| 新邵县| 临邑县| 阜新| 新蔡县| 辽源市| 鹤山市| 湘潭市| 长垣县| 深州市| 扶沟县| 凤山市| 东光县|