寫流程:
具體流程:
Client進行寫操作的時候,會先查詢Meta緩存中是否含有目標table的region信息以及Meta表位置信息,如果有就不再去訪問zookeeper,而是直接進行下一步的操作。如果沒有則會去訪問zookeeper,獲取hbase:meta表位於哪個Region Server。Meta表主要用於存儲用戶表和系統表的所在位置。在低版本的時,會有一個-ROOT-表,用於存儲meta表的位置信息,這個操作主要是為了預防meta表過大而需要對meta表進行切分,切分之后就會造成有多個meta表,這就需要一個表准們存儲meta表的位置信息;
獲取到meta的位置信息以后,會去訪問對應的Region Server,根據讀請求的信息namespace:table/rowkey,查詢處目標數據位於哪個Region Server中的哪個Region。並將該table的region信息以及meta表的位置信息緩存到客戶端的meta cache,方便下次訪問;
然后與得到的RegionServer通訊,將數據順序寫入(append)到WAL,此時並不進行同步操作,即並不將wal寫到hdfs
將數據寫入對應Region的memstore中,數據會在MemStore中進行排序;
同步wal,將wal寫到hdfs,如果不能同步成功則會進行回滾操作。wal和數據寫入到memstore是一個整體的事務,要么都成功要么都失敗;
上面成功后,向客戶端發送ack;
等達到MemStore的刷寫時機后,將數據刷寫到HFile中。
讀流程:
具體步驟:
1)Client 先訪問zookeeper,獲取hbase:meta 表位於哪個Region Server。
2)訪問對應的Region Server,獲取hbase:meta 表,根據讀請求的namespace:table/rowkey,查詢出目標數據位於哪個Region Server中的哪個Region中。並將該table的region信息以及meta表的位置信息緩存在客戶端的meta cache,方便下次訪問。
3)與目標Region Server進行通訊;
4)分別在Block Cache(讀緩存),MemStore和Store File(HFile)中查詢目標數據,並將查到的所有數據進行合並。此處所有數據是指同一條數據的不同版本(time stamp)或者不同的類型(Put/Delete)。
5) 將從文件中查詢到的數據塊(Block,HFile 數據存儲單元,默認大小為64KB)緩存到Block Cache。
6)將合並后的最終結果返回給客戶端。
需要注意的是,讀數據的時候,block cache、memstore、storefile中的數據要一起讀,讀出來之后要做merge(合並),merge的過程中要比較所有讀出的數據的時間戳,誰的時間戳大,就返回哪一條數據。此時,磁盤和內存是一起讀的,磁盤中的數據讀出來之后會放入block cache中,所以,讀流程無論如何都會掃描磁盤,也就造成了HBase的讀流程要慢於寫流程。
從讀寫流程的兩幅流程圖可以看出,HMaster好像並沒有參與整個的讀寫流程,其實Master可以完全不參與讀寫流程,因為讀寫數據所需的meta表位置信息是存儲在zookeeper的,zookeeper擔任了一部分Master與客戶端的交互的功能,所以即使Master掛掉了,用戶也可以在客戶端進行讀寫。但是如果Master一直處於掛掉的狀態,對於HBase集群來說是非常不健康的,比如集群中某個RegionServer出故障掛掉了,那么就無法及時將該RegionServer上的Region轉移到其他健康的RegionServer上面。