hbase中的client如何路由到正確的regionserver
在hbase中,大部分的操作都是在regionserver完成的,client端想要插入,刪除,查詢
資料都需要先找到相應的 regionserver。什麼叫相應的regionserver?就是管理你要操作的那個region的regionserver。client本身並 不知道哪個regionserver管理哪個region,那麼它是如何找到相應的regionserver的?本文就是在研究原始碼
的基礎上揭秘這個過程。
在前面的文章「hbase儲存架構
」中我們已經討論了hbase基本的儲存架構。在此基礎上我們引入兩個特殊的概念:-root-和.meta.。這是什麼?它們是hbase的兩張內建表,從儲存結構和操作方法的角度來說,它們和其他hbase的表沒有任何區別,你可以認為這就是兩張普通的表,對於普通表 的操作對它們都適用。它們與眾不同的地方是hbase用它們來存貯乙個重要的系統資訊——region的分布情況以及每個region的詳細資訊。
好了,既然我們前面說到-root-和.meta.可以被看作是兩張普通的表,那麼它們和其他表一樣就應該有自己的表結構。沒錯,它們有自己的表結構,並且這兩張表的表結構是相同的,在分析原始碼
之後我將這個表結構大致的畫了出來:
我們來仔細分析一下這個結構,每條row記錄了乙個region的資訊。
首先是rowkey,rowkey由三部分組成:tablename, startkey 和 timestamp。rowkey儲存的內容我們又稱之為region的name。哦,還記得嗎?我們在前面的文章中提到的,用來存放region的檔案 夾的名字是regionname的hash值,因為regionname可能包含某些非法字元。現在你應該知道為什麼regionname會包含非法字元 了吧,因為startkey是被允許包含任何值的。將組成rowkey的三個部分用逗號連線就構成了整個rowkey,這裡timestamp使用十進位制 的數字字串來表示的。這裡有乙個rowkey的例子:
table1,rk10000,12345678
然後是表中最主要的family:info,info裡面包含三個column:regioninfo, server
, serverstartcode。其中regioninfo就是region的詳細資訊,包括startkey, endkey 以及每個family的資訊等等。server儲存的就是管理這個region的regionserver的位址。
所以當region被拆分、合併或者重新分配的時候,都需要來修改這張表的內容。
到目前為止我們已經學習了必須的背景
知識,下面我們要正式開始介紹client端尋找regionserver的整個過程。我打算用乙個假想的例子來學習這個過程,因此我先構建了假想的-root-表和.meta.表。
我們先來看.meta.表,假設hbase中只有兩張使用者表:table1和table2,table1非常大,被劃分成了很多region,因此 在.meta.表中有很多條row用來記錄這些region。而table2很小,只是被劃分成了兩個region,因此在.meta.中只有兩條row 用來記錄。這個表的內容看上去是這個樣子的:
.meta.
現在假設我們要從table2裡面插尋一條rowkey是rk10000的資料。那麼我們應該遵循以下步驟:
1. 從.meta.表裡面查詢
哪個region包含這條資料。
2. 獲取管理這個region的regionserver位址。
3. 連線這個regionserver, 查到這條資料。
好,我們先來第一步。問題是.meta.也是一張普通的表,我們需要先知道哪個regionserver管理了.meta.表,怎麼辦?有乙個方法,我們把管 理.meta.表的regionserver的位址放到zookeeper上面不久行了,這樣大家都知道了誰在管理.meta.。
貌似問題解決了,但對於這個例子我們遇到了乙個新問題。因為table1實在太大了,它的region實在太多了,.meta.為了儲存這些region信 息,花費了大量的空間,自己也需要劃分成多個region。這就意味著可能有多個regionserver在管理.meta.。怎麼辦?在 zookeeper裡面儲存所有管理.meta.的regionserver位址讓client自己去遍歷?hbase並不是這麼做的。
hbase的做法是用另外乙個表來記錄.meta.的region資訊,就和.meta.記錄使用者表的region資訊一模一樣。這個表就是-root-表。這也解釋了為什麼-root-和.meta.擁有相同的表結構,因為他們的原理是一模一樣的。
假設.meta.表被分成了兩個region,那麼-root-的內容看上去大概是這個樣子的:
-root-
這麼一來client端就需要先去訪問-root-表。所以需要知道管理-root-表的regionserver的位址。這個位址被存在zookeeper中。預設的路徑是:
/hbase/root-region-server
等等,如果-root-錶太大了,要被分成多個region怎麼辦?嘿嘿,hbase認為-root-表不會大到那個程度,因此-root-只會有乙個region,這個region的資訊也是被存在hbase內部的。
現在讓我們從頭來過,我們要查詢
table2中rowkey是rk10000的資料。整個路由過程的主要**在org.apache.hadoop.hbase.client.hconnectionmanager.tableservers中:
private hregionlocation locateregion(final byte tablename,
final byte row, boolean usecache)
throws ioexception
if (bytes.equals(tablename, root_table_name))
return this.rootregionlocation;
} } else if (bytes.equals(tablename, meta_table_name)) else
} 這是乙個遞迴呼叫的過程:
獲取table2,rowkey為rk10000的regionserver
=>
獲取.meta.,rowkey為table2,rk10000, 99999999999999的regionserver
=>
獲取-root-,rowkey為.meta.,table2,rk10000,99999999999999,99999999999999的regionserver
=>
獲取-root-的regionserver
=>
從zookeeper得到-root-的regionserver
=>
從-root-表中查到rowkey最接近(小於)
.meta.,table2,rk10000,99999999999999,99999999999999的一條row,並得到.meta.的regionserver
=>
從.meta.表中查到rowkey最接近(小於)table2,rk10000, 99999999999999的一條row,並得到table2的regionserver
=>
從table2中查到rk10000的row
到此為止client完成了路由regionserver的整個過程,在整個過程中使用了新增「99999999999999」字尾並查詢最接近(小於)rowkey的方法。對於這個方法大家可以仔細揣摩一下,並不是很難理解。
最後要提醒大家注意兩件事情:
在整個路由過程中並沒有涉及到masterserver,也就是說hbase日常的資料操作並不需要masterserver,不會造成masterserver的負擔。
client端並不會每次資料操作都做這整個路由過程,很多資料都會被cache起來。至於如何cache,則不在本文的討論範圍之內。
HBase 查詢一條資料的過程 白話理解
整體過程是 1.client訪問zk,查詢 root 表,獲取.meta.表資訊 2.從.meta.表查詢,獲取存放資料的region資訊 找到region sever 3.最後通過regionserver獲取查詢的資料 不懂?別急,我們先了解root表和meta表的結構 從這裡可以看出,meta表...
ThinkPHP find方法 查詢一條資料記錄
thinkphp find 方法是和 select 用法類似的乙個方法,不同之處 find 查詢出來的始終只有一條資料,即系統自動加上了 limit 1 限制。當確認查詢的資料記錄只能是一條記錄時,建議使用 find 方法查詢,如使用者登入賬號檢測 public function chekuser ...
優化mysql查詢最新一條資料
title 優化mysql查詢最新一條資料 date 2019 07 24 11 23 21 categories 今天寫web時,發現有個請求一直沒有響應,用谷歌f12看了一下,請求出現了乙個問題。我第一反應是網路延遲,又試了幾次,還是這個問題,便看了一下後台控制台也沒報錯,便想是不是sql查詢時...