1. 程式人生 > >hbase效能優化,看這篇就夠了

hbase效能優化,看這篇就夠了

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使用比較多,後續單獨對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塊磁碟,也是比較理想的