Hbase學習與總結
一.Hbase簡介:
Hbase是bigtable的開源山寨版本。它利用HadoopHDFS作為其檔案儲存系統,利用Hadoop MapReduce來處理HBase中的海量資料,利用Zookeeper作為協同服務。提供高可靠性、高效能、列儲存、可伸縮、實時讀寫的資料庫系統。
它介於nosql和RDBMS之間,僅能通過主鍵(row key)和主鍵的range來檢索資料,僅支援單行事務(可通過hive支援來實現多表join等複雜操作)。主要用來儲存非結構化和半結構化的鬆散資料。
Pig和Hive還為HBase提供了高層語言支援,使得在HBase上進行資料統計處理變的非常簡單。 Sqoop則為HBase提供了方便的RDBMS資料匯入功能,使得傳統資料庫資料向HBase中遷移變的非常方便。
與hadoop一樣,Hbase目標主要依靠橫向擴充套件,通過不斷增加廉價的商用伺服器,來增加計算和儲存能力。
二.HBase中的表一般有這樣的特點:
1 大:一個表可以有上億行,上百萬列
2 面向列:面向列(族)的儲存和許可權控制,列(族)獨立檢索。
3 稀疏:對於為空(null)的列,並不佔用儲存空間,因此,表可以設計的非常稀疏。
三.HBase訪問介面:
1. Native Java API,最常規和高效的訪問方式,適合Hadoop MapReduce Job並行批處理HBase表資料
2. HBase Shell,HBase的命令列工具,最簡單的介面,適合HBase管理使用
3. Thrift Gateway,利用Thrift序列化技術,支援C++,PHP,Python等多種語言,適合其他異構系統線上訪問HBase表資料
4. REST Gateway,支援REST 風格的Http API訪問HBase, 解除了語言限制
5. Pig,可以使用PigLatin流式程式語言來操作HBase中的資料,和Hive類似,本質最終也是編譯成MapReduce Job來處理HBase表資料,適合做資料統計
6. Hive,可以使用類似SQL語言來訪問HBase
四.Hbase表結構:
1.Row Key(行健):
用來檢索記錄主鍵,Table中的記錄按照Row Key排序。訪問hbasetable中的行,只有三種方式:1. 通過單個row key訪問;2.通過row key的range;3.全表掃描。
Row key行鍵可以是任意字串(最大長度是 64KB,實際應用中長度一般為10-100bytes),在hbase內部,row key儲存為位元組陣列。
儲存時,資料按照Row key的字典序(byteorder)排序儲存。設計key時,將經常一起讀取的行儲存放到一起。
字典序對int排序的結果是1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。要保持整形的自然序,行鍵必須用0作左填充。
2.Timestamp(時間戳):
每次資料操作對應的時間戳,可以看作是資料的version number。
HBase中通過row和columns確定的為一個存貯單元稱為cell。每個 cell都儲存著同一份資料的多個版本。版本通過時間戳來索引。時間戳的型別是 64位整型。時間戳可以由hbase(在資料寫入時自動 )賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也可以由客戶顯式賦值。如果應用程式要避免資料版本衝突,就必須自己生成具有唯一性的時間戳。每個 cell中,不同版本的資料按照時間倒序排序,即最新的資料排在最前面。
為了避免資料存在過多版本造成的的管理 (包括存貯和索引)負擔,hbase提供了兩種資料版本回收方式。一是儲存資料的最後n個版本,二是儲存最近一段時間內的版本(比如最近七天)。使用者可以針對每個列族進行設定。
3.Column Family(列族):
hbase表中的每個列,都歸屬與某個列族,Table在水平方向有一個或者多個ColumnFamily組成,一個Column Family中可以由任意多個Column組成,即Column Family支援動態擴充套件,列族必須在使用表之前定義。列名都以列族作為字首。例如courses:history,courses:math都屬於courses這個列族。無需預先定義Column的數量以及型別,所有Column均以二進位制格式儲存,使用者需要自行進行型別轉換。
訪問控制、磁碟和記憶體的使用統計都是在列族層面進行的。實際應用中,列族上的控制權限能 幫助我們管理不同型別的應用:我們允許一些應用可以新增新的基本資料、一些應用可以讀取基本資料並建立繼承的列族、一些應用則只允許瀏覽資料(甚至可能因 為隱私的原因不能瀏覽所有資料)。
4.Cell:
由{row key, column(=<family> + <label>), version}唯一確定的單元。cell中的資料是沒有型別的,全部是位元組碼形式存貯。
5.-ROOT- && .META.Table
HBase中有兩張特殊的Table,-ROOT-和.META.
Ø .META.:記錄了使用者表的Region資訊,.META.可以有多個regoin
Ø -ROOT-:記錄了.META.表的Region資訊,-ROOT-只有一個region
Ø Zookeeper中記錄了-ROOT-表的location
三.物理儲存:
1 Table中的所有行都按照rowkey的字典序排列。
2 Table 在行的方向上分割為多個Hregion。
3 region按大小分割的,每個表一開始只有一個region,隨著資料不斷插入表,region不斷增大,當增大到一個閥值的時候,Hregion就會等分會兩個新的Hregion。當table中的行不斷增多,就會有越來越多的Hregion。
4 Hregion是Hbase中分散式儲存和負載均衡的最小單元。最小單元就表示不同的Hregion可以分佈在不同的HRegionserver上。但一個Hregion是不會拆分到多個server上的。
5 HRegion雖然是分散式儲存的最小單元,但並不是儲存的最小單元。
事實上,HRegion由一個或者多個Store組成,每個store儲存一個columns family。
每個Strore又由一個memStore和0至多個StoreFile組成。如圖:
StoreFile以HFile格式儲存在HDFS上。
五、系統架構
Client:
包含訪問hbase的介面,client維護著一些cache來加快對hbase的訪問,比如regione的位置資訊。
Zookeeper
1 保證任何時候,叢集中只有一個master
2 存貯所有Region的定址入口。
3 實時監控Region Server的狀態,將Regionserver的上線和下線資訊實時通知給Master
4 儲存Hbase的schema,包括有哪些table,每個table有哪些columnfamily
Master
1 為Region server分配region
2 負責region server的負載均衡
3 發現失效的region server並重新分配其上的region
4 GFS上的垃圾檔案回收
5 處理schema更新請求
Region Server
1 Region server維護Master分配給它的region,處理對這些region的IO請求
2 Region server負責切分在執行過程中變得過大的region
六.關鍵流程:
1.region定位:
.META.是一個特殊的表,儲存了hbase中所有資料表的region位置資訊。
root region永遠不會被split,保證了最需要三次跳轉,就能定位到任意region 。
.META.表每行儲存一個region的位置資訊,rowkey 採用表名+表的最後一樣編碼而成。
為了加快訪問,.META.表的全部region都儲存在記憶體中。
2.region分配
任何時刻,一個region只能分配給一個region server。master記錄了當前有哪些可用的region server。以及當前哪些region分配給了哪些region server,哪些region還沒有分配。當存在未分配的region,並且有一個region server上有可用空間時,master就給這個region server傳送一個裝載請求,把region分配給這個region server。regionserver得到請求後,就開始對此region提供服務。
3.region server上線
master使用zookeeper來跟蹤regionserver狀態。當某個region server啟動時,會首先在zookeeper上的server目錄下建立代表自己的檔案,並獲得該檔案的獨佔鎖。由於master訂閱了server目錄上的變更訊息,當server目錄下的檔案出現新增或刪除操作時,master可以得到來自zookeeper的實時通知。因此一旦region server上線,master能馬上得到訊息。
4.region server下線
當region server下線時,它和zookeeper的會話斷開,zookeeper而自動釋放代表這臺server的檔案上的獨佔鎖。而master不斷輪詢server目錄下檔案的鎖狀態。如果master發現某個region server丟失了它自己的獨佔鎖,(或者master連續幾次和region server通訊都無法成功),master就是嘗試去獲取代表這個region server的讀寫鎖,一旦獲取成功,就可以確定:
1 )region server和zookeeper之間的網路斷開了。
2 )region server掛了。
的其中一種情況發生了,無論哪種情況,region server都無法繼續為它的region提供服務了,此時master會刪除server目錄下代表這臺regionserver的檔案,並將這臺region server的region分配給其它還活著的同志。
如果網路短暫出現問題導致region server丟失了它的鎖,那麼regionserver重新連線到zookeeper之後,只要代表它的檔案還在,它就會不斷嘗試獲取這個檔案上的鎖,一旦獲取到了,就可以繼續提供服務。
5.master上線
master啟動進行以下步驟:
1) 從zookeeper上獲取唯一一個程式碼master的鎖,用來阻止其它master成為master。
2 )掃描zookeeper上的server目錄,獲得當前可用的region server列表。
3) 和2)中的每個regionserver通訊,獲得當前已分配的region和regionserver的對應關係。
4 )掃描.META.region的集合,計算得到當前還未分配的region,將他們放入待分配region列表。
6.master下線
由於master只維護表和region的元資料,而不參與表資料IO的過程,master下線僅導致所有元資料的修改被凍結(無法建立刪除表,無法修改表的schema,無法進行region的負載均衡,無法處理region上下線,無法進行region的合併,唯一例外的是region的split可以正常進行,因為只有regionserver參與),表的資料讀寫還可以正常進行。因此master下線短時間內對整個hbase叢集沒有影響。從上線過程可以看到,master儲存的 資訊全是可以冗餘資訊(都可以從系統其它地方收集到或者計算出來),因此,一般hbase叢集中總是有一個master在提供服務,還有一個以上 的’master’在等待時機搶佔它的位置。
七.實戰練習:
先啟動hadoop,然後.啟動hbase:jps檢視,注意在master(即HMater)節點上有HMaster和HRegionServer、HQuorumPeer三個服務項,在datanode(即HRegionServer)中檢視需要啟動的是HQuorumPeer和HRegionServer。
通過WEB檢視hbase:
檢視Master http://master:60010/master.jsp
檢視Region Serverhttp://slave:60030/regionserver.jsp
以下面這個表格為例子,練習hbase shell命令
這裡grad對於表來說是一個只有它自己的列族,course對於表來說是一個有兩個列的列族,這個列族由兩個列組成math和art,當然我們可以根據我們的需要在course中建立更多的列族,如computer,physics等相應的列新增入course列族。
hbase(main):001:0> create ‘scores','grade',‘course'
put‘scores','Tom','grade:','5′
put ‘scores','Tom','course:math','97′
put ‘scores','Tom','course:art','87′
put ‘scores','Jim','grade','4′
put ‘scores','Jim','course:math','89′
put ‘scores','Jim','course:art','80′
put命令比較簡單,只有這一種用法:
hbase> put ‘t1′, ‘r1′, ‘c1′, ‘value', ts1
t1指表名,r1指行鍵名,c1指列名,value指單元格值。ts1指時間戳,一般都省略掉了。
根據鍵值查詢資料:
hbase(main):013:0> get 'scores','Jim'
COLUMN CELL
course:art timestamp=1371374709443,value=80
course:math timestamp=1371374691043,value=89
grade: timestamp=1371374659931, value=4
3row(s) in 0.0360 seconds
hbase(main):014:0> get 'scores','Jim','grade'
COLUMN CELL
grade: timestamp=1371374659931,value=4
1row(s) in 0.0230 seconds
hbase(main):015:0> scan'scores'
ROW COLUMN+CELL
Jim column=course:art,timestamp=1371374709443, value=80
Jim column=course:math,timestamp=1371374691043, value=89
Jim column=grade:,timestamp=1371374659931, value=4
Tom column=course:art,timestamp=1371374627295, value=87
Tom column=course:math,timestamp=1371374609639, value=97
Tom column=grade:,timestamp=1371374578670, value=5
2row(s) in 0.1150 seconds
刪除指定資料
delete ‘scores','Jim','grade'
Deleteall ‘score’,’Jim’ //刪除整行
修改表結構disable ‘scores'
alter ‘scores',NAME=>'info' //新增一個列族
enable ‘scores'
count ‘scores’ //查詢表中有多少行