日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【2022持续更新】大数据最全知识点整理-HBase篇

發布時間:2024/1/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【2022持续更新】大数据最全知识点整理-HBase篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大數據最全知識點整理-HBase篇

  • 基礎問題:
    • 1、Hbase是什么
    • 2、Hbase架構
    • 3、Hbase數據模型
    • 4、Hbase和hive的區別
    • 5、Hbase特點
    • 6、數據同樣存在HDFS,為什么HBase支持在線查詢,且效率比Hive快很多
    • 7、Hbase適用場景
    • 8、RowKey的設計原則
    • 9、HBase中scan和get的功能以及實現的異同?
    • 10、Scan的setCache和setBatch
      • setCache
      • setBatch
    • 11、HBase 寫流程
    • 12、HBase 讀流程
    • 13、HBase中Zookeeper的作用
    • 14、StoreFile(HFile)合并
      • 作用
      • minor(小合并)
      • major(大合并)
    • 15、Hbase協處理器
      • observer
      • Endpoint
      • 協處理加載方式
    • 16、WAL機制
    • 17、Memstore
      • 主要作用:
      • 相關配置
      • Memstore Flush
    • 18、BloomFilter
    • 19、BlockCache讀緩存
      • LRUBlock Cache:
      • SlabCache
      • Bucket Cache
      • 組合模式
      • BlockCache 壓縮
    • 20、Region拆分
      • 拆分流程
      • 自動拆分
      • 手動拆分
    • 21、Region合并
      • 合并過程
      • Merger類手動合并
      • 熱合并
    • 22、Region 負載均衡
    • 23、Region預分區
    • 24、一張表中定義多少個 Column Family 最合適
    • 25、為什么不建議在 HBase 中使用過多的列族
    • 26、直接將時間戳作為行健,在寫入單個region時會發生熱點問題,為什么
    • 27、HBase中region太小和region太大的影響
    • 28、每天百億數據如何寫入Hbase
    • 29、HBase集群安裝注意事項?
    • 30、Hbase數據熱點問題
    • 31、HBase宕機恢復流程
      • Master 宕機恢復
      • regionServer宕機恢復
    • 32、HBase性能優化
      • HDFS調優
      • 集群性能優化
      • 表層面優化
      • 讀優化
      • 寫優化

基礎問題:

