大數據面試系列之——Hbase

Hbase是一個分佈式的列式存儲的數據庫
1.說說Hbase的特點

  • 1.分佈式架構,Hbase通過集羣存儲數據,數據最終會落到HDFS上
  • 2.是一種NoSQL的非關係型數據庫,不符合關係型數據庫的範式
  • 3.面向列存儲,底層基於key-value結構
  • 4.適合存儲半結構化、非結構化的數據
  • 5.適合存儲稀疏的數據,空的數據不佔用空間
  • 6.提供實時的增刪改查的能力,但是不提供嚴格的事務機制,只能在行級別提供事務

2.Hbase的架構組成及其作用

  • 1.Zookeeper,作爲分佈式的協調。RegionServer也會把自己的信息寫到ZooKeeper中。
  • 2.HDFS是Hbase運行的底層文件系統
  • 3.RegionServer,理解爲數據節點,存儲數據的
  • 4.Master RegionServer要實時的向Master報告信息。Master知道全局的RegionServer運行情況,可以控制RegionServer的故障轉移和Region的切分

3.說說行存儲和列存儲的特點

  • 1.行存儲在磁盤上的存儲是連續的;列存儲在磁盤上的存儲是不連續的
  • 2.從寫入性能上對比,寫入次數越少性能越高。因爲針對磁盤的每一次寫入,都要發生磁頭調度,產生尋道時間。因爲行存儲是隻寫一次而列存儲要寫多次,所以行存儲在寫入性能上更有優勢
  • 3.從讀取性能上對比:
    a. 如果讀取的是整表,則行存儲性能較高
    b. 如果是讀取指定的列,則行存儲會產生冗餘列,而冗餘列的消除是在內存中發生。而列存儲則不會存在冗餘列
  • 4.在存儲數據的時候,如果基於行存儲,由於一行數據的字段類型可能不同,所以會產生頻繁的數據類型轉換;如果是基於列存儲,由於同一列數據的類型一般一致,則可以避免頻繁的數據類型轉換,同時可以考慮一些更好的壓縮算法對一列數據進行壓縮

4.Hbase行鍵列族的概念,物理模型,表的設計原則

  • 行鍵:是hbase表自帶的,每個行鍵對應一條數據。

  • 列族:是創建表時指定的,爲列的集合,每個列族作爲一個文件單獨存儲,存儲的數據都是字節數組,其中數據可以有很多,通過時間戳來區分。

  • 物理模型:整個hbase表會拆分成多個region,每個region記錄着行鍵的起始點保存在不同的節點上,查詢時就是對各個節點的並行查詢,當region很大時使用.META表存儲各個region的起始點,-ROOT又可以存儲.META的起始點。

  • Rowkey的設計原則:各個列族數據平衡,長度原則、相鄰原則,創建表的時候設置表放入regionserver緩存中,避免自動增長和時間,使用字節數組代替string,最大長度64kb,最好16字節以內,按天分表,兩個字節散列,四個字節存儲時分毫秒。

  • 列族的設計原則:儘可能少(按照列族進行存儲,按照region進行讀取,不必要的io操作),經常和不經常使用的兩類數據放入不同列族中,列族名字儘可能短

5.HBase簡單讀寫流程

  • 讀:
    找到要讀數據的region所在的RegionServer,然後按照以下順序進行讀取:先去BlockCache讀取,若BlockCache沒有,則到Memstore讀取,若Memstore中沒有,則到HFile中去讀。
  • 寫:
    找到要寫數據的region所在的RegionServer,然後先將數據寫到WAL(Write-Ahead Logging,預寫日誌系統)中,然後再將數據寫到Memstore等待刷新,回覆客戶端寫入完成。

6.請描述如何解決Hbase中region太小和region太大帶來的結果
Region過大會發生多次compaction,將數據讀一遍並寫一遍到hdfs上,佔用io,region過小會造成多次split,region會下線,影響訪問服務,調整hbase.heregion.max.filesize爲256m。

