HBase的讀和寫

1. HBase的結構(基礎 & 重點!!!)

XX.png

YY.png

圖片來源:尚硅谷大數據HBase課程

HBase的結構很是重要!!!必定要牢記分清!緩存

對比MySQL記憶安全

HBase MySQL
NameSpace DataBase
Table Table
Row key id
columns family columns...
Region SELECT * FROM TABLE WHERE nu BETWEEN AND j
Store SELECT columns... FROM TABLE WHERE id BETWEEN AND j

2. Read

R.png

2.1 讀數據的流程

  • Step1:客戶端遞交請求到ZooKeeper,獲取HBase集羣的meta表存放在哪個RegionServer(Linux設備)上
meta表記錄了HBase中全部表的元數據,包括各個表的Region的元數據(分配在哪一個RegionServer上、Row key範圍等等)。注意:meta自己也是一張表,所以也須要存儲在RegionServer上
  • Step2:客戶端根據ZooKeeper返回的meta表找到meta表存放的RegionServer,並和該RegionServer創建通訊,讀取meta表信息,獲取查詢指令【查詢指令中包含條件:Table & Row key】須要檢索的Region存放在哪一個RegionServer上
Step1獲得的mata表元數據(meta表的存儲位置)和Step2獲得的Region的元數據(該Region的所在位置和Row key範圍)會被客戶端做爲緩存,必定時間內查詢相近數據時可以直接讀取緩存進行定位,提升查詢效率
  • Step3:客戶端獲得須要的Region位置後,與該Region所在的RegionServer進行通訊並讀取須要的數據記錄(重點分析步驟)

2.2 Step3的深刻分析

對Step3的深刻分析前首先必須明確Store的結構:MemStore(內存) + HFile(寫入到磁盤的文件) + Block Cache(一個緩存區,也是內存)。MemStore和Block Cache都是實時運行的內存,前者存放着還沒有Flush爲HFile的數據,後者則保存着以前讀取的緩存記錄(緩存的是HFile中的數據記錄,MemStore自己也是內存,不必進行緩存)
1596564038(1).png併發

以上圖爲例,當Block Cache中無緩存時,讀取數據的數據流程至關於將HFile1和HFile2加載到內存MemStore中,與MemStore中本就存在的數據記錄一塊兒進行篩選,返回符合查找條件的數據記錄。而若是在HFile2中找到了知足條件的記錄,Block Cache會對HFile2進行緩存,下一次的查找就會檢索Block Cache、MemStore和HFile1中的數據,少了一次文件的IO,會提高查找效率ide

3. Write

W.png

3.1 寫數據的流程

寫數據的流程前兩步和讀數據同樣,都是通過ZooKeeper定位到所須要進行操做的RegionServer大數據

通常來講,寫入數據的流程應該是先寫入到內存,[進行排序(寫入多條時)],而後再刷寫到磁盤上。但這個機制在大數據場景下有很嚴重的風險,當大量數據寫入並在MemStore中進行排序時,若是設備出現斷電等故障,將會丟失大量數據。所以在Hbase中,RegionServer維護了一個WAL文件,充當臨時的寫入文件,當發生寫入時,數據行先是寫入到WAL中,而後再加載到MemStore中進行排序後刷寫到HFile中,這樣即使中途斷電等故障,過後重啓HBase服務也不會丟失這些數據。this

3.2 Flush機制

那麼,Hbase何時,或者說什麼條件下才會觸發刷寫(Flush)機制,將MemStore中的數據寫入磁盤成爲HFile文件呢?spa

  • 手動Flush:在HBase客戶端命令行中執行flush + 表名便可將當前表的全部Store中MemStore的全部數據排序後刷寫爲一個HFile文件
  • MemStore達到內存限制:阻塞寫的Flush和不阻塞寫的Flush
<!--觸發該條件的Flush不會阻塞寫操做,可併發進行-->

<!--單個MemStore的最大內存,當實際達到這個限制,會觸發Flush-->
<property>  
        <name>hbase.hregion.memstore.flush.size</name>  
        <value>134217728</value>  
        <description>  
            Memstore will be flushed to disk if size of the memstore  
            exceeds this number of bytes. Value is checked by a thread that runs  
            every hbase.server.thread.wakefrequency.  
        </description>  
</property>
<!--觸發如下參數的Flush會阻塞寫操做,即Flush完成前不支持寫入-->

<!--Region中全部MemStore實際大小總和爲默認單個MemStore分配內存大小的倍數-->
<property>  
       <name>hbase.hregion.memstore.block.multiplier</name> 
       <value>4</value>  
</property>  


<!--能夠理解爲一個安全的設置,有時候集羣的「寫負載」很是高,寫入量一直超過flush的量,
這時,咱們就但願memstore不要超過必定的安全設置。在這種狀況下,寫操做就要被阻塞一直
到memstore恢復到一個「可管理」的大小, 這個大小就是默認值是堆大小 * 0.4 * 0.95,也就
是當regionserver級別的flush操做發送後,會阻塞客戶端寫,一直阻塞到整個regionserver級
別的memstore的大小爲 堆大小 * 0.4 *0.95爲止 --> 
<property>  
    <name>hbase.regionserver.global.memstore.size.lower.limit</name>          
    <value></value> 
</property>  

<!--整個RegionServer中爲全部Store分配的MemStore內存大小佔堆內存的比例,默認爲0.4-->
<property>
    <name>hbase.regionserver.global.memstore.size</name>  
    <value></value>   
</property>
  • 到達自動刷寫時間
<!--這個時間是指內存中最後一條數據最後一次編輯的時間以後若是1小時沒有數據操做,將會觸發自動刷寫-->
<property>  
    <name>hbase.regionserver.optionalcacheflushinterval</name>
    <value>3600000</value>  
        <description>  
            Maximum amount of time an edit lives in memory before being automatically  
            flushed.  Default 1 hour. Set it to 0 to disable automatic flushing.  
        </description>      
</property>
  • WAL文件數量達到限制:當WAL文件的數量超過32個時,region 會按照時間順序依次進行刷寫,直到WAL文件數量減少到32如下
相關文章
相關標籤/搜索