HBase读写流程
HBase寫流程
假如說我們要插入一條數據到某個表里面,會經歷的過程如下圖:?
概述
-
Client會先訪問zookeeper,得到對應的RegionServer地址
-
Client對RegionServer發起寫請求,RegionServer接受數據寫入內存
-
當MemStore的大小達到一定的值后,flush到StoreFile并存儲到HDFS
詳細流程
-
Client首先會去訪問Zookeeper,從Zookeeper里面去獲取表的相關信息以及表的region的相關信息,根據我們要插入的RowKey去獲取指定的RegionServer的信息(如果是批量提交的話,會把RowKey根據HRegionLocation進行分組)
-
當我們得到了需要訪問的RegionServer之后,Client就會向對應的RegionServer發起寫請求;RegionServer收到請求之后,會執行各種的檢查操作:比如會看下對應的Region是否處于只讀狀態、MemoryStore大小是否超過了BlockingMemoryStoreSize等等
-
檢查完成之后進行真正的數據寫入操作,RegionServer依次將數據寫入到MemStore和HLog,只有這兩者都寫入成功之后,此次寫入才算成功
-
整個過程比較復雜,需要去獲取到相關的鎖,寫入到MemStore和HLog是事務型操作,要么全部寫入成功要么就是失敗
-
當MemStore達到我們設定的閾值之后,會將MemStore中的數據flush成StoreFile文件;當StoreFile文件增加到一定數量的時候,會觸發compact合并機制,將多個StoreFile文件合并成一個大的StoreFile文件;如果單個StoreFile文件達到一定的閾值,會觸發spilt機制,將Region一分為二,然后HMaster給2個region分配相應的RegionServer進行管理,從而分擔壓力
剖析RegionServer內部
-
RegionServer處理數據的輸入輸出請求,同時每個RegionServer管理著多個Region?
每個RegionServer都有對應的HLog實例 -
Region是HBase存儲的基本單元,數據都存儲在Region當中?
每一個Region只存儲一個ColumnFamily的數據,且只是這個ColumnFamily的一部分?
當Region的大小達到某個閾值之后,會根據RowKey的排序劃分為多個Region -
而每個Region里面又包含了多個Store?
每一個Store里面包含了1個MemStore和1個或是多個StoreFile?
MemStore便是數據在內存中的實體,而且有序 -
當有數據寫入的時候,會先寫入到MemStore,當MemStore的大小達到上限之后?
Store會去創建StoreFile(這里的StoreFile是HFile的一層封裝;HBase依賴于HDFS,HFile存儲在HDFS上)?
因此MemStore的數據最終會寫入到HFile之中 -
那么HBase如何保證MemStore中的數據不會丟失呢??
HLog就是WAL的一種實現,WAL是預寫日志,是事務機制中常見的一致性的實現方式對于每個RegionServer,都會有一個HLog的實例,RegionServer會將更新操作記錄到MemStore,然后再更新到HLog當中,只有當HLog更新完成之后,這條記錄才算真正成功的寫入;這樣,即使MemStore中的數據丟失了,還是可以通過HLog找回來 -
一般的WAL是先寫入日志,再寫入內存的?
而對于HBase是先寫入內存再寫入日志,依托于MVCC模式確保一致性 -
如果HFile丟失了怎么辦??
HFile是存儲在HDFS上的,默認的備份是3份,所以這里并不考慮HFile丟失的可能性
HBase讀流程
概述
-
Client會先訪問zookeeper,得到對應的RegionServer地址
-
Client對RegionServer發起讀請求
-
當RegionServer收到client的讀請求后,先掃描自己的Memstore,再掃描BlockCache(加速內容緩存區)如果還沒找到則StoreFile中讀取數據,然后將數據返回給Client
詳細流程
-
Client與Zookeeper建立連接
-
然后通過Zookeeper訪問meta,將HBase的meta表緩存到本地
-
通過緩存的meta表,獲取要訪問的表所對應的RegionServer的信息
-
當Client知道要訪問的表在哪個RegionServer之后,Client就向對應的RegionServer發起讀請求,RegionServer獲取到請求并進行復雜的處理之后,就會將數據返回給客戶端
-
那么RegionServer具體做哪些事情呢??
首先RegionServer先掃描自己的MemStore?
如果沒有找到數據再掃描BlockCache?
如果還沒有找到的話,就去StoreFile里面查找數據,最后將這條數據返回給Client
關于HBase讀寫流程的注意點
通過讀和寫的流程我們可以發現與HMaster沒有一點關系,Client請求數據的時候只需要知道Zookeeper的地址就可以了(這部分與HMaster沒有關系,也不需要提前知道RegionServer的IP)
那么為什么Client只需要訪問Zookeeper就可以了呢??
因為HMaster在啟動的時候會將meta的信息加載到Zookeeper,這個表里面存儲了HBase里面所有的表、所有的Region的詳細信息?
比如說:Region開始的key、結束的key;所在的RegionServer的地址等等?
HBase的meta表此刻就相當于是一個目錄,通過它可以快速的定位到數據的實際位置?
因此讀寫操作只需要與Zookeeper、以及對應的RegionServer交互就可以了,而HMaster只需要維護table和region的元數據信息、協調各個RegionServer就行了,所以它的負載就小了很多
HBase模塊協作
HBase啟動時發生了什么
-
HMaster啟動,注冊到Zookeeper,等待RegionServer匯報?
注冊的時候首先將自己注冊到backup mater節點?
這樣做的原因是,因為我們可能有很多個master,最終的active master是要看它們搶占的速度的,所以說它們默認的會先寫入到backup master節點,如果它們搶占到鎖之后,成為active狀態,然后將自己從backup master中去刪除;只有在成為active master之后,才會去實例化一些相關的類;當master節點成功的轉變成為active狀態之后,這時候它就會去等待RegionServer節點向他進行報告 -
RegionServer注冊到Zookeeper,并向HMaster匯報
-
HMaster對各個RegionServer(包括失效的)的數據進行整理,分配Region和meta信息?
當所有的數據整理完全之后,整理的是一張meta表(表里記錄的是所有表相關的region信息、各個RegionServer負責的是哪些數據等等),之后就將meta表交給Zookeeper -
Backup master會定期地從active master處保持數據的更新,從而保障自己的meta表是最新的
-
RegionServer在啟動之后,且正式的注冊進集群之后,有很多工作要做,比如:設置WAL預寫日志相關的一些信息、定期的去刷新MemStore保證最終的數據寫入到HFile文件等等
當RegionServer失效后發生什么
-
Zookeeper感知到后會向HMaster匯報,然后HMaster會將失效的RegionServer從meta表中刪除,同時將RegionServer上的Region分配到其它節點
-
HMaster更新hbase:meta表以保證數據正常訪問
當HMaster失效后會發生什么
-
配置了HA:?
處于Backup狀態的其它HMaster節點推選出一個轉為Active狀態 -
沒有配置HA:?
該讀取數據還是需要讀取,該寫入數據還是需要寫入?
但是像新建表、修改表結構,是不能操作的,會拋出異常?
數據能正常讀寫,但是不能創建刪除表,也不能更改表結構(因為這些操作會涉及到meta表的更新,而HMaster是處于失效的狀態,因此是不能操作的)
總結
- 上一篇: Spark transformation
- 下一篇: Spark内存管理(1)—— 静态内存管