7.Hbase表的設計原則

  • 1、列族的數量及列族的勢
    建議將HBase列族的數量設置的越少越好。當前,對於兩個或兩個以上的列族HBase並不能處理的很好。這是由於HBase的Flushing和壓縮是基於Region的。當一個列族所存儲的數據達到Flushing的閾值時,該表中所有列族將同時進行Flushing操作。這將帶來不必要的I/O開銷,列族越多,該特性帶來的影響越大。
    此外,還要考慮到同一個表中不同列族所存儲的記錄數量的差別,即列族的勢(Cardinality)。當兩個列族數量差別過大時會使包含記錄數量較少列族的數據分散在多個Region上,而Region有可能存儲在不同的RegionServer上。這樣,當進行查詢或scan操作的時候,系統效率將會受到影響。

  • 2、行鍵(RowKey)的設計
    首先應該避免使用時序或單調(遞減/遞增)行鍵。因爲當數據到來的時候,HBase首先需要根據記錄的行鍵來確定存儲的位置,即Region的位置,如果使用時序或單調行鍵,那麼連續到來的數據將被分配到同一個Region中,而此時系統的其他Region/RegionServer處於空閒狀態,這是分佈式最不希望看到的狀態。

  • 3、儘量最小化行鍵和列族的大小
    在HBase中,一個具體的值由存儲該值的行鍵、對應的列(列族:列)以及該值的時間戳決定。HBase中索引是爲了加速隨即訪問的速度,索引的創建是基於“行鍵+列族:列+時間戳+值”的,如果行鍵和列族的大小過大,甚至超過值本身的大小,那麼將會增加索引的大小。並且在HBase中數據記錄往往非常之多,重複的行鍵、列將不但使索引的大小過大,也將加重系統的負擔

  • 4、版本的數量
    默認情況下爲3個,可以通過HColumnDescriptor進行設置,建議不要設置的過大

8.Hbase如何導入數據
使用 MapReduce Job 方式,根據 Hbase API 編寫 java 腳本,將文本文件用文件流的方式截取,然後存儲到多個字符串數組中,在 put 方法下,通過對錶中的列族進行 for 循環遍歷列名,用 if 判斷列名後進行 for 循環調用 put.add 的方法對列族下每一個列進行設值,每個列族下有幾個了就賦值幾次!沒有表先對先創建表。

9.Hbase的存儲結構
Hbase 中的每張表都通過行鍵(rowkey)按照一定的範圍被分割成多個子表(HRegion),默認一個 HRegion 超過 256M 就要被分割成兩個,由 HRegionServer 管理,管理哪些 HRegion由 Hmaster 分配。 HRegion 存取一個子表時,會創建一個 HRegion 對象,然後對錶的每個列族(Column Family)創建一個 store 實例,每個 store 都會有 0 個或多個 StoreFile 與之對應,每個 StoreFile 都會對應一個 HFile, HFile 就是實際的存儲文件,因此,一個 HRegion 還擁有一個 MemStore 實例。

10.Hbase 和 hive 有什麼區別hive 與 hbase 的底層存儲是什麼?hive是產生的原因是什麼?habase是爲了彌補hadoop的什麼缺陷?

  • Hive和Hbase都是架構在Hadoop上,底層存儲都是HDFS
  • 區別:
    • 1.Hive是建立在Hadoop之上爲了減少MapReducejobs編寫工作的批處理系統,HBase是爲了支持彌補Hadoop對實時操作的缺陷的項目
    • 2.想象你在操作RMDB數據庫,如果是全表掃描,就用Hive+Hadoop,如果是索引訪問,就用HBase+Hadoop
    • 3.Hive query就是MapReduce jobs可以從5分鐘到數小時不止,HBase是非常高效的,肯定比Hive高效的多
    • 4.Hive本身不存儲和計算數據,它完全依賴於HDFS和MapReduce,Hive中的表純邏輯
    • 5.hive借用hadoop的MapReduce來完成一些hive中的命令的執行
    • 6.hbase是物理表,不是邏輯表,提供一個超大的內存hash表,搜索引擎通過它來存儲索引,方便查詢操作
    • 7.hbase是列存儲
    • 8.hdfs作爲底層存儲,hdfs是存放文件的系統,而Hbase負責組織文件
    • 9.hive需要用到hdfs存儲文件,需要用到MapReduce計算框架

11.解釋下 hbase 實時查詢的原理
實時查詢,可以認爲是從內存中查詢,一般響應時間在 1 秒內。 HBase 的機制是數據先寫入到內存中,當數據量達到一定的量(如 128M),再寫入磁盤中, 在內存中,是不進行數據的更新或合併操作的,只增加數據,這使得用戶的寫操作只要進入內存中就可以立即返回,保證了 HBase I/O 的高性能

