HBase參數最佳化

來源:互聯網
上載者:User

標籤:

zookeeper.session.timeout
預設值:3分鐘(180000ms)
說明:RegionServer與Zookeeper間的連線逾時時間。當逾時時間到後,ReigonServer會被Zookeeper從RS叢集清單中移除,HMaster收到移除通知後,會對這台server負責的regions重新balance,讓其他存活的RegionServer接管.
調優:這個timeout決定了RegionServer是否能夠及時的failover。設定成1分鐘或更低,可以減少因等待逾時而被延長的failover時間。
不過需要注意的是,對於一些Online應用,RegionServer從宕機到恢復本身就很短的(網路閃斷,crash等故障,營運可快速介入),如果調低timeout時間,反而會得不償失。因為當ReigonServer被正式從RS叢集中移除時,HMaster就開始做balance了 (讓其他RS根據故障機器記錄的WAL日誌進行恢複)。當故障的RS在人工介入恢複後,這個balance動作是毫無意義的,反而會使負載不均勻,給RS 帶來更多負擔。特別是那些固定分配regions的情境。

hbase.regionserver.handler.count
預設值:10
說明:RegionServer的請求處理IO線程數。
調優:這個參數的調優與記憶體息息相關。
較少的IO線程,適用於處理單次請求記憶體消耗較高的Big PUT情境(大容量單次PUT或設定了較大cache的scan,均屬於Big PUT)或ReigonServer的記憶體比較緊張的情境。
較多的IO線程,適用於單次請求記憶體消耗低,TPS要求非常高的情境。設定該值的時候,以監控記憶體為主要參考。
這裡需要注意的是如果server的region數量很少,大量的請求都落在一個region上,因快速充滿memstore觸發flush導致的讀寫鎖會影響全域TPS,不是IO線程數越高越好。
壓測時,開啟Enabling RPC-level logging,可以同時監控每次請求的記憶體消耗和GC的狀況,最後通過多次壓測結果來合理調節IO線程數。

hbase.hregion.max.filesize
預設值:256M
說明:在當前ReigonServer上單個Reigon的最大儲存空間,單個Region超過該值時,這個Region會被自動split成更小的region。
調優:小region對split和compaction友好,因為拆分region或compact小region裡的storefile速度很快,記憶體佔用低。缺點是split和compaction會很頻繁。特別是數量較多的小region不停地split, compaction,會導致叢集回應時間波動很大,region數量太多不僅給管理上帶來麻煩,甚至會引發一些Hbase的bug。一般512以下的都算小region。
大region,則不太適合經常split和compaction,因為做一次compact和split會產生較長時間的停頓,對應用的讀寫效能衝擊非常大。此外,大region意味著較大的storefile,compaction時對記憶體也是一個挑戰。
當然,大region也有其用武之地。如果你的應用情境中,某個時間點的訪問量較低,那麼在此時做compact和split,既能順利完成split和compaction,又能保證絕大多數時間平穩的讀寫效能。
記憶體方面,小region在設定memstore的大小值上比較靈活,大region則過大過小都不行,過大會導致flush時app的IO wait增高,過小則因store file過多影響讀效能。

既然split和compaction如此影響效能,有沒有辦法去掉?
compaction是無法避免的,split倒是可以從自動調整為手動。
只要通過將這個參數值調大到某個很難達到的值,比如100G,就可以間接禁用自動split(RegionServer不會對未到達100G的region做split)。
再配合RegionSplitter這個工具,在需要split時,手動split。
手動split在靈活性和穩定性上比起自動split要高很多,相反,管理成本增加不多,比較推薦online即時系統使用。

hbase.regionserver.global.memstore.upperLimit/lowerLimit
預設值:0.4/0.35
upperlimit說明:hbase.hregion.memstore.flush.size 這個參數的作用是:當單個memstore達到指定值時,flush該memstore。但是,一台ReigonServer可能有成百上千個memstore,每個memstore也許未達到flush.size,jvm的heap就不夠用了。該參數就是為了限制memstores佔用的總記憶體。
當ReigonServer內所有的memstore所佔用的記憶體總和達到heap的40%時,HBase會強制block所有的更新並flush這些memstore以釋放所有memstore佔用的記憶體。
lowerLimit說明:同upperLimit,只不過當全域memstore的記憶體達到35%時,它不會flush所有的memstore,它會找一些記憶體佔用較大的memstore,做個別flush,當然更新還是會被block。lowerLimit算是一個在全域flush導致效能暴跌前的補救措施。為什麼說是效能暴跌?可以想象一下,如果memstore需要在一段較長的時間內做全量flush,且這段時間內無法接受任何讀寫請求,對HBase叢集的效能影響是很大的。
調優:這是一個Heap記憶體保護參數,預設值已經能適用大多數情境。它的調整一般是為了配合某些專屬最佳化,比如讀密集型應用,將讀緩衝開大,降低該值,騰出更多記憶體給其他模組使用。

這個參數會給使用者帶來什麼影響?
比如,10G記憶體,100個region,每個memstore 64M,假設每個region只有一個memstore,那麼當100個memstore平均佔用到50%左右時,就會達到lowerLimit的限制。假設此時,其他memstore同樣有很多的寫請求進來。在那些大的region未flush完,就可能又超過了upperlimit,則所有 region都會被block,開始觸發全域flush。
不過,除了你的記憶體非常小或你的應用情境裡大多數都是讀,我覺得不需要去調這個參數。