1、Hbase是什么

  • Hbase一個分布式的基于列式存儲的數據庫,基于Hadoop的hdfs存儲,zookeeper進行管理。
  • Hbase適合存儲半結構化或非結構化數據,對于數據結構字段不夠確定或者雜亂無章很難按一個概念去抽取的數據。
  • Hbase為null的記錄不會被存儲.
  • 基于的表包含rowkey,時間戳,和列族。新寫入數據時,時間戳更新,同時可以查詢到以前的版本.
  • hbase是主從架構。Master作為主節點,Regionserver作為從節點。
  • 深入閱讀:可能是最易懂的Hbase架構原理解析

    2、Hbase架構

    Hbase架構圖:
    Zookeeper: Master 的高可用、RegionServer 的監控、元數據的入口以及集群配置的維護等

    HDFS: 提供底層數據支撐

    Master
    1、監控RegionServer,進行負載均衡
    2、RegionServer故障轉移
    3、處理元數據變更
    4、處理region的分配或分裂
    5、處理增刪改查請求

    RegionServer
    1.負責存儲HBase的實際數據
    2.管理分配給它的Region
    3.刷新緩存到HDFS
    4.維護Hlog
    5.執行壓縮
    6.負責處理Region分片

    Region: 實際存儲數據,HBase表會根據RowKey值被切分成不同的region存儲在RegionServer中,在一個RegionServer中可以有多個不同的region

    Hlog: 預寫日志,用于記錄HBase的修改記錄,寫數據時,數據會首先寫入內存經MemStore排序后才能刷寫到StoreFile,有可能引起數據丟失,為了解決這個問題,數據會先寫入Hlog,然后再寫入內存。在系統故障時,數據可以Hlog重建。

    Store: StoreFile存儲在Store中,一個Store對應HBase表中的一個列族。

    MemStore: 寫緩存,由于StoreFile中的數據要求是有序的,所以數據是先存儲在MemStore中,排好序后,等到達刷寫時機才會刷寫到StoreFile,每次刷寫都會形成一個新的StoreFile。StoreFile過多會影響性能,此時可進行compact操作

    StoreFile: 這是在磁盤上保存原始數據的實際的物理文件,是實際的存儲文件。StoreFile是以Hfile的形式存儲在HDFS的。每個 Store 會有一個或多個StoreFile,數據在每個 StoreFile 中都是有序的(按照Rowkey的字典順序排序)。

    3、Hbase數據模型

    數據模型圖:
    物理模型圖:

    • Name Space
      命名空間,類似于關系型數據庫的 DatabBase 概念,每個命名空間下有多個表。HBase有兩個自帶的命名空間,分別是 hbase 和 default,hbase 中存放的是 HBase 內置的表,default 表是用戶默認使用的命名空間。
    • Row
      HBase 表中的每行數據都由一個 RowKey 和多個 Column(列)組成,數據是按照 RowKey的字典順序存儲的,并且查詢數據時只能根據 RowKey 進行檢索,所以 RowKey 的設計十分重要。
    • Column
      HBase 表中的每行數據都由一個 RowKey 和多個 Column(列)組成,數據是按照 RowKey的字典順序存儲的,并且查詢數據時只能根據 RowKey 進行檢索,所以 RowKey 的設計十分重要。
    • Time Stamp
      用于標識數據的不同版本(version),每條數據寫入時,如果不指定時間戳,系統會自動為其加上該字段,其值為寫入 HBase 的時間。
    • Cell
      HBase 中通過 row 和 columns 確定的為一個存貯單元稱為 cell。
      由{rowkey, 列族:列, time Stamp} 唯一確定的單元。cell 中的數據是沒有類型的,全部是字節碼形式存貯(byte[]數組)。

    4、Hbase和hive的區別

    Hbase和Hive在大數據架構中處在不同位置,Hbase主要解決實時數據查詢問題,Hive主要解決海量數據處理和計算問題,一般是配合使用。

    Hbase: Hadoop database 的簡稱,也就是基于Hadoop數據庫,是一種NoSQL數據庫,主要適用于海量明細數據(十億、百億)的隨機實時查詢,如日志明細、交易清單、軌跡行為等。

    Hive:Hive是Hadoop數據倉庫,嚴格來說,不是數據庫,主要是讓開發人員能夠通過SQL來計算和處理HDFS上的結構化數據,適用于離線的批量數據計算。

    深入閱讀:一篇文章讓你了解Hive和HBase的區別

    5、Hbase特點

  • 大:一個表可以有數十億行,上百萬列;
  • 無模式:每行都有一個可排序的主鍵和任意多的列,列可以根據需要動態的增加,同一
    張表中不同的行可以有截然不同的列;
  • 面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索;
  • 稀疏:空(null)列并不占用存儲空間,表可以設計的非常稀疏;
  • 數據多版本:每個單元中的數據可以有多個版本,默認情況下版本號自動分配,是單元
    格插入時的時間戳;
  • 數據類型單一:Hbase 中的數據都是字符串,沒有類型。
  • 深入閱讀:可能是最易懂的Hbase架構原理解析

    6、數據同樣存在HDFS,為什么HBase支持在線查詢,且效率比Hive快很多

    1、KV存儲,rowkey查詢,
    2、blockCache讀緩存
    3、數據存儲按照rowkey字典排序,使用插值查找
    4、布隆過濾器改進查找次數

    7、Hbase適用場景

  • 寫密集型應用,每天寫入量巨大,而相對讀數量較小的應用,比如微信的歷史消息,游戲日志等等
  • 不需要復雜查詢條件且有快速隨機訪問的需求。HBase只支持基于rowkey的查詢,對于HBase來說,單條記錄或者小范圍的查詢是可以接受的,大范圍的查詢由于分布式的原因,可能在性能上有點影響,而對于像SQL的join等查詢,HBase無法支持。
  • 對性能和可靠性要求非常高的應用,由于HBase本身沒有單點故障,可用性非常高。 數據量較大,而且增長量無法預估的應用,HBase支持在線擴展,即使在一段時間內數據量呈井噴式增長,也可以通過HBase橫向擴展來滿足功能。
  • 結構化和半結構化的數據,基于Hbase動態列,稀疏存的特性。Hbase支持同一列簇下的列動態擴展,無需提前定義好所有的數據列,并且采用稀疏存的方式方式,在列數據為空的情況下不占用存儲空間。
  • 網絡安全業務數據帶有連續性,一個完整的攻擊鏈往往由N多次攻擊事件構成,在hive中,一次攻擊即為一條數據,無法體現數據的連續性。在Hbase里面,由于其多版本特性,對于任何一個字段,當數據更新后,其舊版本數據仍可訪問。所以一次攻擊事件可以存儲為一條數據,將多次攻擊日志疊加更新至此,大大減輕了業務開發人員的取數效率。
  • 8、RowKey的設計原則

  • 唯一性原則
    rowkey在設計上保證其唯一性。rowkey是按照字典順序排序存儲的,因此,設計rowkey的時候,要充分利用這個排序的特點,將經常讀取的數據存儲到一塊,將最近可能會被訪問的數據放到一塊。
  • 長度原則
    rowkey是一個二進制碼流,可以是任意字符串,最大長度 64kb ,實際應用中一般為10-100bytes,以byte[] 形式保存,一般設計成定長。建議越短越好,不要超過16個字節,原因如下:數據的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節,1000w行數據,光rowkey就要占用100*1000w=10億個字節,將近1G數據,這樣會極大影響HFile的存儲效率;MemStore將緩存部分數據到內存,如果rowkey字段過長,內存的有效利用率就會降低,系統不能緩存更多的數據,這樣會降低檢索效率。目前操作系統都是64位系統,內存8字節對齊,控制在16個字節,8字節的整數倍利用了操作系統的最佳特性。
  • 散列原則
    如果rowkey按照時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將rowkey的高位作為散列字段,由程序隨機生成,低位放時間字段,這樣將提高數據均衡分布在每個RegionServer,以實現負載均衡的幾率。如果沒有散列字段,首字段直接是時間信息,所有的數據都會集中在一個RegionServer上,這樣在數據檢索的時候負載會集中在個別的RegionServer上,造成熱點問題,會降低查詢效率。
    4)就近原則
    rowkey是按照字典序存儲,設計rowkey時可以將經常一起讀取的數據rowkey相鄰,在物理存儲時可以落在同一個region中,避免讀寫多個Region。
  • 深入閱讀:HBase之rowkey設計原則和方法

    9、HBase中scan和get的功能以及實現的異同?

    scan 方法:按指定的條件獲取一批記錄

    • setCaching 與 setBatch 方法提高速度(以空間換時間)。
    • setStartRow 與 setEndRow 來限定范圍([start, end]start 是閉區間, end 是開區間)。范圍越小,性能越高。
    • setFilter方法添加過濾器,這也是分頁、多條件查詢的基礎。

    get方法:按指定RowKey 獲取唯一一條記錄。Get 的方法處理分兩種:

    • 設置了 ClosestRowBefore 和沒有設置的 rowlock,主要是用來保證行的事務性,即每個 get 是以一個 row 來標記的,一個 row 中可以有很多 family 和 column。
    • 獲取當前rowkey下指定version的數據。

    10、Scan的setCache和setBatch

    setCache

    • 在默認情況下,如果你需要從hbase中查詢數據,在獲取結果ResultScanner時,hbase會在你每次調用ResultScanner.next()操作時對返回的每個Row執行一次RPC操作。
    • 即使你使用ResultScanner.next(int nbRows)時也只是在客戶端循環調用RsultScanner.next()操作,你可以理解為hbase將執行查詢請求以迭代器的模式設計,在執行next()操作時才會真正的執行查詢操作,而對每個Row都會執行一次RPC操作。
    • 因此顯而易見的就會想如果我對多個Row返回查詢結果才執行一次RPC調用,那么就會減少實際的通訊開銷。
    • 這個就是hbase配置屬性“hbase.client.scanner.caching”的由來,設置cache可以在hbase配置文件中顯示靜態的配置,也可以在程序動態的設置。
    • cache值得設置并不是越大越好,需要做一個平衡。
    • cache的值越大,則查詢的性能就越高,但是與此同時,每一次調用next()操作都需要花費更長的時間,因為獲取的數據更多并且數據量大了傳輸到客戶端需要的時間就越長,一旦你超過了maximum heap the client process 擁有的值,就會報outofmemoryException異常。
    • 當傳輸rows數據到客戶端的時候,如果花費時間過長,則會拋出ScannerTimeOutException異常。

    setBatch

    • 在cache的情況下,我們一般討論的是相對比較小的row,那么如果一個Row特別大的時候應該怎么處理呢?要知道cache的值增加,那么在client process 占用的內存就會隨著row的增大而增大。
    • 在HBase中同樣為解決這種情況提供了類似的操作:Batch。
    • 可以這么理解,cache是面向行的優化處理,batch是面向列的優化處理。
    • 它用來控制每次調用next()操作時會返回多少列,比如你設置setBatch(5),那么每一個Result實例就會返回5列,如果你的列數為17的話,那么就會獲得四個Result實例,分別含有5,5,5,2個列。

    11、HBase 寫流程

    ① Client 先訪問 zookeeper,找到 Meta 表,并獲取 Meta 表元數據。
    ② 確定當前將要寫入的數據所對應的 Region 和 RegionServer 服務器。
    ③ Client 向該 RegionServer 服務器發起寫入數據請求,然后 RegionServer 收到請求
    并響應。
    ④ Client 先把數據寫入到 HLog,以防止數據丟失。
    ⑤ 然后將數據寫入到 Memstore,在memstore中會對 rowkey進行排序。
    ⑥ 如果 HLog 和 Memstore 均寫入成功,則這條數據寫入成功
    ⑦ 如果 Memstore 達到閾值,會把 Memstore 中的數據 flush 到 Storefile 中。
    ⑧ 當 Storefile 越來越多,會觸發 Compact 合并操作,把過多的 Storefile 合并成一個大
    的 Storefile。
    ⑨ 當 Storefile 越來越大,Region 也會越來越大,達到閾值后,會觸發 Split 操作,將
    Region 一分為二。

    12、HBase 讀流程

    ① RegionServer 保存著 meta 表以及表數據,要訪問表數據,首先 Client 先去訪問zookeeper,從 zookeeper 里面獲取 meta 表所在的位置信息,即找到這個 meta 表在哪個RegionServer 上保存著。
    ② 接著 Client 通過剛才獲取到的 RegionServer 的 IP 來訪問 Meta 表所在的RegionServer,從而讀取到 Meta,進而獲取到 Meta 表中存放的元數據。
    ③ Client 通過元數據中存儲的信息,訪問對應的 RegionServer,然后掃描所在RegionServer 的 Memstore 和 Storefile 來查詢數據。
    ④ 最后 RegionServer 把查詢到的數據響應給 Client。

    深入閱讀:Hbase的數據讀寫流程

    13、HBase中Zookeeper的作用

  • hbase regionserver向zookeeper注冊,提供hbase regionserver狀態信息(是否在線)。
  • 存放Master管理的表的META元數據信息;表名、列名、key區間等。
  • Client訪問用戶數據之前需要首先訪問zookeeper中的META.表,根據META表找到用戶數據的位置去訪問,中間需要多次網絡操作,不過client端會做cache緩存。
  • Master沒有單點問題,HBase中可以啟動多個Master,通過Zookeeper的事件處理確保整個集群只有一個正在運行的Master。
  • 當RegionServer意外終止后,Master會通過Zookeeper感知到。
  • 14、StoreFile(HFile)合并

    在HBase中,每當memstore的數據flush到磁盤后,就形成一個storefile,當storefile的數量越來越大時,會嚴重影響HBase的讀性能 ,HBase內部的compact處理流程是為了解決MemStore Flush之后,storefile數太多,導致讀數據性能大大下降的一種自我調節手段,它會將文件按照策略進行合并,提升HBase的數據讀性能。

    作用

  • 合并文件
  • 清除刪除、過期、多余版本的數據
  • 提高讀寫數據的效率
  • HBase中實現了兩種compaction的方式:

    minor(小合并)

    Minor操作只用來做部分文件的合并操作以及超過生存時間TTL的數據,刪除標記數據、多版本數據不進行清除。

    觸發條件:
    把所有的文件都遍歷一遍之后每一個文件都去考慮。符合條件而進入待合并列表的文件由新的條件判斷:
    該文件 < (所有文件大小總和 - 該文件大小) * hbase.store.compaction.ratio比例因子。

    major(大合并)

    Major操作是對Region下的Store下的所有StoreFile執行合并操作,順序重寫全部數據,重寫過程中會略過做了刪除標記的數據,最終合并出一個HFile文件,并將原來的小文件刪除。會占用大量IO資源。

    觸發條件:
    Major是Minor升級而來的。如果本次Minor Compaction包含所有文件,且達到了足夠的時間間隔,則會被升級為Major Compaction。判斷時間間隔根據以下兩個配置項:

    hbase.hregion.majorcompaction:major Compaction發生的周期,單位是毫秒,默認值是7天。

    hbase.hregion.majorcompaction.jitter majorCompaction:周期抖動參數,0~1.0的一個指數。調整這個參數可以讓Major Compaction的發生時間更靈活,默認值是0.5。

    雖然有以上機制控制Major Compaction的發生時機,但是由于Major
    Compaction時對系統的壓力還是很大的,所以建議關閉自動Major Compaction,采用手動觸發的方式。

    合并流程

  • 獲取需要合并的HFile列表。

  • 由列表創建出StoreFileScanner。HRegion會創建出一個Scanner,用這個Scanner來讀取本次要合并 的所有StoreFile上的數據。

  • 把數據從這些HFile中讀出,并放到tmp目錄(臨時文件 夾)。
    HBase會在臨時目錄中創建新的HFile,并使用之前建立的Scanner 從舊HFile上讀取數據,放入新HFile。以下兩種數據不會被讀取出來:
    1)如果數據過期了(達到TTL所規定的時間),那么這些數據不會 被讀取出來。
    2)如果是majorCompaction,那么數據帶了墓碑標記也不會被讀取 出來。

  • 用合并后的HFile來替換合并前的那些HFile。
    最后用臨時文件夾內合并后的新HFile來替換掉之前的那些HFile文 件。過期的數據由于沒有被讀取出來,所以就永遠地消失了。如果本次 合并是Major Compaction,那么帶有墓碑標記的文件也因為沒有被讀取 出來,就真正地被刪除掉了。

  • 15、Hbase協處理器

    Hbase 作為列族數據庫最經常被人詬病的特性包括:無法輕易建立“二級索引”,難以執行求和、計數、排序等操作。比如,在0.92版本前,統計總行數需要使用Counter方法,執行一次MapReduce Job才能得到。雖然 HBase 在數據存儲層中集成 了 MapReduce,能夠有效用于數據表的分布式計算。然而在很多情況下,做一些簡單的相加或者聚合計算的時候,如果直接將計算過程放置在regionServer端,能夠減少通訊開銷,從而獲得很好的性能提升。于是,HBase在0.92之后引入了協處理器(coprocessors),能夠輕易建立二次索引、復雜過濾器、求和、計數以及訪問控制等。

    協處理器包括observer和endpoint

    observer

    類似于傳統數據庫中的觸發器,當數據寫入的時候會調用此類協處理器中的邏輯。主要的作用是當執行被監聽的一個操作的時候,可以觸發另一個我們需要的操作,比如說監聽數據庫數據的增刪過程,我們可以在hbase數據庫插入數據或者刪除數據之前或之后進行一系列的操作。

    二級索引基于此觸發器構建。

    Endpoint

    類似傳統數據庫中的存儲過程,客戶端可以調用Endpoint執行一段 Server 端代碼,并將 Server 端代碼的結果返回給客戶端進一步處理,常用于Hbase的聚合操作。 min、max、avg、sum、distinct、group by

    協處理加載方式

    協處理器的加載方式有兩種,我們稱之為靜態加載方式(Static Load)和動態加載方式 (Dynamic Load)。靜態加載的協處理器稱之為 System Coprocessor,動態加載的協處理器稱 之為 Table Coprocessor

    靜態加載:
    通過修改 hbase-site.xml 這個文件來實現,啟動全局 aggregation,能過操縱所有的表上的數據。只需要添加如下代碼:

    <property><name>hbase.coprocessor.user.region.classes</name><value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value> </property>

    為所有 table 加載了一個 cp class,可以用”,”分割加載多個 class
    注意: 該方法因為是全局的,所以在實際應用中并不是很多,而另一種方法用的會更多一些

    動態加載
    啟用表 aggregation,只對特定的表生效。通過 HBase Shell 來實現。
    ①disable 指定表。hbase> disable ‘table名’;
    ②添加 aggregation

    hbase> alter 'mytable', METHOD => 'table_att','coprocessor'=> '|org.apache.Hadoop.hbase.coprocessor.AggregateImplementation||'

    ③重啟指定表 hbase> enable ‘table名’

    16、WAL機制

    數據在寫入HBase的時候,先寫WAL,再寫入緩存。通常情況下寫緩存延遲很低,WAL機制一方面是為了確保數據即使寫入緩存后數據丟失也可以通過WAL恢復,另一方面是為了集群之間的復制。默認WAL機制是開啟的,并且使用的是同步機制寫WAL。

    如果業務不特別關心異常情況下部分數據的丟失,而更關心數據寫入吞吐量,可考慮關閉WAL寫,這樣可以提升2~3倍數據寫入的吞吐量。

    如果業務不能接受不寫WAL,但是可以接受WAL異步寫入,這樣可以帶了1~2倍性能提升。

    HBase中可以通過設置WAL的持久化等級決定是否開啟WAL機制、以及HLog的落盤方式。

    WAL的持久化等級分為如下四個等級:

    • SKIP_WAL:只寫緩存,不寫HLog日志。這種方式因為只寫內存,因此可以極大的提升寫入性能,但是數據有丟失的風險。在實際應用過程中并不建議設置此等級,除非確認不要求數據的可靠性。
    • ASYNC_WAL:異步將數據寫入HLog日志中。
    • SYNC_WAL:同步將數據寫入日志文件中,需要注意的是數據只是被寫入文件系統中,并沒有真正落盤,默認。
    • FSYNC_WAL:同步將數據寫入日志文件并強制落盤。最嚴格的日志寫入等級,可以保證數據不會丟失,但是性能相對比較差。

    除了在創建表的時候直接設置WAL存儲級別,也可以通過客戶端設置WAL持久化等級,代碼:put.setDurability(Durability.SYNC_WAL);

    17、Memstore

    hbase為了保證隨機讀取的性能,所以storefile的數據按照rowkey的字典序存儲。當客戶端的請求在到達regionserver之后,為了保證寫入rowkey的有序性,不能將數據立刻寫入到hfile中,而是將每個變更操作保存在內存中,也就是memstore中。memstore能夠保證內部數據有序。當某個memstore達到閾值后,會將Region的所有memstore都flush到hfile中(Flush操作為Region級別),這樣能充分利用hadoop寫入大文件的性能優勢,提高寫入性能。

    由于memstore是存放在內存中,如果regionserver宕機,會導致內存中數據丟失。所有為了保證數據不丟失,hbase將更新操作在寫入memstore之前會寫入到一個WAL中。WAL文件是追加、順序寫入的,WAL每個regionserver只有一個,同一個regionserver上所有region寫入同一個的WAL文件。這樣當某個regionserver失敗時,可以通過WAL文件,將所有的操作順序重新加載到memstore中。

    主要作用:

    • 更新數據存儲在 MemStore 中,使用 LSM(Log-Structured Merge Tree)數據結構存儲,在內存內進行排序整合。即保證寫入數據有序(HFile中數據都按照RowKey進行排序),同時可以極大地提升HBase的寫入性能。

    • 作為內存緩存,讀取數據時會優先檢查 MemStore,根據局部性原理,新寫入的數據被訪問的概率更大。

    • 在持久化寫入前可以做某些優化,例如:保留數據的版本設置為1,持久化只需寫入最新版本。

    如果一個 HRegion 中 MemStore 過多(Column family 設置過多),每次 flush 的開銷必然會很大,并且生成大量的 HFile 影響后續的各項操作,因此建議在進行表設計的時候盡量減少 Column family 的個數。

    用戶可以通過shell命令分別對一個 Table 或者一個 Region 進行 flush:

    hbase> flush 'TABLENAME' hbase> flush 'REGIONNAME'

    相關配置

    hbase.hregion.memstore.flush.size
    默認值:128M
    MemStore 最大尺寸,當 Region 中任意一個 MemStore 的大小(壓縮后的大小)達到了設定值,會觸發 MemStore flush。

    hbase.hregion.memstore.block.multiplier
    默認值:2
    Region 級別限制,當 Region 中所有 MemStore 的大小總和達到了設定值(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默認 2* 128M = 256M),會觸發 MemStore flush。

    hbase.regionserver.global.memstore.upperLimit
    默認值:0.4
    Region Server 級別限制,當一個 Region Server 中所有 MemStore 的大小總和達到了設定值(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默認 0.4 * RS堆內存大小),會觸發Region Server級別的MemStore flush。

    hbase.regionserver.global.memstore.lowerLimit
    默認值:0.38
    與 hbase.regionserver.global.memstore.upperLimit 類似,區別是:當一個 Region Server 中所有 MemStore 的大小總和達到了設定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默認 0.38 * RS堆內存大小),會觸發部分 MemStore flush。

    Flush 順序是按照 Region 的總 MemStore 大小,由大到小執行,先操作 MemStore 最大的 Region,再操作剩余中最大的 Region,直至總體 MemStore 的內存使用量低于設定值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize)。

    hbase.regionserver.maxlogs
    默認值:32
    當一個 Region Server 中 HLog 數量達到設定值,系統會選取最早的一個 HLog 對應的一個或多個 Region 進行 flush。

    當增加 MemStore 的大小以及調整其他的 MemStore 的設置項時,也需要去調整 HLog 的配置項。否則,WAL的大小限制可能會首先被觸發。因而,將利用不到其他專門為Memstore而設計的優化。

    需要關注的 HLog 配置是 HLog 文件大小,由參數 hbase.regionserver.hlog.blocksize 設置(默認512M),HLog 大小達到上限,或生成一個新的 HLog

    通過WAL限制來觸發Memstore的flush并非最佳方式,這樣做可能會會一次flush很多Region,盡管“寫數據”是很好的分布于整個集群,進而很有可能會引發flush“大風暴”。

    hbase.regionserver.optionalcacheflushinterval
    默認值:3600000
    HBase 定期刷新 MemStore,默認周期為1小時,確保 MemStore 不會長時間沒有持久化。為避免所有的 MemStore 在同一時間都進行 flush,定期的 flush 操作有 20000 左右的隨機延時。

    Memstore Flush

    為了減少 flush 過程對讀寫的影響,HBase 采用了類似于兩階段提交的方式,將整個 flush 過程分為三個階段:

    • prepare 階段:遍歷當前 Region 中的所有 MemStore,將 MemStore 中當前數據集 kvset 做一個快照 snapshot,然后再新建一個新的 kvset,后期的所有寫入操作都會寫入新的 kvset 中。整個 flush 階段讀操作讀 MemStore 的部分,會分別遍歷新的 kvset 和 snapshot。prepare 階段需要加一把 updateLock 對寫請求阻塞,結束之后會釋放該鎖。因為此階段沒有任何費時操作,因此持鎖時間很短。

    • flush 階段:遍歷所有 MemStore,將 prepare 階段生成的 snapshot 持久化為臨時文件,臨時文件會統一放到目錄.tmp下。這個過程因為涉及到磁盤IO操作,因此相對比較耗時。

    • commit 階段:遍歷所有的 MemStore,將 flush 階段生成的臨時文件移到指定的 Column family 目錄下,生成對應的 Storefile(HFile) 和 Reader,把 Storefile 添加到 Store 的 Storefiles 列表中,最后再清空 prepare 階段生成的 snapshot。

    18、BloomFilter

    布隆過濾器是hbase中的高級功能,它能夠減少特定訪問模式(get/scan)下的查詢時間。不過由于這種模式增加了內存和存儲的負擔,所以被默認為關閉狀態。

    hbase支持如下類型的布隆過濾器:

  • ROW 行鍵使用布隆過濾器
  • ROWCOL 行加列使用布隆過濾器,粒度更細。
  • 如果用戶隨機查找一個rowkey,位于某個region中兩個開始rowkey之間的位置。對于hbase來說,它判斷這個行鍵是否真實存在的唯一方法就是加載這個region,并且掃描它是否包含這個鍵。當我們get數據時,hbase會加載很多塊文件。

    采用布隆過濾器后,它能夠準確判斷該StoreFile的所有數據塊中,是否含有我們查詢的數據,從而減少不必要的塊加載,增加hbase集群的吞吐率。

    1、布隆過濾器的存儲在哪
    開啟布隆后,HBase會在生成StoreFile時包含一份布隆過濾器結構的數據,稱其為MetaBlock;MetaBlock與DataBlock(真實的KeyValue數據)一起由LRUBlockCache維護。所以,開啟bloomfilter會有一定的存儲及內存cache開銷。大多數情況下,這些負擔相對于布隆過濾器帶來的好處是可以接受的。

    2、采用布隆過濾器后,如何get數據
    在讀取數據時,hbase會首先在布隆過濾器中查詢,根據布隆過濾器的結果,再在MemStore中查詢,最后再在對應的HFile中查詢。

    3、采用ROW還是ROWCOL

    • 如果用戶只做行掃描,使用ROW即可,使用更加細粒度的ROWCOL會增加內存的消耗。
    • 如果大多數隨機查詢使用行加列作為查詢條件,Bloomfilter需要設置為ROWCOL。
    • 如果不確定業務查詢類型,設置為row。

    19、BlockCache讀緩存


    一個RegionServer只有一個BlockCache。用來優化讀取性能,不是數據存儲的必須組成部分。

    BlockCache名稱中的Block指的是HBase的Block。BlockCache的工作原理跟其他緩存一樣:
    讀請求到HBase之后先嘗試查詢BlockCache,如果獲取不到就去StoreFile和 Memstore中去獲取。如果獲取到了則在返回數據的同時把Block塊緩存到BlockCache中。BlockCache默認是開啟的。
    BlockCache的實現方案有以下幾種:

    LRUBlock Cache:

    近期最少使用算法。讀出來的block會被放到BlockCache中待 下次查詢使用。當緩存滿了的時候,會根據LRU的算法來淘汰block。

    SlabCache

    這是一種堆外內存的解決方案。不屬于JVM管理的內存范圍,說白了,就是原始的內存區域了。回收堆外內存的時候JVM幾乎不會停頓,可以避免GC過程中遇見的系統卡頓與異常。

    Bucket Cache

    BucketCache借鑒SlabCache也用上了堆外內存。不過它以下自己的特點:

    • 相比起只有2個區域的SlabeCache,BucketCache一上來就分配了 14種區域。這 14種區域分別放的是大小為4KB、8KB、16KB、32KB、40KB、 48KB、56KB、64KB、96KB、128KB、192KB、256KB、384KB、 512KB的Block。而且這個種類列表還是可以手動通過設置 hbase.bucketcache.bucket.sizes屬性來定義

    • BucketCache的存儲不一定要使用堆外內存,是可以自由在3種存 儲介質直接選擇:堆(heap)、堆外(offheap)、文件 (file)。通過設置hbase.bucketcache.ioengine為heap、 offfheap或者file來配置。

    • 每個Bucket的大小上限為最大尺寸的block * 4,比如可以容納 的最大的Block類型是512KB,那么每個Bucket的大小就是512KB * 4 = 2048KB。

    • 系統一啟動BucketCache就會把可用的存儲空間按照每個Bucket 的大小上限均分為多個Bucket。如果劃分完的數量比你的種類還 少,比如比14(默認的種類數量)少,就會直接報錯,因為每一 種類型的Bucket至少要有一個Bucket。

    組合模式

    把不同類型的Block分別放到 LRUCache和BucketCache中。
    Index Block和Bloom Block會被放到LRUCache中。Data Block被直接放到BucketCache中,所以數據會去LRUCache查詢一下,然后再去 BucketCache中查詢真正的數據。其實這種實現是一種更合理的二級緩存,數據從一級緩存到二級緩存最后到硬盤,從小到大,存儲介質也由快到慢。考慮到成本和性能的組合,比較合理的介質是:LRUCache使用內存->BuckectCache使用SSD->HFile使用機械硬盤。

    BlockCache 壓縮

    在開啟此功能后,數據塊會以它們on-disk的形式緩存到BlockCache。與默認的模式不同點在于:默認情況下,在緩存一個數據塊時,會先解壓縮然后存入緩存。而lazy BlockCache decompression 直接將壓縮的數據塊存入緩存。

    如果一個RegionServer存儲的數據過多,無法適當的將大部分數據放入緩存,則開啟這個功能后,可以提升50%的吞吐量,30%的平均延遲上升,增加80%垃圾回收,以及2%的整體CPU負載。

    壓縮默認關閉,若要開啟,可以在hbase-site.xml文件里設置 hbase.block.data.cachecompressed 為 true

    20、Region拆分

    一個Region就是一個表的一段Rowkey的數據集合。一旦 Region 的負載過大或者超過閾值時,它就會被分裂成兩個新的 Region。Region的拆分分為自動拆分和手動拆分。自動拆分可以采用不同的策略。

    拆分流程

    這個過程是由 RegionServer 完成的,其拆分流程如下。

  • 將需要拆分的 Region下線,阻止所有對該 Region 的客戶端請求,Master 會檢測到 Region 的狀態為 SPLITTING。
  • 將一個 Region 拆分成兩個子 Region,先在父 Region下建立兩個引用文件,分別指向 Region 的首行和末行,這時兩個引用文件并不會從父 Region 中復制數據。
  • 之后在 HDFS 上建立兩個子 Region 的目錄,分別復制上一步建立的引用文件,每個子 Region 分別占父 Region 的一半數據。復制登錄完成后刪除兩個引用文件。
  • 完成子 Region 創建后,向 Meta 表發送新產生的 Region 的元數據信息。
  • 將 Region 的拆分信息更新到 HMaster,并且每個 Region 進入可用狀態。
  • 自動拆分

    Region的自動拆分主要根據拆分策略進行,主要有以下幾種拆分策略:

    • ConstantSizeRegionSplitPolicy
      0.94版本前唯一拆分策略,按照固定大小來拆分Region。Region 中的最大Store大于設置閾值(hbase.hregion.max.filesize:默認10GB)觸發拆分。拆分點為最大Store的rowkey的順序中間值。
      弊端: 切分策略對于大表和小表沒有明顯的區分。閾值(hbase.hregion.max.filesize)設置較大對大表友好,但小表有可能不會觸發分裂,極端情況下可能就1個。如果設置較小則對小表友好,但大表就會在整個集群產生大量的region,占用集群資源。

    • IncreasingToUpperBoundRegionSplitPolicy
      0.94版本~2.0版本默認切分策略。切分策略稍微有點復雜,基于ConstantSizeRegionSplitPolicy思路,一個region大小大于設置閾值就會觸發切分。但是這個閾值并不是固定值,而是會在一定條件下不斷調整,調整規則和region所屬表在當前regionserver上的region個數有關系.

    • KeyPrefixRegionSplitPolicy
      在IncreasingToUpperBoundRegionSplitPolicy的基礎上增加了對拆分點(splitPoint,拆分點就是Region被拆分處的rowkey)的自定義,可以將rowKey的前多少位作為前綴。保證相同前綴的rowkey拆分至同一個region中。

    • DelimitedKeyPrefixRegionSplitPolicy
      KeyPrefixRegionSplitPolicy根據rowkey的固定前幾位來進行判 斷,而DelimitedKeyPrefixRegionSplitPolicy是根據分隔符來判斷的。比如你定義了前綴分隔符為_,那么host1_001和host12_999的前綴 就分別是host1和host12。

    • SteppingSplitPolicy
      2.0版本默認切分策略,相比 IncreasingToUpperBoundRegionSplitPolicy 簡化,基于當前表的region個數進行規劃,對于大集群中的大表、小表會比 IncreasingToUpperBoundRegionSplitPolicy更加友好,小表不會再產生大量的小region,而是適可而止。

    • BusyRegionSplitPolicy

    • 此前的拆分策略都沒有考慮熱點問題。熱點問題就是數據庫中的Region被訪問的頻率并不一樣,某些Region在短時間內被訪問的很頻繁,承載了很大的壓力,這些Region就是熱點Region。
      它會通過拆分熱點Region來緩解熱點Region壓力,但也會帶來很多不確定性因素,因為無法確定下一個被拆分的Region是哪個。

    • DisabledRegionSplitPolicy
      關閉策略,手動拆分。可控制拆分時間,選擇集群空閑時間

    手動拆分

    調用hbase shell的 split方法,split的調用方式如下:

    split 'regionName' # format: 'tableName,startKey,id'

    比如:

    split 'test_table1,c,1476406588669.96dd8c68396fda69'

    這個就是把test_table1,c,1476406588669.96dd8c68396fda69這個 Region從新的拆分點999處拆成2個Region。

    21、Region合并

    如果有很多Region,則MemStore也過多,數據頻繁從內存Flush到HFile,影響用戶請求,可能阻塞該Region服務器上的更新操作。過多的 Region 會增加服務器資源的負擔。當刪了大量的數據,或Region拆分過程中產生了過多小Region,這時可以Region合并,減輕RegionServer資源負擔。

    合并過程

  • 客戶端發起 Region 合并處理,并發送 Region 合并請求給 Master。
  • Master 在 Region 服務器上把 Region 移到一起,并發起一個 Region 合并操作的請求。
  • Region 服務器將準備合并的 Region下線,然后進行合并。
  • 從 Meta 表刪除被合并的 Region 元數據,新的合并了的 Region 的元數據被更新寫入 Meta 表中。
  • 合并的 Region 被設置為上線狀態并接受訪問,同時更新 Region 信息到 Master。
  • Merger類手動合并

    合并通過使用org.apache.hadoop.hbase.util.Merge類來實現。
    例如把以下兩個Region合并:

    test_table1,b,1476406588669.39eecae03539ba0a63264c24130c2cb1. test_table1,c,1476406588669.96dd8c68396fda694ab9b0423a60a4d9.

    就需要在Linux下(不需要進入hbase shell)執行以下命令:

    hbase org.apache.hadoop.hbase.util.Merge test_table1 test_table1,b,1476406588669.39eecae03539ba0a63264c24130c2cb1. test_table1,c,1476406588669.96dd8c68396fda694ab9b0423a60a4d9.

    此方式需要停止整個Hbase集群,所以后來又增加了online_merge(熱合并)。

    熱合并

    hbase shell提供了一個命令叫online_merge,通過這個方法可以進行熱合并,無需停止整個Hbase集群。

    假設要合并以下兩個Region:

    test_table1,a,1476406588669.d1f84781ec2b93224528cbb79107ce12. test_table1,b,1476408648520.d129fb5306f604b850ee4dc7aa2eed36.

    online_merge的傳參是Region的hash值。只需在hbase shell 中執行以下命令:

    merge_region 'd1f84781ec2b93224528cbb79107ce12', 'd129fb5306f604b850ee4dc7aa2eed36'

    22、Region 負載均衡

    當 Region 分裂之后,Region 服務器之間的 Region 數量差距變大時,Master 便會執行負載均衡來調整部分 Region 的位置,使每個 Region 服務器的 Region 數量保持在合理范圍之內,負載均衡會引起 Region 的重新定位,使涉及的 Region 不具備數據本地性。

    Region 的負載均衡由 Master 來完成,Master 有一個內置的負載均衡器,在默認情況下,均衡器每 5 分鐘運行一次,用戶可以配置。負載均衡操作分為兩步進行:首先生成負載均衡計劃表, 然后按照計劃表執行 Region 的分配。

    執行負載均衡前要明確,在以下幾種情況時,Master 是不會執行負載均衡的。

    • 均衡負載開關關閉。
    • Master 沒有初始化。
    • 當前有 Region 處于拆分狀態。
    • 當前集群中有 Region 服務器出現故障。

    Master 內部使用一套集群負載評分的算法,來評估 HBase 某一個表的 Region 是否需要進行重新分配。這套算法分別從 Region 服務器中 Region 的數目、表的 Region 數、MenStore 大小、 StoreFile 大小、數據本地性等幾個維度來對集群進行評分,評分越低代表集群的負載越合理。

    確定需要負載均衡后,再根據不同策略選擇 Region 進行分配,負載均衡策略有三種,如下表所示。

    策略原理
    RandomRegionPicker隨機選出兩個 Region 服務器下的 Region 進行交換
    LoadPicker獲取 Region 數目最多或最少的兩個 Region 服務器,使兩個 Region 服務器最終的 Region 數目更加平均
    LocalityBasedPicker選擇本地性最強的 Region

    根據上述策略選擇分配 Region 后再繼續對整個表的所有 Region 進行評分,如果依然未達到標準,循環執行上述操作直至整個集群達到負載均衡的狀態。

    23、Region預分區

    Hbase建表時默認單region,所有數據都會寫入此region,超過閾值(hbase.Region.max.filesize,默認10G)會此region會進行拆分,分成2個region。在此過程中,會產生三個問題:

  • 拆分后如果數據往一個region上寫,會造成熱點問題。
  • 拆分過程中會消耗大量的IO資源。
  • 拆分過程中當前region會下線,影響訪問服務。
  • 基于此我們可以在建表時進行預分區,創建多個空region,減少由于split帶來的資源消耗,從而提高HBase的性能。
    預分區時會確定每個region的起始和終止rowky,rowkey設計時確保均勻的命中各個region,就不會存在寫熱點問題。當然隨著數據量的不斷增長,該split的還是要進行split。

    24、一張表中定義多少個 Column Family 最合適

    Column Family劃分標準一般根據數據訪問頻度,如一張表里有些列訪問相對頻繁,而另一些列訪問很少,這時可以把這張表劃分成兩個列族,分開存儲,提高訪問效率。

    25、為什么不建議在 HBase 中使用過多的列族

    HBase 中每張表的列族個數建議設在1~3之間,列族數過多可能會產生以下影響:

    對Flush的影響
    在 HBase 中,數據首先寫入memStore 的,每個列族都對應一個store,store中包含一個MemStore。列族過多將會導致內存中存在越多的MemStore;而MemStore在達到閾值后會進行Flush操作在磁盤生產一個hFile文件。列族越多導致HFile越多。

    由于Flush操作是Region 級別的,即Region中某個MemStore被Flush,同一個Region的其他MemStore也會進行Flush操作。當列族之間數據不均勻,比如一個列族有100W行,一個列族只有10行,會產生很多很多小文件,而且每次 Flush 操作也涉及到一定的 IO 操作。
    ?
    此外列族數過多可能會觸發RegionServer級別的Flush操作;這將會阻塞RegionServer上的更新操作,且時間可能會達到分鐘級別。

    對Split的影響
    當HBase表中某個Region過大會觸發split拆分操作。如果有多個列族,且列族間數據量相差較大,這樣在Region Spli時會導致原本數據量很小的HFil文件進一步被拆分,從而產生更多的小文件。

    對 Compaction 的影響
    目前HBase的Compaction操作也是Region級別的,過多的列族且列族間數據量相差較大,也會產生不必要的 IO。

    對HDFS的影響
    HDFS 其實對一個目錄下的文件數有限制的。列族數過多,文件數可能會超出HDFS的限制。小文件問題也同樣會出現。

    對RegionServer內存的影響
    一個列族在RegionServer中對應于一個 MemStore。每個MemStore默認占用128MB的buffer。如果列族過多,MemStore會占用RegionServer大量內存。

    26、直接將時間戳作為行健,在寫入單個region時會發生熱點問題,為什么

    region 中的 rowkey 是有序存儲,若時間比較集中。就會存儲到一個 region 中,這樣一個 region 的數據變多,其它的 region 數據很少,加載數據就會很慢,直到 region 分裂,此問題才會得到緩解。

    27、HBase中region太小和region太大的影響

    hbase.hregion.max.filesize:此參數定義了單個region的最大數據量。

    1)當region太小,觸發split的機率增加,split過程中region會下線,影響訪問服務。

    2)當region太大,由于長期得不到split,會發生多次compaction,將數據讀一遍并重寫一遍到 hdfs 上,占用IO。降低系統的穩定性與吞吐量。

    hbase數據會首先寫入MemStore,超過配置后會flush到磁盤成為StoreFile,當StoreFile的數量超過配置之后,會啟動compaction,將他們合并為一個大的StoreFile。

    當合并后的Store大于max.filesize時,會觸發分隔動作,將它切分為兩個region。hbase.hregion.max.filesize不宜過大或過小,經過實戰,
    生產高并發運行下,最佳大小5-10GB!

    推薦關閉某些重要場景的hbase表的major_compact!在非高峰期的時候再去調用major_compact,這樣可以減少split的同時,顯著提供集群的性能,吞吐量、非常有用。

    28、每天百億數據如何寫入Hbase

    1)百億數據:證明數據量非常大;
    2)存入HBase:證明是跟HBase的寫入數據有關;
    3)保證數據的正確:要設計正確的數據結構保證正確性;
    4)在規定時間內完成:對存入速度是有要求的。
    解決思路:
    1)假設一整天60x60x24 = 86400秒都在寫入數據,那么每秒的寫入條數高達100萬條,HBase當然是支持不了每秒百萬條數據的,
    所以這百億條數據可能不是通過實時地寫入,而是批量地導入。批量導入推薦使用BulkLoad方式,性能是普通寫入方式幾倍以上;
    2)存入HBase:普通寫入是用JavaAPI put來實現,批量導入推薦使用BulkLoad;
    3)保證數據的正確:這里需要考慮RowKey的設計、預建分區和列族設計等問題;
    4)還有region熱點的問題,如果你的hbase數據不是那種每天增量的數據,建議跑個mapreduce對你的數據進行各評判,看看如何能將數據盡可能均勻的分配到每個region中,當然這需要預先分配region

    29、HBase集群安裝注意事項?

    ① HBase需要HDFS的支持,因此安裝HBase前確保Hadoop集群安裝完成;
    ② HBase需要ZooKeeper集群的支持,因此安裝HBase前確保ZooKeeper集群安裝完成;
    ③ 注意HBase與Hadoop的版本兼容性;
    ④ 注意hbase-env.sh配置文件和hbase-site.xml配置文件的正確配置;
    ⑤ 注意regionservers配置文件的修改;
    ⑥ 注意集群中的各個節點的時間必須同步,否則啟動HBase集群將會報錯。

    30、Hbase數據熱點問題

    一、出現熱點問題原因

  • hbase的中的數據是按照字典序排序的,當大量連續的rowkey集中寫在個別的region,各個region之間數據分布不均衡;
  • 創建表時沒有提前預分區,創建的表默認只有一個region,大量的數據寫入當前region;
  • 創建表已經提前預分區,但是設計的rowkey沒有規律可循
  • 二、如何解決熱點問題

  • 隨機數+業務主鍵,如果想讓最近的數據快速get到,可以將時間戳加上
  • Rowkey設計越短越好,不要超過10-100個字節
  • 映射regionNo,這樣既可以讓數據均勻分布到各個region中,同時可以根據startKey和endKey可以get到同一批數據。
  • 31、HBase宕機恢復流程

    宕機分為 Master 宕機和 regionServer 宕機

    Master 宕機恢復

    1、Master主要負責實現集群的負載均衡和讀寫調度,沒有單點問題,所以集群中可以存在多個Master節點。
    2、通過熱備方式實現Master高可用,并在zookeeper上進行注冊
    3、active master會接管整個系統的元數據管理任務,zk以及meta表中的元數據,相應用戶的管理指令,創建、刪除、修改,merge region等

    regionServer宕機恢復

    集群中一臺RegionServer宕機并不會導致已經寫入的數據丟失,HBase采用WAL機制保證,即使意外宕機導致Memstore緩存數據沒有落盤,也可以通過HLog日志恢復。 RegionServer宕機一定程度上會影響業務方的讀寫請求,因為zookeeper感知到RegionServer宕機事件是需要一定時間的,這段時間默認會有3min。

    引起RegionServer宕機的原因各種各樣,Full GC、網絡異常、官方Bug導致(close wait端口未關閉)等。

    一旦RegionServer發生宕機,Zookeeper感知后會通知Master,Master首先會將這臺RegionServer上所有Region移到其他RegionServer上,再將HLog分發給其他RegionServer進行回放,完成之后再修改路由,業務方的讀寫才會恢復正常。整個過程都是自動完成的,并不需要人工介入。

    宕機原因
    1、Full Gc引起長時間停頓超過心跳時間
    2、HBase對Jvm堆內存管理不善,未合理使用堆外內存
    3、Jvm啟動參數配置不合理
    4、業務寫入或吞吐量太大
    5、網絡異常導致超時或RegionServer斷開集群連接

    宕機檢測
    通過Zookeeper實現, 正常情況下RegionServer會周期性向Zookeeper發送心跳,一旦發生宕機,心跳就會停止,超過一定時間(SessionTimeout)Zookeeper就會認為RegionServer宕機離線,并將該消息通知給Master。

    具體流程

  • master通過zk實現對RegionServer的宕機檢測。RegionServer會周期性的向zk發送心跳,超過一定時間,zk會認為RegionServer離線,發送消息給master。

  • master重新分配宕機regionserver上的所有region,regionserver宕機后,所有region處于不可用狀態,所有路由到這些region上的請求都會返回異常。 異常情況比較短暫,master會將這些region分配到其它regionserver上。

  • 將HLog日志分分配至其他regionserver中,回放HLog日志補救數據。

  • 恢復完成后修改路由,對外提供讀寫服務。

    深入閱讀:HBase宕機恢復

  • 32、HBase性能優化

    HDFS調優

    Hbase基于HDFS存儲,首先需要進行HDFS的相關優化。優化內容詳見《大數據面試題整理-HDFS篇》

    集群性能優化

  • 高可用: 在 HBase 中 Master 負責監控 RegionServer 的生命周期,均衡 RegionServer 的負載,如果 Master 掛掉了,那么整個 HBase 集群將陷入不健康的狀態,并且此時的工作狀態并不會維持太久。生產環境推薦開啟高可用。
  • hbase.regionserver.handler.count: rpc請求的線程數量,默認值是10,生產環境建議使用100。
  • hbase.master.distributed.log.splitting:默認值為true,建議設為false。關閉hbase的分布式日志切割,在log需要replay時,由master來負責重放
  • hbase.snapshot.enabled:快照功能,默認是false(不開啟),某些關鍵的表建議設為true。
  • hbase.hregion.memstore.flush.size:默認值128M,單位字節,一旦有memstore超過該值將被flush,如果regionserver的jvm內存比較充足(16G以上),可以調整為256M。
  • hbase.regionserver.lease.period:默認值60000(60s),客戶端連接regionserver的租約超時時間,客戶端必須在這個時間內匯報,否則則認為客戶端已死掉。這個最好根據實際業務情況進行調整
  • hfile.block.cache.size:默認值0.25,regionserver的block cache的內存大小限制,在偏向讀的業務中,可以適當調大該值。
  • 表層面優化

  • 預分區: 在建表時進行預分區,創建多個空region,減少由于split帶來的資源消耗,從而提高HBase的性能。確定每個region的起始和終止rowky,rowkey設計時確保均勻的命中各個region,降低熱點問題發生的概率。
  • RowKey 設計: 唯一性原則、長度原則、散列原則、就近原則。
  • 列族不可過多: 一般1-3個最好
  • 關閉自動Major: 在非高峰期的時候再去調用major_compact,這樣可以減少split的同時,顯著提供集群的性能,吞吐量、非常有用。
  • 合并小Region: 過多的 Region 會增加服務器資源的負擔。可以定期合并小Region,減輕RegionServer資源負擔。
  • 設置最大版本: 創建表的時候,可根據需求設置表中數據的最大版本,如果只需要保存最新版本的數據,那么可以設置setMaxVersions(1)。
  • 設置過期時間TTL: 創建表的時候,可以設置表中數據的存儲生命期,過期數據將自動標記刪除,例如如果只需要存儲最近兩天的數據,那么可以設置setTimeToLive(2 * 24 * 60 * 60)。
  • 小表可以放進內存: 創建表的時候,高頻率訪問的小表可以通過HColumnDescriptor.setInMemory(true)將表放到RegionServer的緩存中。
  • 調整blocksize: 配置HFile中block塊的大小,默認64KB。blocksize影響HBase讀寫數據的效率。
    1)blocksize越大,配置壓縮算法,壓縮的效率就越好,有利于提升寫入性能;
    2)但是由于讀數據以block塊為單位,所以越大的block塊,隨機讀的性能較差。
    3)如果要提升寫入的性能,一般擴大到128kb或者256kb,可以提升寫數據的效率,也不會太大影響隨機讀性能。
  • 讀優化

  • 開啟 Bloomfilter: 提升隨機讀寫性能,任何業務都應該設置Bloomfilter,通常設置為row就可以,除非確認業務隨機查詢類型為row+cf,可以設置為rowcol
  • 合理規劃BlockCache:
    1)對于注重讀響應時間的系統,可以將 BlockCache設大些,加大緩存的命中率。
    2)開啟BolckCache壓縮。
    3)采用組合模式把不同類型的Block分別放到 LRUCache和BucketCache中,其中IndexBloom Block放到LRUCache中。Data Block放到BucketCache中,LRUCache使用內存->BuckectCache使用SSD->HFile使用機械硬盤。
  • 異構存儲: 可以將熱點表存儲在SSD中
  • 開啟Short-CircuitLocal Read: Short Circuit策略允許客戶端繞過DataNode直接讀取本地數據
  • 開啟HedgedRead功能: 客戶端發起一個本地讀,一旦一段時間之后還沒有返回,客戶端將會向其他DataNode發送相同數據的請求。哪一個請求先返回,另一個就會被丟棄。
  • 批量讀: 通過調用HTable.get(List)方法可以根據一個指定的row key列表,批量獲取多行記錄,這樣做的好處是批量執行,只需要一次網絡I/O開銷,這對于對數據實時性要求高而且網絡傳輸RTT高的情景下可能帶來明顯的性能提升。
  • 指定列族: scan時指定需要的列族,可以減少網絡傳輸數據量,否則默認scan操作會返回整行所有Column Family的數據。
  • 多線程并發讀: 在客戶端開啟多個HTable讀線程,每個讀線程負責通過HTable對象進行get操作。
  • 限定掃描范圍: 指定列簇或者指定要查詢的列,指定startRow和endRow
  • scan批量緩存 hbase.client.scanner.caching默認為1,scan一次從服務端抓取的數據條數,通過將其設置成一個合理的值,可以減少scan過程中next()的時間開銷,避免占用過多的客戶端內存,一般1000以內合理。
  • 寫優化

  • 批量寫: 采用批量寫,可以減少客戶端到RegionServer之間的RPC的次數,提高寫入性能。批量寫請求要么全部成功返回,要么拋出異常。
  • 異步批量提交: 用戶提交寫請求之后,數據會先寫入客戶端緩存,并返回用戶寫入成功,當緩存達到閾值(默認2M,可通過hbase.client.write.buffer配置)時才會批量提交給RegionServer。客戶端異常緩存數據有可能丟失。
  • HTable.setWriteBufferSize(writeBufferSize); // 設置緩存大小 HTable.setAutoFlush(false);//關閉自動提交
  • 多線程并發寫: 客戶端開啟多個HTable寫線程,每個寫線程負責一個HTable對象的flush操作,這樣結合定時flush和寫buffer,可以即保證在數據量小的時候,數據可以在較短時間內被flush,同時又保證在數據量大的時候,寫buffer一滿就即使進行flush。

  • 使用BulkLoad寫入: 在HBase中數據都是以HFile形式保存在HDFS中的,當有大量數據需要寫入到HBase的時候,可以采用BulkLoad方式完成。通過使用MapReduce或者Spark直接生成HFile格式的數據文件,然后再通過RegionServer將HFile數據文件移動到相應的Region上去。

  • 合理設置WAL: 寫HBase時,數據需要先寫入WAL保障數據不丟失。如果業務不特別關心異常情況下部分數據的丟失,而更關心數據寫入吞吐量,可開啟WAL異步寫入或考慮關閉WAL寫。

  • 總結

    以上是生活随笔為你收集整理的【2022持续更新】大数据最全知识点整理-HBase篇的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。