12.列簇怎麼創建比較好?
rowKey 最好要創建有規則的 rowKey,即最好是有序的。 HBase 中一張表最好只創建一到兩個列族比較好,因爲 HBase 不能很好的處理多個列族

13.描述 Hbase 中 scan 和 get 的功能以及實現的異同

  • 1.按指定RowKey 獲取唯一一條記錄, get方法(org.apache.hadoop.hbase.client.Get)Get 的方法處理分兩種 : 設置了 ClosestRowBefore 和沒有設置的 rowlock .主要是用來保證行的事務性,即每個 get 是以一個 row 來標記的.一個 row 中可以有很多 family 和 column.

  • 2.按指定的條件獲取一批記錄, scan 方法(org.apache.Hadoop.hbase.client.Scan)實現條件查詢功能使用的就是 scan 方式.1)scan 可以通過 setCaching 與 setBatch 方法提高速度(以空間換時間); 2)scan 可以通過 setStartRow 與 setEndRow 來限定範圍([start, end]start 是閉區間, end 是開區間)。範圍越小,性能越高。3)scan 可以通過 setFilter 方法添加過濾器,這也是分頁、多條件查詢的基礎。

  • 3.全表掃描,即直接掃描整張表中所有行記錄

14.請詳細描述 Hbase 中一個 Cell 的結構

