圖片來源:尚硅谷大數據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 |
meta表記錄了HBase中全部表的元數據,包括各個表的Region的元數據(分配在哪一個RegionServer上、Row key範圍等等)。注意:meta自己也是一張表,所以也須要存儲在RegionServer上
Step1獲得的mata表元數據(meta表的存儲位置)和Step2獲得的Region的元數據(該Region的所在位置和Row key範圍)會被客戶端做爲緩存,必定時間內查詢相近數據時可以直接讀取緩存進行定位,提升查詢效率
對Step3的深刻分析前首先必須明確Store的結構:MemStore(內存) + HFile(寫入到磁盤的文件) + Block Cache(一個緩存區,也是內存)。MemStore和Block Cache都是實時運行的內存,前者存放着還沒有Flush爲HFile的數據,後者則保存着以前讀取的緩存記錄(緩存的是HFile中的數據記錄,MemStore自己也是內存,不必進行緩存)併發
以上圖爲例,當Block Cache中無緩存時,讀取數據的數據流程至關於將HFile1和HFile2加載到內存MemStore中,與MemStore中本就存在的數據記錄一塊兒進行篩選,返回符合查找條件的數據記錄。而若是在HFile2中找到了知足條件的記錄,Block Cache會對HFile2進行緩存,下一次的查找就會檢索Block Cache、MemStore和HFile1中的數據,少了一次文件的IO,會提高查找效率ide
寫數據的流程前兩步和讀數據同樣,都是通過ZooKeeper定位到所須要進行操做的RegionServer大數據
通常來講,寫入數據的流程應該是先寫入到內存,[進行排序(寫入多條時)],而後再刷寫到磁盤上。但這個機制在大數據場景下有很嚴重的風險,當大量數據寫入並在MemStore中進行排序時,若是設備出現斷電等故障,將會丟失大量數據。所以在Hbase中,RegionServer維護了一個WAL文件,充當臨時的寫入文件,當發生寫入時,數據行先是寫入到WAL中,而後再加載到MemStore中進行排序後刷寫到HFile中,這樣即使中途斷電等故障,過後重啓HBase服務也不會丟失這些數據。this
那麼,Hbase何時,或者說什麼條件下才會觸發刷寫(Flush)機制,將MemStore中的數據寫入磁盤成爲HFile文件呢?spa
flush + 表名
便可將當前表的全部Store中MemStore的全部數據排序後刷寫爲一個HFile文件<!--觸發該條件的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>