一:hbase現(xiàn)有硬件資源的理論性能
1.集群容量規(guī)劃公式:
優(yōu)化調整,發(fā)揮硬件的最大優(yōu)勢;
Disk Size / Java Heap=RegionSize / MemstoreSize * ReplicationFactor * HeapFractionForMemstore *2
按照默認配置,
- RegionSize = 10G,對應參數(shù)為hbase.hregion.max.filesize;
- MemstoreSize = 128M,對應參數(shù)為hbase.hregion.memstore.flush.size;
- ReplicationFactor = 3,對應參數(shù)為dfs.replication;
- HeapFractionForMemstore = 0.4,對應參數(shù)為hbase.regionserver.global.memstore.lowerLimit;
推導公式;
- 硬盤容量緯度下Region個數(shù):
Disk Size / (RegionSize * ReplicationFactor) - Java Heap緯度下Region個數(shù):
Java Heap * HeapFractionForMemstore / (MemstoreSize / 2 )
Disk Size / (RegionSize * ReplicationFactor) = Java Heap * HeapFractionForMemstore / (MemstoreSize / 2 )
=> Disk Size / Java Heap = RegionSize / MemstoreSize * ReplicationFactor * HeapFractionForMemstore * 2
2.hbase對于cpu要求高,越多core越好
3.軟硬件獨立的hbase集群
其他硬件配置,
- 集群使用萬兆網卡(千兆對于大數(shù)據(jù)集群來說實在太小,很容易打滿,影響較大),
- 磁盤盡可能大,
- 內存不用太高,一般128G就已經特別多了HBase本身對內存的需求并不是配的越大越好。
- CPU核數(shù)越多越好,HBase本身壓縮數(shù)據(jù)、compaction線程等都是很吃CPU資源的。
二:hbase現(xiàn)集群調優(yōu)參數(shù)
| 屬 性 值 | cdh集群現(xiàn)有 | 集群效果 |
|---|---|---|
| hbase.hstore.blockingStoreFiles | 100 | HStore的storeFile的文件數(shù)大于配置值, |
| 則在flush memstore前先進行split或者compact, | ||
| 除非超過 | ||
| hbase.hstore.blockingWaitTime配置的時間, | ||
| 默認為7,可調大,比如:100, | ||
| 避免memstore不及時flush,當寫入量大時, | ||
| 觸發(fā)memstore的block,從而阻塞寫操作。 | ||
| cachecompress | FALSE | 開啟cache的壓縮, |
| 50% increase in throughput | ||
| and 30% improvement in mean latency while, | ||
| increasing garbage collection by 80% | ||
| and increasing overall CPU load by 2% | ||
| hbase.regionserver.thread.compaction.small | 5 | 壓縮的線程數(shù),增加壓縮性能。 |
| hbase.hregion.memstore.flush.size | 256 | 當前系統(tǒng)flush比較頻繁,并且內存資源比較充足, |
| 可以適當將該值調整為256M。避免頻繁的flush | ||
| hbase.hstore.compactionThreshold | 5 | 有五個store file就觸發(fā)compact操作, |
| 減少壓縮隊列。 | ||
| HBase HRegion 最大化壓縮 | 0 | 禁止自動大合并(時間長,耗費資源), |
| hbase.hregion.majorcompaction | 業(yè)務低峰期進行手動合并。 | |
| GC-region server配置(JDK1.7) | -XX:+UseG1GC | G1日志打?。?/td> |
| -XX:MaxGCPauseMillis=100 | -verbose:gc | |
| -XX:InitiatingHeapOccupancyPercent=70 | -XX:+PrintGC | |
| -XX:G1HeapRegionSize=16m | -XX:+PrintGCDetails | |
| -XX:+ParallelRefProcEnabled | -XX:+PrintGCApplicationStoppedTime | |
| -XX:+UnlockExperimentalVMOptions | -XX:+PrintHeapAtGC | |
| -XX:-ResizePLAB | -XX:+PrintGCDateStamps | |
| -XX:+PrintAdaptiveSizePolicy | ||
| -XX:+PrintTenuringDistribution | ||
| -XX:+PrintSafepointStatistics | ||
| -XX:PrintSafepointStatisticsCount=1 | ||
| -XX:PrintFLSStatistics=1 | ||
| zookeeper.session.timeout | 120000 | 加大zk超時時間,防止其他意外導致超時 |
| hbase.bucketcache.ioengine | 現(xiàn)在用blockcache,0.6 | 降低了JVM GC對業(yè)務請求的實際影響 |
| hbase.regionserver.maxlogs | 32 | region flush的觸發(fā)條件之一, |
| 計算方法: | wal日志文件總數(shù)超過該閾值就會強制執(zhí)行flush操作。該默認值對于很多集群來說太小 | |
| maxLogs = | ||
| HEAP_SIZE * memstoreRatio * 2/ LogRollSize | ||
| hbase.hregion.max.filesize | 10G | 會進行region的切分; |
| 改進: | ||
| 手動進行split,調一個每天的數(shù)據(jù)量不可能達到、 | ||
| 定時器萬一失靈也不會造成麻煩的值。 | ||
| 100G的文件split大約需要1小時的時間 | ||
| hbase.hregion.memstore.mslab.enabled | TRUE | 減少因內存碎片導致的Full GC,提高整體性能。 |
| hbase.regionserver.handler.count | 200 | 特別是當請求內容很大的時候, |
| 比如scan/put幾M的數(shù)據(jù),會占用過多的內存, | ||
| 有可能導致頻繁的GC,甚至出現(xiàn)內存溢出。 |
| hbase參數(shù)名 | 現(xiàn)有值 | 描述說明建議 |
|---|---|---|
| zookeeper.session.timeout | 120000 | RegionServer與Zookeeper間的連接超時時間。 |
| 超時時間到后,ReigonServer會被Zookeeper從RS集群清單中移除, | ||
| HMaster收到移除通知后,會對這臺server負責的regions重新balance, | ||
| 讓其他存活的RegionServer接管. | ||
| 這個timeout決定了RegionServer是否能夠及時的failover。 | ||
| 設置成1分鐘或更低,可以減少因等待超時而被延長的failover時間。 | ||
| 不過需要注意的是,對于一些Online應用, | ||
| RegionServer從宕機到恢復時間本身就很短的(網絡閃斷,crash等故障,運維可快速介入),如果調低timeout時間,反而會得不償失。 | ||
| 因為當ReigonServer被正式從RS集群中移除時,HMaster就開始做balance了(讓其他RS根據(jù)故障機器記錄的WAL日志進行恢復)。 | ||
| 當故障的RS在人工介入恢復后,這個balance動作是毫無意義的,反而會使負載不均勻,給RS帶來更多負擔。特別是那些固定分配regions的場景。 | ||
| 推薦:120000 | ||
| 參考:http://hbase.apache.org/1.2/book.html#trouble.rs.runtime.zkexpired | ||
| HDFS 服務 | HDFS | 此 HBase 服務實例依賴的 HDFS 服務的名稱 |
| ZooKeeper 服務 | Zookeeper | 此 HBase 服務實例依賴的 ZooKeeper 服務的名稱。 |
| hbase.master.handler.count | 200 | HBase Master 中啟動的 RPC 服務器實例數(shù)量; |
| Master處理事務的線程數(shù),如果Master十分繁忙或者Region Server數(shù)很多時,可以適當增大該值。 | ||
| 經驗法則是根據(jù)集群的約為負載,在每個請求的有效負載較大時保持低值,并在有效負載較小時保持高值。 | ||
| hbase.regionserver.handler.count | 200 | 這個參數(shù)的調優(yōu)與內存息息相關。 |
| 較少的IO線程,適用于處理單次請求內存消耗較高的Big PUT場景(大容量單次PUT或設置了較大cache的scan,均屬于Big PUT)或ReigonServer的內存比較緊張的場景。 | ||
| 較多的IO線程,適用于單次請求內存消耗低,TPS要求非常高的場景。設置該值的時候,以監(jiān)控內存為主要參考。設置太多適得其反。 | ||
| 這里需要注意的是如果server的region數(shù)量很少,大量的請求都落在一個region上,因快速充滿memstore觸發(fā)flush導致的讀寫鎖會影響全局TPS,不是IO線程數(shù)越高越好。 | ||
| 壓測時,開啟Enabling RPC-level logging,可以同時監(jiān)控每次請求的內存消耗和GC的狀況,最后通過多次壓測結果來合理調節(jié)IO線程數(shù)。 | ||
| 這里是一個案例?Hadoop and HBase Optimization for Read Intensive Search Applications,作者在SSD的機器上設置IO線程數(shù)為100,僅供參考。 | ||
| 經驗法則是在每個請求的有效負載較大時保持低值,并在有效負載較小時保持高值。 將hbase.regionserver.handler.count增加到大約為區(qū)域服務器上的CPU數(shù)量的值 | ||
| 建議: | ||
| 從cpu*2開始調整, | ||
| hbase.regionserver.global.memstore.upperLimit, | 0.2 | 根據(jù)實際業(yè)務集群的讀寫比例來設置。 |
| hbase.regionserver.global.memstore.size | ||
| hbase.hregion.memstore.flush.size | 256M | 如 memstore 大小超過此值(字節(jié)數(shù)),Memstore 將刷新到磁盤。通過運行由 hbase.server.thread.wakefrequency 指定的頻率的線程檢查此值。 |
| 在集群內存足夠的情況下。增大,針對刷數(shù)據(jù)頻繁操作。 | ||
| hbase.hstore.compactionThreshold | 5 | 當store中文件數(shù)超過該閾值就會觸發(fā)compaction。通常建議生產線上寫入qps較高的系統(tǒng)調高此值 |
| 建議: | ||
| 太大的compact需要足夠的內存來記錄壓縮期間的所有更新,減少compact次數(shù),增加compact時間,影響讀數(shù)據(jù)。如果太大,客戶端在壓縮期間會超時。 | ||
| hbase.hstore.blockingStoreFiles | 100 | HStore的storeFile的文件數(shù)大于配置值,則在flush memstore前先進行split或者compact,除非超過hbase.hstore.blockingWaitTime配置的時間,比如:100,避免memstore不及時flush,當寫入量大時,觸發(fā)memstore的block,從而阻塞寫操作。 |
| 參考: | ||
| http://hbase.apache.org/1.2/book.html#hbase.hstore.blockingStoreFiles | ||
| hbase.hstore.compaction.max | 10 | 一次minicompact選取的最大store file數(shù)量,設置太大則會有更多的storefile進入compact中,一般情況,默認值夠用。 |
| 建議:默認值。 | ||
| hbase.hregion.majorcompaction | 0 | 禁用hbase的自動compact,在低峰期進行手動compact操作。 |
| hfile.block.cache.size | 0.6 | 根據(jù)集群讀寫業(yè)務設置比例 |
| dfs.client.hedged.read.threadpool.size | 16 | 通常,為每個讀請求生成一個線程。 |
| 然而,如果Hedged Reads被啟用, | ||
| 那么客戶端等待了一些可配置的時間后, | ||
| 如果讀取沒有返回,則客戶端會生成第二個讀取請求, | ||
| 去讀取相同數(shù)據(jù)的不同塊備份。 | ||
| 首先返回的讀取結果會被使用,另一個讀取請求將被丟棄。 | ||
| Hedged reads 對于一個由錯誤的磁盤或脆弱的網絡連接造成的罕見的慢讀,很有幫助。 | ||
| dfs.client.hedged.read.threshold.millis - 在生成第二個讀取線程前等待的毫秒數(shù)。 | ||
| 專用于服務Hedged Reads的線程數(shù)。如果被設置成 0 (默認值), hedged reads被禁用 | ||
| 建議: | ||
| 線程池大小可以與讀handler的數(shù)目相同, | ||
| 而超時閾值不適宜調整的太小,否則會對集群和客戶端都增加壓力。 | ||
| 使用以下度量方式調整集群上Hedged Reads的設置。 | ||
| 參考 HBase Metrics 獲取更多信息。 | ||
| hedgedReadOps - Hedged Read線程被觸發(fā)的次數(shù)。 | ||
| 這可能表明讀取請求通常很慢,或者被觸發(fā)的讀取速度太快。 | ||
| hedgeReadOpsWin - Hedged Read 線程快于原有讀取線程的次數(shù)。這可能表明給定的RegionServer(原有讀取線程要讀取的數(shù)據(jù)所在的RegionServer)在請求的服務上有問題。 | ||
| hbase.regionserver.thread.compaction.small | 5 | 完成minicompact的線程數(shù),增大可以加快Mini compact |
| 建議:5 | ||
| hbase.ipc.server.read.threadpool.size | 200 | 讀取 RegionServer HBase IPC Server 使用的線程池大小。 |
| hbase.ipc.server.read.threadpool.size是用來把前端請求放到隊列中的參數(shù),HADOOP系統(tǒng)內部都是通過RPC框架來請求資源的。默認這個參數(shù)應該是10, | ||
| 建議; | ||
| 10個夠不夠,還是不知道,看整體并發(fā),監(jiān)控metric:numActiveHandler 解釋:Number of active rpc handlers. 如果這個值經常滿,那么就需要增加。 | ||
| Region Mover 線程 | 5 | 向 RegionServer 加載region或從中卸載region要使用的線程數(shù)。可用于提高解除或滾動重新啟動操作的速度 |
| 建議: | ||
| 比默認值適當增大,加快region移動速度。 | ||
| 抑制參數(shù)驗證:HBase HRegion Major Compaction | RegionServer Default Group | 是否抑制 HBase HRegion Major Compaction 參數(shù)的內置參數(shù)驗證產生的配置警告。 |
| HBase Region Server 刷新隊列監(jiān)控閾值 | 20 | 刷新隊列閾值 |
| HBase RegionServer 的 Java 堆棧大?。ㄗ止?jié)) | 23.12G | Java最大內存。 |
| 建議一:初始通過fullgc之后,年老代內存的3到4倍設置 | ||
| 建議二:通過觀察線上gc監(jiān)控,判斷內存高峰期使用情況,修改內存。 | ||
| hbase-site.xml 的 HBase 服務高級配置代碼段(安全閥) | hbase.block.data.cachecompressed:false | cache是否啟用壓縮; |
| enabling this feature with SNAPPY compression has been | ||
| shown to result in 50% increase in throughput and 30% improvement in mean latency while, | ||
| increasing garbage collection by 80% | ||
| and increasing overall CPU load by 2%. | ||
| 建議: | ||
| 當前關閉cache壓縮;(由于之前開啟導致cpu上升) | ||
| 客戶端 Java 配置選項 | -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Djava.net.preferIPv4Stack=true | 基于jdk1.7.0_80 |
| HBase REST Server 的 Java 配置選項 | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled | 基于jdk1.7.0_80 |
| HBase Thrift Server 的 Java 配置選項 | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled | 基于jdk1.7.0_80 |
| HBase Master 的 Java 配置選項 | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled | 基于jdk1.7.0_80 |
| HBase RegionServer 的 Java 配置選項 | -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:InitiatingHeapOccupancyPercent=70 -XX:G1HeapRegionSize=16m -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -XX:-ResizePLAB | 基于jdk1.7.0_80,通過觀察具體高峰期gc情況優(yōu)化; |
| GC參數(shù): | ||
| -Xmx50g | ||
| -XX:+UseG1GC | ||
| -XX:+UnlockExperimentalVMOptions | ||
| -XX:MaxGCPauseMillis=100 | ||
| -XX:InitiatingHeapOccupancyPercent=65 | ||
| -XX:+ParallelRefProcEnabled | ||
| -XX:MaxTenuringThreshold=1 | ||
| -XX:G1HeapRegionSize=16m | ||
| GC日志打印添加參數(shù): | ||
| -verbose:gc | ||
| -XX:+PrintGC | ||
| -XX:+PrintGCDetails | ||
| -XX:+PrintGCApplicationStoppedTime | ||
| -XX:+PrintHeapAtGC | ||
| -XX:+PrintGCDateStamps | ||
| -XX:+PrintAdaptiveSizePolicy | ||
| -XX:+PrintTenuringDistribution | ||
| -XX:+PrintSafepointStatistics | ||
| -XX:PrintSafepointStatisticsCount=1 | ||
| -XX:PrintFLSStatistics=1 | ||
| -XX:+HeapDumpOnOutOfMemoryError | ||
| -XX:HeapDumpPath=path |
三:根據(jù)實際場景的hbase優(yōu)化;
1.冷熱數(shù)據(jù)
現(xiàn)有業(yè)務:數(shù)據(jù)更新頻繁;冷數(shù)據(jù);
基于數(shù)據(jù)更新頻繁,blockcache比例減少;如果數(shù)據(jù)不頻,開啟blockcache同時使用bucketcache,減少blockcache比例,設置bucketcache;.
2.數(shù)據(jù)get 、scan操作
- 現(xiàn)有業(yè)務:get操作比較多;
- scan操作少
- 用來表設計參考;
3.數(shù)據(jù)讀寫比例
- 現(xiàn)有業(yè)務:hbase數(shù)據(jù)讀大于寫
- 根據(jù)業(yè)務調整memstore、blockcache或者bucketcache比例;
- 設置數(shù)據(jù)的compact隊列及flush隊列參數(shù),預防隊列過大,調整性能;
4.數(shù)據(jù)的版本、過期時間、bloom filter、表設計
原則:盡量在表結構設計就考慮性能問題,而不是通過設置參數(shù)在調整
- version:根據(jù)業(yè)務,具體調整數(shù)據(jù)版本version應該幾個?
- TTL,MINVERSION根據(jù)數(shù)據(jù)使用調整數(shù)據(jù)過期時間TTL;及數(shù)據(jù)最小版本號minversion;
- bloom filter:根據(jù)數(shù)據(jù)的使用場景設計bloom filter:行級布隆過濾器,因為它在額外的空間開銷和利用過濾存儲文件提升性能之間取得了更好的平衡。設置數(shù)據(jù)bllomfilter的開啟及設計;
- IN_MEMORY屬性;可以將meta表設置為true;
- 設置rowkey、column長度越短越好,數(shù)據(jù)定義規(guī)則
- 針對get與scan頻繁的字段:盡量使常用查詢的域放入ROWKEY(最重要的放在前面,然后依次拼接),合理設置rowkey,
- 盡量高表使用,通常比寬表性能高50%以上;
- hbase建表預分區(qū);
- 行記錄:建議多行存儲(不是去增加一個列),更好的get及scan性能,太長的行記錄不易region的split
5.gc優(yōu)化:
GC參數(shù):
-Xmx50g
-Xms50g
-XX:+UseG1GC
-XX:+UnlockExperimentalVMOptions
-XX:MaxGCPauseMillis={50/90/500} for SSD/HDD/offline cluster
-XX:G1NewSizePercent={2/5} for normal/heavy load cluster
-XX:InitiatingHeapOccupancyPercent=65
-XX:+ParallelRefProcEnabled
-XX:MaxTenuringThreshold=1
-XX:G1HeapRegionSize=16m
GC日志打印添加參數(shù):
-verbose:gc
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintHeapAtGC
-XX:+PrintGCDateStamps
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintTenuringDistribution
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
-XX:PrintFLSStatistics=1
6.hbase讀優(yōu)化客戶端
- scan.setcaching :
大scan場景下將scan緩存從100增大到500或者1000,用以減少RPC次數(shù) - scan.setbatch
每次請求返回的列數(shù) - scan:
指定列族、startrow、endrow、filter - get :
多get請求采用批量請求;get請求可以指定列族及列; - scan.setBlockCache(false):
如果離線批量讀取請求的話;否則會從cache擠出其他熱點數(shù)據(jù); - filter
優(yōu)先使用keyfilter,而不是valuefilter - cache
使用redis等緩存系統(tǒng)
7.hbase寫性能問題:
- HBase理論平均寫延時 < 10ms,時間復雜度O(1)
- 沒有可用的handler響應
- 考慮增加handler數(shù)目或硬件資源
- 更常見的情況是95%-99%的寫入都很快,但有些 寫入非常慢,甚至上萬倍,一般問題在服務端:
- 寫入Memstore慢
- HLog寫入超時——考慮HDFS及硬盤異常
- GC——考慮優(yōu)化內存使用(GC參數(shù)及算法調優(yōu)有限)
- Flush慢
- HFile寫入超時——考慮HDFS及硬盤異常
- Compaction被觸發(fā)且運行時間長——優(yōu)化高峰期Compaction 策略
- 寫入Memstore慢
8.hbase 客戶端緩存元數(shù)據(jù)
- 客戶端自己發(fā)現(xiàn)自己的緩存是錯的,再去拿新meta信息后重試;hbase客戶端使用重試的方式解決這個問題,本地有緩存的情況下
- 按照緩存直接訪問hregionserver
- regionserver報regionnot online異常
- 客戶端知道了我訪問錯了
- 客戶端去取meta
- 客戶端更新緩存,拿到正確地址
- 客戶端使用正確地址