HBase補充學習(一)

前言

最近選的一門選修課需要學生進行知識分享,好巧不巧的選了HBase,本來以爲對其已經學得很ok了,結果自查以後才發現自己學得還是比較表面,冰山一角就是冰山一角,沒啥好推脫的,利用一週的時間充實預分享的知識,昨天已經分享結束,雖然還是由於拖拉導致沒能按以往慣例準備好講解稿和幾次試講,但時長是夠了。想着也是花了時間就把一些東西放在這當記錄好了(裏面也主要是蒐集的各種資料的總結)。

知識點

  1. 爲什麼要不用RDBMS?
  • 數據量爆炸式增長並數據種類急劇增加下,使用RDBMS二維表會變得很高很寬,查詢效率大大降低
  • RDBMS對單機依賴很強,集羣部署難;升級維護難,需要進行停機維護,耗費人力物力
  • 對數據模式要求嚴格,對數據格式約束很強。對於非結構化和半結構化數據只能存儲數據的存儲路徑,存儲方面需要捨棄部分數據,在數據分析的背景下不合適
  1. 爲什麼不用HDFS?
  • hadoop設計的初衷是大規模數據的計算和olap分析, 應用場景區別與數據庫,所以在HDFS設計時候就側重在一次寫入多次讀取。絕大部分文件的修改是採用在文件尾部追加數據,而不是覆蓋原有數據的方式。對文件的隨機寫入操作在實際中幾乎不存在。一旦寫完之後,對文件的操作就只有讀,而且通常是按順序讀。
  • HDFS雖然因爲文件的分佈式存儲和強擴展性,具有海量數據存儲的能力,但文件本身是隻支持增加數據的,如果查詢數據需要遍歷整個HDFS集合找到目標HDFS,並對整個HDFS文件從頭到尾進行遍歷,效率過低
  • 對於數據刪除,HDFS只支持整個文件刪除,不支持文件中單個數據的刪除
  • 對於數據修改,HDFSdatanode需要進行同步更新,消耗大。並且在同步的時候有讀請求的話還需考慮讀的是髒數據還是加鎖不讓讀。如果是第二種情況加速不讓讀提供強一致性分佈式事務,不僅大大降低HDFS性能而且違背hadoop設計的初衷. 如果提供一個髒讀數據,爲什麼不直接刪除數據a然後重新插入修改後數據a,讓用戶有個正確的讀取操作呢?
  1. 爲什麼要用NoSQL?
  • NoSQL,not only sql。對比RDBMS,對數據模式要求不嚴謹,適合存儲非結構化數據,數據以二進制形式存儲
  • 擴展性很強,在分佈式環境中應用較多
  1. 爲什麼要用HBase?
  • 對於HDFS無法支持隨機讀寫問題,想到如果提前先對數據進行排序,查詢效率相對會提高些。HBase是基於HDFS之上的一個數據庫引擎,主要做的就是數據排序和無效數據簡單的處理
  • HBase屬NoSQL,對錶約束不強,無模式設計,所有字段按照Byte字節數據格式存儲
  • HBase擴展性強,支持海量數據存儲
  1. HBase各個特點的具體解釋
  • 鬆散表結構:NULL不佔存儲空間,在HBase中只有列真正插入數據纔有產生列信息,MySQL中NULL爲屬性的值,佔存儲空間
  • 海量分佈式存儲:支持PB級數據存儲,Region和RegionServer爲多對1關係,底層由Hadoop支持可以進行分佈式存儲
  • 列式存儲:Region下的Store按列族分割,一個Store即一個HFile
  • 易於擴展:RegionServer的擴展(即添加一個集羣節點即可完成)
  • 高併發:對數據進行查看時無需遍歷所有數據(關係型數據庫以MySQL爲例,找一條數據首先需要遍歷整個表,其次需要拿到這個條目所有的屬性值;HBase則根據Rowkey找到目標數據的一行,在找到這一行的某一列族即可)
  • 支持多版本:HBase支持一個數據有多個版本,並且支持用戶自定義支持的版本數量,適用於需維護如登錄記錄、交易記錄等最近N次變更值的數據。並且HBase支持TTL(Time To Live),每一行中的每一列數據一旦達到到期時間,將被自動刪除,這點適用於如日誌、瀏覽記錄等無需永久保存的數據
  1. HBase各組件功能記錄
    6.1 Master
  • 在ZooKeeper輔助下分配Region給RegionServer
  • HBase表的DDL操作,表創建及表刪除
  • 處理RegionServer的負載均衡問題,通過ZooKeeper偵測各個RegionServer之間的狀態。如果發現失效/過忙的RegionServer就將其上的Region分配到其他空閒並健康的RegionServer上,並完成原有RegionServer上HLog的拆分(HLog回滾)。(此處需要注意雖然RegionServer失效了,但是由於數據是存在HDFS中而RegionServer只是一個單純的管理作用,所以即使RegionServer失效也對其管理的Region中的數據無影響,故可通過Master的協調將該Region的管理工作分配給其他正常工作的RegionServer中去。)
  • 維護集羣元數據信息,主要是Master將存儲HBase表的Meta表信息的Region信息存儲在ZooKeepr中