hfile.block.cache.size
預設值:0.2
說明:storefile的讀緩衝佔用Heap的大小百分比,0.2表示20%。該值直接影響資料讀的效能。
調優:當然是越大越好,如果讀比寫多,開到0.4-0.5也沒問題。如果讀寫較均衡,0.3左右。如果讀比寫少,果斷預設吧。設定這個值的時候,你同時要參考 hbase.regionserver.global.memstore.upperLimit ,該值是memstore佔heap的最大百分比,兩個參數一個影響讀,一個影響寫。如果兩值加起來超過80-90%,會有OOM的風險,謹慎設定。

hbase.hstore.blockingStoreFiles
預設值:7
說明:在compaction時,如果一個Store(Coulmn Family)內有超過7個storefile需要合并,則block所有的寫請求,進行flush,限制storefile數量增長過快。
調優:block寫請求會影響當前region的效能,將值設為單個region可以支撐的最大store file數量會是個不錯的選擇,即允許comapction時,memstore繼續產生storefile。最大storefile數量可通過 region size/memstore size來計算。如果你將region size設為無限大,那麼你需要預估一個region可能產生的最大storefile數。

hbase.hregion.memstore.block.multiplier
預設值:2
說明:當一個region裡的memstore超過單個memstore.size兩倍的大小時,block該region的所有請求,進行 flush,釋放記憶體。雖然我們設定了memstore的總大小,比如64M,但想象一下,在最後63.9M的時候,我Put了一個100M的資料,此時 memstore的大小會瞬間暴漲到超過預期的memstore.size。這個參數的作用是當memstore的大小增至超過 memstore.size時,block所有請求,遏制風險進一步擴大。
調優:這個參數的預設值還是比較靠譜的。如果你預估你的正常應用情境(不包括異常)不會出現突發寫或寫的量可控,那麼保持預設值即可。如果正常情況下,你的寫請求量就會經常暴長到正常的幾倍,那麼你應該調大這個倍數並調整其他參數值,比如hfile.block.cache.size和 hbase.regionserver.global.memstore.upperLimit/lowerLimit,以預留更多記憶體,防止HBase server OOM。

啟用LZO壓縮
LZO對比Hbase預設的GZip,前者效能較高,後者壓縮比較高,具體參見 Using LZO Compression 。對於想提高HBase讀寫效能的開發人員,採用LZO是比較好的選擇。對於非常在乎儲存空間的開發人員,則建議保持預設。

不要定義太多的Column Family
Hbase目前不能良好的處理超過包含2-3個CF的表。因為某個CF在flush發生時,它鄰近的CF也會因關聯效應被觸發flush,最終導致系統產生更多IO。

大量匯入
在大量匯入資料到Hbase前,你可以通過預先建立regions,來平衡資料的負載。詳見 Table Creation: Pre-Creating Regions

避免CMS concurrent mode failure
HBase使用CMS GC。預設觸發GC的時機是當年老代記憶體達到90%的時候,這個百分比由 -XX:CMSInitiatingOccupancyFraction=N 這個參數來設定。concurrent mode failed發生在這樣一個情境:
當年老代記憶體達到90%的時候,CMS開始進行並發垃圾收集,於此同時,新生代還在迅速不斷地晉陞對象到年老代。當年老代CMS還未完成並發標記時,年老代滿了,悲劇就發生了。CMS因為沒記憶體可用不得不暫停mark,並觸發一次全jvm的stop the world(掛起所有線程),然後採用單線程拷貝方式清理所有垃圾對象。這個過程會非常漫長。為了避免出現concurrent mode failed,我們應該讓GC在未到90%時,就觸發。
通過設定 -XX:CMSInitiatingOccupancyFraction=N
這個百分比, 可以簡單的這麼計算。如果你的 hfile.block.cache.size 和 hbase.regionserver.global.memstore.upperLimit 加起來有60%(預設),那麼你可以設定 70-80,一般高10%左右差不多。

Hbase用戶端最佳化
AutoFlush(預設是true)
將HTable的setAutoFlush設為false,可以支援用戶端批次更新。即當Put填滿用戶端flush緩衝時,才發送到服務端。

Scan Caching
scanner一次緩衝多少資料來scan(從服務端一次抓多少資料回來scan)。
預設值是 1,一次只取一條。

Scan Attribute Selection
scan時建議指定需要的Column Family,減少通訊量,否則scan操作預設會返回整個row的所有資料(所有Coulmn Family)。

Close ResultScanners
通過scan取完資料後,記得要關閉ResultScanner,否則RegionServer可能會出現問題(對應的Server資源無法釋放)。

Optimal Loading of Row Keys
當你scan一張表的時候,返回結果只需要row key(不需要CF, qualifier,values,timestaps)時,你可以在scan執行個體中添加一個filterList,並設定 MUST_PASS_ALL 操作,filterList中add FirstKeyOnlyFilter或KeyOnlyFilter。這樣可以減少網路通訊量。

Turn off WAL on Puts
當Put某些非重要資料時,你可以設定writeToWAL(false),來進一步提高寫效能。writeToWAL(false)會在Put時放棄寫WAL log。風險是:當RegionServer宕機時,可能你剛才Put的那些資料會丟失,且無法恢複。

啟用Bloom Filter
Bloom Filter通過空間換時間,提高讀操作效能。

HBase參數最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.