HBase 中通過 row 和 columns 確定的爲一個存貯單元稱爲 cell。Cell:由{row key, column(= +

15.請描述 Hbase 中 scan 對象的 setCache 和 setBatch 方法的使用

  • cache:

    • 在默認情況下,如果你需要從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異常。
  • batch:

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

16.簡述 HBASE 中 compact 用途是什麼,什麼時候觸發,分爲哪兩種,有什麼區別,有哪些相關配置參數?

在 hbase 中每當有 memstore 數據 flush 到磁盤之後,就形成一個 storefile,當 storeFile 的數量達到一定程度後,就需要將 storefile 文件來進行 compaction 操作。

Compact 的作用:

1>.合併文件

2>.清除過期,多餘版本的數據

3>.提高讀寫數據的效率

HBase 中實現了兩種 compaction 的方式:

minor and major. 這兩種 compaction 方式的區別是:

  • 1、 Minor 操作只用來做部分文件的合併操作以及包括 minVersion=0 並且設置 ttl 的過期版本清理,不做任何刪除數據、多版本數據的清理工作。
  • 2、 Major 操作是對 Region 下的 HStore 下的所有 StoreFile 執行合併操作,最終的結果是整理合並出一個文件。簡述 Hbase filter 的實現原理是什麼?結合實際項目經驗,寫出幾個使用 filter 的場景HBase 爲篩選數據提供了一組過濾器,通過這個過濾器可以在 HBase 中的數據的多個維度(行,列,數據版本)上進行對數據的篩選操作,也就是說過濾器最終能夠篩選的數據能夠細化到具體的一個存儲單元格上(由行鍵,列名,時間戳定位)。 RowFilter、 PrefixFilter。。。hbase的filter是通過scan設置的,所以是基於scan的查詢結果進行過濾.過濾器的類型很多,但是可以分爲兩大類——比較過濾器,專用過濾器過濾器的作用是在服務端判斷數據是否滿足條件,然後只將滿足條件的數據返回給客戶端;如在進行訂單開發的時候,我們使用rowkeyfilter過濾出某個用戶的所有訂單

17.Hbase 內部是什麼機制
在 HBase 中無論是增加新行還是修改已有行,其內部流程都是相同的。 HBase 接到命令後存下變化信息,或者寫入失敗拋出異常。默認情況下,執行寫入時會寫到兩個地方:預寫式日誌(write-ahead log,也稱 HLog)和 MemStore。 HBase 的默認方式是把寫入動作記錄在這兩個地方,以保證數據持久化。只有當這兩個地方的變化信息都寫入並確認後,才認爲寫動作完成。MemStore 是內存裏的寫入緩衝區, HBase 中數據在永久寫入硬盤之前在這裏累積。當MemStore 填滿後,其中的數據會刷寫到硬盤,生成一個 HFile。 HFile 是 HBase 使用的底層存儲格式。 HFile 對應於列族,一個列族可以有多個 HFile,但一個 HFile 不能存儲多個列族的數據。在集羣的每個節點上,每個列族有一個 MemStore。大型分佈式系統中硬件故障很常見, HBase 也不例外。設想一下,如果 MemStore 還沒有刷寫,服務器就崩潰了,內存中沒有寫入硬盤的數據就會丟失。 HBase 的應對辦法是在寫動作完成之前先寫入 WAL。 HBase 集羣中每臺服務器維護一個 WAL 來記錄發生的變化。WAL 是底層文件系統上的一個文件。直到 WAL 新記錄成功寫入後,寫動作才被認爲成功完成。這可以保證 HBase 和支撐它的文件系統滿足持久性。大多數情況下, HBase 使用Hadoop 分佈式文件系統(HDFS)來作爲底層文件系統。如果 HBase 服務器宕機,沒有從 MemStore 裏刷寫到 HFile 的數據將可以通過回放WAL 來恢復。你不需要手工執行。 Hbase 的內部機制中有恢復流程部分來處理。每臺HBase 服務器有一個 WAL,這臺服務器上的所有表(和它們的列族)共享這個 WAL。你可能想到,寫入時跳過 WAL 應該會提升寫性能。但我們不建議禁用 WAL,除非你願意在出問題時丟失數據。如果你想測試一下,如下代碼可以禁用 WAL: 注意:不寫入 WAL 會在 RegionServer 故障時增加丟失數據的風險。關閉 WAL,出現故障時 HBase 可能無法恢復數據,沒有刷寫到硬盤的所有寫入數據都會丟失。

18.HBase 宕機如何處理

宕機分爲 HMaster 宕機和 HRegisoner 宕機,如果是 HRegisoner 宕機, HMaster 會將其所管理的 region 重新分佈到其他活動的 RegionServer 上,由於數據和日誌都持久在 HDFS中,該操作不會導致數據丟失。所以數據的一致性和安全性是有保障的。如果是 HMaster 宕機, HMaster 沒有單點問題, HBase 中可以啓動多個 HMaster,通過Zookeeper 的 Master Election 機制保證總有一個 Master 運行。即 ZooKeeper 會保證總會有一個 HMaster 在對外提供服務

19.導致Hbase掛掉的場景

導致Hbase掛掉的場景

  • HMaster
    HMaster會出現異常(執行abort())停止的場景如下:
    1.zk異常導致的master停止服務是最常見的場景,涉及操作包含但不限於以下:
    a)Zk鏈接超時,超時時間通過zookeeper.session.timeout配置,默認爲3分鐘, 如果fail.fast.expired.active.master配置的值爲false(默認爲false),則不會立即abort,而是會嘗試恢復zk的過期session;
    b)在打開region後,需要從zk中刪除opened節點,如果zk有該節點,但是刪除失敗;
    c)在split region過程中,從zk刪除split節點時;
    d)Master節點改變時;
    e)從zk中創建unassigned節點時;
    f)在下線disabled的regoin時,從zk中刪除disabled的region如果發生zk異常;
    g)還有很多操作zk的節點時如果出現異常。
    2.在assign時,如果設置region爲offlined狀態,但是region之前的狀態不是closed或者offlined;
    3.在assign時,如果無法從.META.表中讀取region信息;
    4.把新的hbase集羣加入到正在運行的hbase集羣時,如果zk的/hbase/unassigned節點沒有數據;
    5.使用線程池批量分配region時,如果出現未被捕獲的異常,實現方式如下:
    6.在啓動master的服務線程時,出現了異常;
    7.在hdfs中檢查hbase日誌路徑時,發現了dead的server時,需從hdfs中讀出log,如果出現io異常需要檢查hdfs文件系統,如果fsOk狀態爲true,但是通過FSUtils工具類進行檢查時出現io異常;
    8.在校驗並且分配-ROOT-的region時,如果zk異常,或者其它異常(其它異常會重試10次),比如:“-ROOT- is onlined on the dead server”。

  • HRegionServer
    HRegionServer會出現異常停止(執行abort())服務的場景如下:
    1.在讀寫hdfs時如果出現IOException異常,此時會發起hdfs的文件系統檢查(checkFileSystem)1.
    2.Regionserver的服務線程出現了未捕獲異常;
    3.在啓動HRegionServer時出現異常;
    4.在進行HLog回滾時,出現異常;
    5.在flush memstore時,如果持久化失敗,會重啓RS,在重啓中把hlog的內容重新加載到memstore;
    6.出現zk異常,包括但不限於以下場景:
    a)Zk鏈接超時,超時時間通過zookeeper.session.timeout配置,默認爲3分鐘,與master不同,如果zk操作不會重試;
    b)啓動HRegionServer時出現KeeperException異常;
    c)在進行split操作時,如果出現異常會進行回滾操作,在回滾過程中需要從zk中刪除region的spliting狀態,如果刪除時出現KeeperException或者回滾的其它操作出現異常;
    d)在打開region時,出現了KeeperException異常;
    e)在進行hbase集羣複製時,很多與zk交互的操作出現KeeperException異常時均會導致abort;
    7.在close region時,如果出現異常,比如:不能成功的flush memstore;
    8.Flush memstore時,如果HLog發現該region已經在flush則會強制終止JVM,採用的是Runtime.getRuntime().halt(1)方法,該方法不會執行正常退出的關閉鉤子,從而不會flush RS的所有region,也不會遷移region,只有等待ZK的session超時後master纔會發現該RS不可用,做遷移工作。

  • 總結
    Hbase掛掉的可能性有很多,主要由zk或者hdfs的問題導致,因此zk、hdfs的可用對於hbase極其重要,關於zk:
    1.zk如果停止了服務則在很多時候會導致master、rs掛掉,hbase集羣基本上就失去了服務的能力,因此zk一定要是穩定可靠的,當client已經於rs建立了鏈接,這時zk掛掉,如果不進行split等小數與zk交互失敗會導致觸發rs的abort()的操作時rs還是可以提供服務的;
    2.如果rs/master進行了長時間的gc或者改動了服務器時間,導致出現zk的session超時會導致rs/master停止服務,目前已經出現了2次因爲服務器時間變化導致hbase停止服務的事故;
    3.別輕易人爲改變zk的hbase節點數據,master/rs在進行很多操作時會比較依賴zk的數據,如果發現不符合預期可能會導致master/rs停止服務,尤其是master。
    Master通過ZK知道RS是否可用,一般情況下RS在停止服務時均會正常退出,在正常退出時會從ZK中刪除/hbase/rs/$regionserver的節點,Master會監聽該節點的被刪除,從而較快的(速度取決於所有region關閉時間)對該RS負責的region進行重新分配,如果是強制退出,比如 kill -9或者出現HRegionServer掛掉的第8條時則只有等待ZK的session超時時纔會刪除RS在ZK的節點(RS在ZK中添加節點時採用的是CreateMode.EPHEMERAL模式,該模式創建的節點會在session關閉時自動刪除),那時Master纔會進行重新assign。
    Kill RS的進程也是正常退出(不能使用kill -9強制退出),RS使用Runtime的addShutdownHook方法註冊了jvm關閉鉤子,在關閉鉤子中會執行RS的退出邏輯,實際上hbase-daemon.sh的停止RS就是採用kill。