6.2 ZooKeeper

  • 通過選舉保證任何時候,集羣中只有一個活躍的Master
  • 監控RegionServer,當RegionServer異常時通過回調的方式告訴Master當前RegionServer的情況
  • 元數據的入口,Region的狀態存儲在hbase:meta表裏面,hbase:meta本身的Region狀態存儲在ZooKeeper中

6.3 HDFS

  • 存儲數據的載體(HFile+HLog)

6.4 RegionServer

  • 處理來自Client的讀/寫請求
  • 負責與底層HDFS交互
  • 管理Master爲其分配的Region
  • 負責Region的切分(動作由Master觸發,RegionServer執行切分動作)
  • 負責StoreFile的合併

6.5 Region

  • HBase分佈式存儲和負載的最小單元
  • HBase表對弈一個Region

6.6 Store

  • 由內存中的MemStore和磁盤中的若干StoreFile組成。一個Store裏有1個或多個StoreFile和一個MemStore。從HBase表的角度來看,每個Store存儲一個列族

6.7 MemStore

  • 寫緩存
  • 提前根據RowKey對數據進行排序

6.8 HFile/StoreFile

  • 數據存儲在HFile中

6.9 hbase:meta表

  • 存儲regionserver信息。Key: region、start key、region id;Values: RegionServer
  1. WAL機制
    write ahead log,預寫入日誌。由於HBase數據先寫入內存,爲防止服務器宕機或者斷電等導致內存數據丟失,在數據寫入內存前會先寫入WAL以便異常恢復,WAL文件存放在/.log文件夾中。對WAL的寫入必須是順序寫入
    7.1 客戶端對數據執行一個修改操作,如put(),delete(),incr()等。
    7.2 每一個修改被封裝到一個KeyValue對象實例,並通過RPC調用發送出來。
    7.3 上述調用成批地發送給含有匹配region的HRegionServer。
    7.4 數據先被寫入到WAL,然後被放放到實際擁有記錄的存儲文件的MemStore中。
    7.5 當MemStore達到一定的大小或經歷一個特定時間之後,數據會異步地連續寫入到文件系統中
  • 回滾
    每隔固定檢查間隔(默認一小時),會將當前WAL中的操作與實際持久化到HDFS上的操作比較,被持久化的操作會被移動到.oldlogs文件夾中即歸檔
  • 歸檔
    .oldlogs文件夾中的WAL文件定期會被Master清理
  1. MemStore刷寫
    WAL 的數量越來越大,這就意味着 MemStore 中未持久化到磁盤的數據越來越多
    其實 internalFlushCacheAndCommit 裏面包含兩個步驟:flushCache 和 commit 階段。flushCache 階段其實就是將 prepareFlush 階段創建好的快照寫到臨時文件裏面,臨時文件是存放在對應 Region 文件夾下面的 .tmp 目錄裏面。
  • 優化數據的存儲:減少HDFS上無效數據的存儲。比如一個數據添加後馬上刪除,MemStore刷寫不會把這個數據寫到HDFS上
  • 對數據進行排序
  1. Region切分
    在這裏插入圖片描述
  • regionserver 更改ZK節點 /region-in-transition 中該region的狀態爲SPLITING
  • master通過watch節點/region-in-transition檢測到region狀態改變,並修改內存中region的狀態,在master頁面RIT模塊就可以看到region執行split的狀態信息
  • 在父存儲目錄下新建臨時文件夾,split保存split後的daughter region信息
  • 關閉parent region:parent region 關閉數據寫入並觸發flush操作,將寫入region的數據全部持久化到磁盤,此後短時間內客戶端落在父region上的請求都會拋出異常NotServingRegionException
  • 核心分裂步驟:在.split文件夾下新建兩個子文件夾,稱之爲daughter A、daughter B,並在文件夾中生成reference文件(文件的命名方式是父region對應的HFile文件+父region),分別指向父region中對應文件
  • 父region分裂爲兩個子region後,將daughter A、daughter B拷貝到HBase根目錄下,形成兩個新的region
  • parent region通知修改 hbase.meta 表後下線,不再提供服務。下線後parent region在meta表中的信息並不會馬上刪除, 而是標註split列、offline列爲true,並記錄兩個子region
  • 開啓daughter A、daughter B兩個子region。通知修改 hbase.meta 表,正式對外提供服務
    在父Region數據拷貝到子Region之前,使用reference文件讀取文件。根據reference文件名(region名+真實文件名)定位到真實數據所在文件路徑。
    在這裏插入圖片描述
  • 子region發生major_compaction時,將父目錄中屬於該子region的所有數據讀出來並寫入子region目錄數據文件中
  • Master會啓動一個線程定期遍歷檢查所有處於splitting狀態的父region,確定檢查父region是否可以被清理。檢測線程首先會在meta表中揪出所有split列爲true的region,並加載出其分裂後生成的兩個子region(meta表中splitA列和splitB列),只需要檢查此兩個子region是否還存在引用文件,如果都不存在引用文件就可以認爲該父region對應的文件可以被刪除。
    在這裏插入圖片描述
  1. LSM樹
    LSM樹(Log-Structured Merge Tree)存儲引擎和B樹存儲引擎一樣,同樣支持增、刪、讀、改、順序掃描操作。而且通過批量存儲技術規避磁盤隨機寫入問題。當然凡事有利有弊,LSM樹和B+樹相比,LSM樹犧牲了部分讀性能,用來大幅提高寫性能。
    LSM樹,此時的數據已是有序且順序寫入磁盤的,所以寫入速度很快。但是隨着數據量的不斷增大, storefile會越來越多,數據查詢時需要掃描所有文件,所以LSM樹可以說得上是犧牲一部分讀性能來提高寫性能。這也是它的核心思想
    LSM中的merge操作就是爲解決storefile越來越多造成讀性能下降的問題。當memstore刷新後storefile達到配置的數量或者距離上次壓縮時間滿足配置的間隔時,出發compact操作,圖中展示從內存刷寫到磁盤,之後storefile存儲的小樹合併爲一顆大樹的過程。
  2. HFile合併
    由於內存裏memstore是在數據插入的過程中就排序的,就是數據插入的時候按照順序插入,所以memstore裏的數據是有序的。當memstore的數據刷寫到磁盤時,生成的storefile裏的數據也是有序的,這樣的話各個storefile裏的數據就分別有序了。合併的時候需要將各個有序的storefile合併成一個大的有序的storefile。
  • Major Compaction:將會合並和重寫一個Region的所有HFile文件,根據每個列族寫一個HFile 文件,過濾被刪除的數據、TTL過期數據、版本號超過設定版本號的數據。由於消耗較大,很少使用,一般是做了很多的minor compaction後進行一個major compaction將無效數據刪除
  • Minor Compaction:將會自動選取相鄰的一些小HFiles 文件重寫爲大的HFiles 文件
  1. HBase優化
  • RowKey設計
    避免熱點,利用加鹽、反轉補齊方式。加鹽是指在行鍵前面添加隨機數字或者字母,使得數據隨機分配到不同的分區,這種方式弊端顯而易見。如果需要使用GET請求再次獲取某行數據,則需要在插入時保存一個原始業務行鍵與添加的隨機數的映射關係,或者使用某種散列函數計算原始業務行鍵的散列值,然後將該散列值作爲最終行鍵的前綴。使用這種行鍵設計的應用通常只是用來做些分析統計,因此一般實時在線系統不建議使用該行鍵設計方式。反轉補齊是指將通過反轉(如12345反轉爲54321)可以將變化最多的部分放到行鍵前面,這樣數據的寫入也能夠順序地流入各個分區而使得集羣負載比較均衡。反轉補齊是避免熱點區間常用的方法。
  • 跳過WAL
    對於一些能夠容忍部分數據丟失的業務,如日誌系統等,可以跳過WAL寫入以提高寫入速度
  • 增加Scan緩存
    Scan操作一般需要查詢大量的數據,如果一次RPC請求就將所有數據都加載到客戶端,則請求時間會比較長,同時由於數據量大,網絡傳輸也容易出錯,因此HBase Scan API提供了一個分批拉取數據然後緩存到客戶端的功能,會根據業務需求做一個平衡,設置一個最適合業務的值。

總結

自查是挺痛苦的一件事情,但是好在自查後如果投入時間去補的話可以早點學更多東西。
不管怎麼多,學習是永無止境的,還是繼續腳踏實地,好好學習吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章