hbase性能優化,看這篇就夠了
- 2019 年 10 月 3 日
- 筆記
HDFS(hdfs-site.xml)相關調整
- dfs.datanode.synconclose = true
dfs.datanode.synconclose set to false in hdfs-site.xml: data loss is possible on hard system reset or power loss
- mount ext4 with dirsync! Or use XFS
- dfs.datanode.sync.behind.writes = true (default false)
設置為true,在數據寫入完成之後,datanode會要求作業系統將數據直接同步到磁碟
- dfs.namenode.avoid.read.stale.datanode = true (default false)
- dfs.namenode.avoid.write.stale.datanode = true (default false)
- dfs.namenode.stale.datanode.interval = 30000 (default 30000)
避免讀寫declared dead的datanode,datanode會發送心跳給namenode,如果超過了dfs.namenode.stale.datanode.interval的時間還未接收到datanode的心跳,則認為該datanode為stale狀態,也就會將datanode declare成dead。默認情況下,namenode仍然會對stale狀態的datanode讀
- dfs.datanode.failed.volumes.tolerated = <N>
keep DN running with some failed disks,tolerate losing this many disks,根據磁碟實際配置數量調整
- dfs.client.read.shortcircuit = true
啟用短路徑讀取(short-circuit): 當client請求數據時,datanode會讀取數據然後通過TCP協議發送給client,short-circuit繞過了datanode直接讀取數據。 short-circuit的前提是client和數據在同一個節點上,所以集群hbase regionserver和hdfs datanode的數量上一般都是1:1,並且datanode和regionserver共處一個節點。 除此之後,指標Locality(數據本地性)需要額外關注,因為更高的數據本地性,可以使短路徑發揮更好的性能
- dfs.datanode.max.transfer.threads = 8192 (default 4096)
Specifies the maximum number of threads to use for transferring data in and out of the DN. An HDFS DataNode has an upper bound on the number of files that it will serve at any one time
詳見:https://hbase.apache.org/book.html#dfs.datanode.max.transfer.threads
http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html
- dfs.namenode.handler.count = 64 (default 10)
The number of Namenode RPC server threads that listen to requests from clients. If dfs.namenode.servicerpc-address is not configured then Namenode RPC server threads listen to requests from all nodes.
- dfs.datanode.handler.count = 8 (default 10)
The number of server threads for the datanode.
HBase(hbase-site.xml)相關調整
- hbase.hstore.blockingStoreFiles = 16
- hbase.hregion.memstore.block.multiplier = 4
- hbase.hregion.memstore.flush.size = 128
如果storefile的數量超過了10個,就會阻塞flush,compact執行緒進行合併(如果觀察日誌,你會看到類似"Too many HFiles, delaying flush"之類的輸出),如果想讓數據寫入更加平滑或者業務寫入量巨大,可以考慮增大該值。
另外,在達到了blockingStoreFiles閥值的時候,開始阻塞flush,那麼memstore就會膨脹,當memstore膨脹到 flush size 乘於 multiplier(flush size X multiplier)的時候,這個列簇的
寫操作就會被阻塞,一直到flush完成(可以關注日誌,會有相關日誌輸出)。
所以如果寫入量巨大,建議同時增加multiplier大小,至於flush size的大小,一般默認即可
- hbase.regionserver.handler.count = 30
每個regionserver啟動的RPC Listener實例個數,hbase.master.handler.count參數意思跟它基本一樣。handler個數並非越多越好,如果設置了過多的handler可能得到一個適得其反的結果
。如果是read-only的場景,handler的個數接近與cpu個數比較好。在調整該參數時候,建議設置為cpu個數的倍數,從兩倍cpu個數開始調整。
- hbase.hregion.max.filesize = 10G
控制region split的閥值,需要注意:如果有多個列簇,不管哪個列簇達到了該值,就會觸發split,並且是region級別的,哪怕其他的列簇的hfile值還很小
目前來說,推薦的最大region size為10-20G,當然也可以設置的更大,比如50G(如果設置了壓縮,該值指的是壓縮之後的大小)
- hbase.regionserver.region.split.policy = SteppingSplitPolicy
split演算法有多種,不一一介紹了。默認是SteppingSplitPolicy演算法,可以根據實際場景情況選擇更為合適的,比如對於已知數據大小的歷史數據,可以將表的split演算法設置為org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy,以實現更好的控制region數目
- zookeeper.session.timeout = 90000(default,in milliseconds)
regionserver與zookeeper建立session,zookeeper通過session來確認regionserver的狀態,每個regionserver在zookeeper中都有自己的臨時znode。如果建立的session斷開了或者超時了(比如gc或者網路問題),那麼zk中的這個regionserver的臨時znode將被刪除,並且該regionserver標記為crashed。 1.在設置該參數值需要注意,要關注zookeeper server的Minimum session timeout和Maximum session timeout,zookeeper默認Minimum session timeout 為 2 X tick time,Maximum session timeout 為 20 x tick time,tick time為心跳間隔(默認2秒)。 也就是說你在hbase側設置的最大會話超時時間在是以client的身份設置的,所以最終還是以zookeeper server為主。(在cdh集群中,如果hbase的該參數值大於zk server的最大會話超時時間,會提示你修改),比如你在hbase側設置最大超時時間為90s,但是zk的最大超時時間是40s,那麼最終還是如果超過40s便視為超時。 2.如果想增加hbase超時時間限制,可以提高tick time的值,但是建議不要超過5秒,超過5秒不利於zookeeper集群的正常運行 3.對於那種failing quickly is better than waiting的應用,可以將超時時間限定小一些(建議值20秒-30秒),但是在此之前,你需要對GC的時間有一個良好的控制。否則會因為GC導致regionserver頻繁被標記為crashed
- hbase.regionserver.thread.compaction.small = 1 (default)
用於minor compact的執行緒數,當compact quene比較高的時候,建議增加該值。但是需要注意的是:該執行緒數永遠不要超過你可用磁碟數目的一半。 比如:你有8塊SSDs, 該值不要超過4 同理hbase.hstore.flusher.count
- hbase.hregion.majorcompaction = 0
major compact時間周期,默認七天,但是觸發時間點往往都不是最佳的。所以一般線上環境都禁用major compact,然後在合適的時間手動執行
- hbase.regionserver.hlog.blocksize = 128M (default)
默認即可,但是需要了解的是WAL一般在達到該值的95%的時候就會滾動
- hbase.regionserver.maxlogs = 32 (default)
配置WAL Files的數量,(WAL:to recover memstore data not yet flushed to disk if a RegionServer crashes),WAL files過少的話,會觸發更多的flush,太多的話,hbase recovery時間會比較長。 根據不同的regionserver堆大小設置不同數量的WAL。有一個經驗公式: (regionserver_heap_size * memstore fraction) / (default_WAL_size) 例如,HBase集群配置如下: • 16 GB RegionServer heap • 0.4 memstore fraction • 120 MB default WAL size The formula for this configuration looks as follows: (16384 MB * 0.4 / 120 MB = approximately 55 WAL files 注意:如果recovery的時間過長,可以減小上面計算的值
- hbase.wal.provider = mutiwal
默認情況下,一個regionserver只有一個wal文件,所有region的walEntry都寫到這個wal文件中,在HBase-5699之後,一個regionserver可以配置多個wal文件,這樣可以提高寫WAL時的吞吐,進而降低數據寫延時,其中配置hbase.wal.regiongrouping.strategy決定了每個region寫入wal時的分組策略,默認是bounded,表示每個regiongroup寫入固定數量個wal; Multiple Wal:HBASE-5669(available in hbase 1.0.0+) 1.版本低於1.2.0 replication存在問題 2.寫入性能較單WAL提升20% 3.hbase.wal.regiongrouping.strategy = bounded(分組策略) 4.hbase.wal.regiongrouping.numgroups = 2(根據盤數設置) 注意:hbase.regionserver.maxlogs,決定了一個regionserver中wal文件的最大數量,默認是32,在上述配置下,如果仍舊設置保持32,等價於不使用multiwal時的64;
HBase表屬性調整
Compression
1.可以選擇的有NONE, GZIP, SNAPPY, 等等 2.指定壓縮方式:create ’test', {NAME => ’cf', COMPRESSION => 'SNAPPY’}} 3.節省磁碟空間 4.壓縮針對的是整個塊,對get或scan不太友好 5.快取塊的時候不會使用壓縮,除非指定hbase.block.data.cachecompressed = true,這樣可以快取更多的塊,但是讀取數據時候,需要進行解壓縮
HFile Block Size
1. 不等同於HDFS block size 2. 指定BLOCKSIZE屬性 create ‘test′,{NAME => ‘cf′, BLOCKSIZE => ’4096'} 3.默認64KB,對Scan和Get等同的場景比較友好 4.增加該值有利於scan 5.減小該值有利於get
Garbage Collection優化
目前對於hbase來說,生產上G1 GC使用比較多,參考HBase G1 GC優化
RegionServer節點硬體配置
大多時候,對於hbase集群我們會面臨這樣的問題: • 應該分配多少的RAM/heap? • 應該準備多少塊磁碟? • 磁碟的大小應該多大? • 網卡頻寬? • 應該有多少個cpu core?
regionserver的磁碟大小與堆大小是有一個比例的: Disk/Heap ratio: RegionSize / MemstoreSize *ReplicationFactor *HeapFractionForMemstores * 2 那麼在默認情況下,該比例等於:10gb/128mb * 3 * 0.4 * 2 = 192 也就是說: 在磁碟上每存儲192位元組的數據,對應堆的大小應為1位元組 那麼如果設置32G的堆,磁碟上也就是可以存儲大概6TB的數據(32gb * 192 = 6tb)
理想狀況下regionserver的硬體配置: 1.每個節點<=6TB的磁碟空間 2.regionserver heap 約等於磁碟大小/200(上面的比例公式) 3.由於hbase屬於cpu密集型,所以較多的cpu core數量更適合 4.網卡頻寬和磁碟吞吐量的匹配值: (背景:磁碟使用傳統HDD,I/O 100M/s) CASE1:1GE的網卡,配備24塊磁碟,像這樣的搭配是不太理想的,因為1GE的網卡流量等於125M/s,而24塊磁碟的吞吐量大概2.4GB/s,網卡成為瓶頸 CASE2:10GE的網卡,配備24塊磁碟,比較理想 CASE3:1GE的網卡,配置4-6塊磁碟,也是比較理想的