20.Hbase的原理 regionserver掛了 如何恢復數據 ?新的數據從Hlog裏讀出來是如何恢復的

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

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

一旦RegionServer發生宕機,HBase都會馬上檢測到這種宕機,並且在檢測到宕機之後會將宕機RegionServer上的所有Region重新分配到集羣中其他正常RegionServer上去,再根據HLog進行丟失數據恢復,恢復完成之後就可以對外提供服務,整個過程都是自動完成的,並不需要人工介入.

21.講一下Hbase,Hbase二級索引用過嗎

默認情況下,Hbase只支持rowkey的查詢,對於多條件的組合查詢的應用場景,不夠給力。

如果將多條件組合查詢的字段都拼接在RowKey中顯然又不太可能

全表掃描再結合過濾器篩選出目標數據(太低效),所以通過設計HBase的二級索引來解決這個問題。

這裏所謂的二級索引其實就是創建新的表,並建立各列值(family:column)與行鍵(rowkey)之間的映射關係。這種方式需要額外的存儲空間,屬於一種以空間換時間的方式

22.Hbase如何優化的

  • 內存優化

    • Ø 垃圾回收優化:CMS, G1(Region)

    • Ø JVM啓動:-Xms(1/64) –Xmx(1/4)

  • Region優化

    • Ø 預分區

    • Ø 禁用major合併,手動合併

  • 客戶端優化

    • 批處理
  • Hbase配置優化

    • 設置RPC監聽數量
      hbase-site.xml
      屬性:hbase.regionserver.handler.count
      解釋:默認值爲 30,用於指定 RPC 監聽的數量,可以根據客戶端的請求數進行調整,讀寫請求較多時,增加此值。

    • 優化 HStore 文件大小
      hbase-site.xml
      屬性:hbase.hregion.max.filesize
      解釋:默認值 10737418240(10GB),如果需要運行 HBase 的 MR 任務,可以減小此值, 因爲一個 region 對應一個 map 任務,
      如果單個 region 過大,會導致 map 任務執行時間過長。該值的意思就是,如果 HFile 的大小達到這個數值,則這個 region 會被切分爲兩個 Hfile

    • 優化 hbase 客戶端緩存
      hbase-site.xml
      屬性:hbase.client.write.buffer
      解釋:用於指定 HBase 客戶端緩存,增大該值可以減少 RPC 調用次數,但是會消耗更多內存,反之則反之。一般我們需要設定一定的緩存大小,以達到減少 RPC 次數的目的

    • 指定 scan.next 掃描 HBase 所獲取的行數
      hbase-site.xml
      屬性:hbase.client.scanner.caching
      解釋:用於指定 scan.next 方法獲取的默認行數,值越大,消耗內存越大。

    • flush、compact、split 機制
      當 MemStore 達到閾值,將 Memstore 中的數據 Flush 進 Storefile;compact 機制則是把 flush 出來的小文件合併成大的 Storefile 文件。split 則是當 Region 達到閾值,會把過大的 Region 一分爲二。
      涉及屬性:
      即:128M 就是 Memstore 的默認閾值
      hbase.hregion.memstore.flush.size:134217728
      即:這個參數的作用是當單個 HRegion 內所有的 Memstore 大小總和超過指定值時,flush
      該 HRegion 的所有 memstore。RegionServer 的 flush 是通過將請求添加一個隊列,模擬生產消費模型來異步處理的。那這裏就有一個問題,當隊列來不及消費,產生大量積壓請求時,可能會導致內存陡增,最壞的情況是觸發 OOM。
      hbase.regionserver.global.memstore.upperLimit:0.4
      hbase.regionserver.global.memstore.lowerLimit:0.38
      即:當 MemStore 使用內存總量達到 hbase.regionserver.global.memstore.upperLimit 指定值時,將會有多個 MemStores flush 到文件中,MemStore flush 順序是按照大小降序執行的,直到刷新到 MemStore 使用內存略小於 lowerLimit

  • HDFS優化

    • NameNode 元數據備份使用 SSD

    • 定時備份 NameNode 上的元數據

      每小時或者每天備份,如果數據極其重要,可以 5~10 分鐘備份一次。備份可以通過定時任務複製元數據目錄即可。

    • 爲 NameNode 指定多個元數據目錄
      使用 dfs.name.dir 或者 dfs.namenode.name.dir 指定。這樣可以提供元數據的冗餘和健壯性, 以免發生故障。

    • NameNode 的 dir 自恢復
      設置 dfs.namenode.name.dir.restore 爲 true,允許嘗試恢復之前失敗的 dfs.namenode.name.dir
      目錄,在創建 checkpoint 時做此嘗試,如果設置了多個磁盤,建議允許。

    • HDFS 保證 RPC 調用會有較多的線程數
      屬性:dfs.namenode.handler.count
      解釋:該屬性是 NameNode 服務默認線程數,默認值是 10,根據機器的可用內存可以調整爲 50~100
      屬性:dfs.datanode.handler.count
      解釋:該屬性默認值爲 10,是 DataNode 的處理線程數,如果 HDFS 客戶端程序讀寫請求比較多,可以調高到 15~20,設置的值越大,內存消耗越多,不要調整的過高,一般業務中,
      5~10 即可。
      hdfs-site.xml

    • HDFS 副本數的調整
      屬性:dfs.replication
      解釋:如果數據量巨大,且不是非常之重要,可以調整爲 2~3,如果數據非常之重要,可以調整爲 3~5。

      hdfs-site.xml

    • HDFS 文件塊大小的調整

      屬性:dfs.blocksize
      解釋:塊大小定義,該屬性應該根據存儲的大量的單個文件大小來設置,如果大量的單個文件都小於 100M,
      建議設置成 64M 塊大小,對於大於 100M 或者達到 GB 的這種情況,建議設置成 256M,一般設置範圍波動在 64M~256M 之間。

      hdfs-site.xml

    • MapReduce Job 任務服務線程數調整

      屬性:mapreduce.jobtracker.handler.count
      解釋:該屬性是 Job 任務線程數,默認值是 10,根據機器的可用內存可以調整爲 50~100

      mapred-site.xml

    • Http 服務器工作線程數
      mapred-site.xml

      屬性:mapreduce.tasktracker.http.threads
      解釋:定義 HTTP 服務器工作線程數,默認值爲 40,對於大集羣可以調整到 80~100

    • 文件排序合併優化
      mapred-site.xml

      屬性:mapreduce.task.io.sort.factor
      解釋:文件排序時同時合併的數據流的數量,這也定義了同時打開文件的個數,默認值爲
      10,如果調高該參數,可以明顯減少磁盤 IO,即減少文件讀取的次數。

    • 設置任務併發
      mapred-site.xml

      屬性:mapreduce.map.speculative
      解釋:該屬性可以設置任務是否可以併發執行,如果任務多而小,該屬性設置爲 true 可以明顯加快任務執行效率,但是對於延遲非常高的任務,建議改爲 false,這就類似於迅雷下載。

    • MR 輸出數據的壓縮
      mapred-site.xml
      屬性:mapreduce.map.output.compress、mapreduce.output.fileoutputformat.compress
      解釋:對於大集羣而言,建議設置 Map-Reduce 的輸出爲壓縮的數據,而對於小集羣,則不需要。

    • 優化 Mapper 和 Reducer 的個數
      mapred-site.xml
      屬性:mapreduce.tasktracker.map.tasks.maximum mapreduce.tasktracker.reduce.tasks.maximum
      解釋:以上兩個屬性分別爲一個單獨的 Job 任務可以同時運行的 Map 和 Reduce 的數量。
      設置上面兩個參數時,需要考慮 CPU 核數、磁盤和內存容量。假設一個 8 核的 CPU,業務內容非常消耗 CPU,那麼可以設置 map 數量爲 4,如果該業務不是特別消耗 CPU 類型的,
      那麼可以設置 map 數量爲 40,reduce 數量爲 20。這些參數的值修改完成之後,一定要觀察是否有較長等待的任務,如果有的話,可以減少數量以加快任務執行,
      如果設置一個很大的值,會引起大量的上下文切換,以及內存與磁盤之間的數據交換,這裏沒有標準的配置數值,
      需要根據業務和硬件配置以及經驗來做出選擇。
      在同一時刻,不要同時運行太多的 MapReduce,這樣會消耗過多的內存,任務會執行的非常緩慢,我們需要根據 CPU 核數,內存容量設置一個 MR 任務併發的最大值,
      使固定數據量的任務完全加載到內存中,避免頻繁的內存和磁盤數據交換,從而降低磁盤 IO,提高性能。
      大概估算公式:
      map = 2 + ⅔cpu_core, reduce = 2 + ⅓cpu_core

    • 優化 DataNode 允許的最大文件打開數
      hdfs-site.xml
      屬性:dfs.datanode.max.transfer.threads
      解釋:HBase 一般都會同一時間操作大量的文件,根據集羣的數量和規模以及數據動作,設置爲 4096 或者更高。默認值:4096

    • 優化延遲高的數據操作的等待時間
      hdfs-site.xml
      屬性:dfs.image.transfer.timeout
      解釋:如果對於某一次數據操作來講,延遲非常高,socket 需要等待更長的時間,建議把該值設置爲更大的值(默認 60000 毫秒),以確保 socket 不會被 timeout 掉。

    • 優化數據的寫入效率
      mapred-site.xml
      屬性:
      mapreduce.map.output.compress mapreduce.map.output.compress.codec
      解釋:開啓這兩個數據可以大大提高文件的寫入效率,減少寫入時間。第一個屬性值修改爲true,第二個屬性值修改爲:org.apache.hadoop.io.compress.GzipCodec 或者其他壓縮方式

    • 優化 DataNode 存儲
      屬性:dfs.datanode.failed.volumes.tolerated
      解釋:默認爲 0,意思是當 DataNode 中有一個磁盤出現故障,則會認爲該 DataNode shutdown 了。
      如果修改爲 1,則一個磁盤出現故障時,數據會被複制到其他正常的 DataNode 上,當前的 DataNode 繼續工作。

發佈了28 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章