基本操作
進(jìn)入HBase客戶端命令行
[root@hadoop102 hbase]$ bin/hbase shell
查看幫助命令
hbase(main):001:0> help
查看當(dāng)前數(shù)據(jù)庫中有哪些表
hbase(main):002:0> list
表的操作
創(chuàng)建表
hbase(main):002:0> create 'student','info'
插入數(shù)據(jù)到表
hbase(main):003:0> put 'student','1001','info:sex','male'
hbase(main):004:0> put 'student','1001','info:age','18'
hbase(main):005:0> put 'student','1002','info:name','Janna'
hbase(main):006:0> put 'student','1002','info:sex','female'
hbase(main):007:0> put 'student','1002','info:age','20'
掃描查看表數(shù)據(jù)
hbase(main):008:0> scan 'student'
hbase(main):009:0> scan 'student',{STARTROW => '1001', STOPROW => '1001'}
hbase(main):010:0> scan 'student',{STARTROW => '1001'}
查看表結(jié)構(gòu)
hbase(main):011:0> describe 'student'
更新指定字段的數(shù)據(jù)
hbase(main):012:0> put 'student','1001','info:name','Nick'
hbase(main):013:0> put 'student','1001','info:age','100'
查看“指定行”或“指定列族:列”的數(shù)據(jù)
hbase(main):014:0> get 'student','1001'
hbase(main):015:0> get 'student','1001','info:name'
統(tǒng)計(jì)表數(shù)據(jù)行數(shù)
hbase(main):021:0> count 'student'
刪除數(shù)據(jù)
刪除某rowkey的全部數(shù)據(jù):
hbase(main):016:0> deleteall 'student','1001'
刪除某rowkey的某一列數(shù)據(jù)
hbase(main):017:0> delete 'student','1002','info:sex'
清空表數(shù)據(jù)
hbase(main):018:0> truncate 'student'
提示:清空表的操作順序?yàn)橄萪isable,然后再truncate。
刪除表
首先需要先讓該表為disable狀態(tài):
hbase(main):019:0> disable 'student'
然后才能drop這個(gè)表:
hbase(main):020:0> drop 'student'
提示:如果直接drop表,會(huì)報(bào)錯(cuò):ERROR: Table student is enabled. Disable it first.
變更表信息
將info列族中的數(shù)據(jù)存放3個(gè)版本:
hbase(main):022:0> alter 'student',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}
HBase進(jìn)階
RegionServer 架構(gòu)

1)StoreFile
保存實(shí)際數(shù)據(jù)的物理文件,StoreFile以Hfile的形式存儲(chǔ)在HDFS上。每個(gè)Store會(huì)有一個(gè)或多個(gè)StoreFile(HFile),數(shù)據(jù)在每個(gè)StoreFile中都是有序的。
2)MemStore
寫緩存,由于HFile中的數(shù)據(jù)要求是有序的,所以數(shù)據(jù)是先存儲(chǔ)在MemStore中,排好序后,等到達(dá)刷寫時(shí)機(jī)才會(huì)刷寫到HFile,每次刷寫都會(huì)形成一個(gè)新的HFile。
3)WAL
由于數(shù)據(jù)要經(jīng)MemStore排序后才能刷寫到HFile,但把數(shù)據(jù)保存在內(nèi)存中會(huì)有很高的概率導(dǎo)致數(shù)據(jù)丟失,為了解決這個(gè)問題,數(shù)據(jù)會(huì)先寫在一個(gè)叫做Write-Ahead logfile的文件中,然后再寫入MemStore中。所以在系統(tǒng)出現(xiàn)故障的時(shí)候,數(shù)據(jù)可以通過這個(gè)日志文件重建。
4)BlockCache
讀緩存,每次查詢出的數(shù)據(jù)會(huì)緩存在BlockCache中,方便下次查詢。
寫流程

寫流程:
1)Client先訪問zookeeper,獲取hbase:meta表位于哪個(gè)Region Server。
2)訪問對(duì)應(yīng)的Region Server,獲取hbase:meta表,根據(jù)讀請(qǐng)求的namespace:table/rowkey,查詢出目標(biāo)數(shù)據(jù)位于哪個(gè)Region Server中的哪個(gè)Region中。并將該table的region信息以及meta表的位置信息緩存在客戶端的meta cache,方便下次訪問。
3)與目標(biāo)Region Server進(jìn)行通訊;
4)將數(shù)據(jù)順序?qū)懭耄ㄗ芳樱┑絎AL;
5)將數(shù)據(jù)寫入對(duì)應(yīng)的MemStore,數(shù)據(jù)會(huì)在MemStore進(jìn)行排序;
6)向客戶端發(fā)送ack;
7)等達(dá)到MemStore的刷寫時(shí)機(jī)后,將數(shù)據(jù)刷寫到HFile。
MemStore Flush

MemStore刷寫時(shí)機(jī):
1.當(dāng)某個(gè)memstroe的大小達(dá)到了hbase.hregion.memstore.flush.size(默認(rèn)值128M),其所在region的所有memstore都會(huì)刷寫。
當(dāng)memstore的大小達(dá)到了
hbase.hregion.memstore.flush.size(默認(rèn)值128M)
- hbase.hregion.memstore.block.multiplier(默認(rèn)值4)
時(shí),會(huì)阻止繼續(xù)往該memstore寫數(shù)據(jù)。
2.當(dāng)region server中memstore的總大小達(dá)到
java_heapsize
*hbase.regionserver.global.memstore.size(默認(rèn)值0.4)
*hbase.regionserver.global.memstore.size.lower.limit(默認(rèn)值0.95),
region會(huì)按照其所有memstore的大小順序(由大到?。┮来芜M(jìn)行刷寫。直到region server中所有memstore的總大小減小到上述值以下。
當(dāng)region server中memstore的總大小達(dá)到
java_heapsize
*hbase.regionserver.global.memstore.size(默認(rèn)值0.4)
時(shí),會(huì)阻止繼續(xù)往所有的memstore寫數(shù)據(jù)。
- 到達(dá)自動(dòng)刷寫的時(shí)間,也會(huì)觸發(fā)memstore flush。自動(dòng)刷新的時(shí)間間隔由該屬性進(jìn)行配置hbase.regionserver.optionalcacheflushinterval(默認(rèn)1小時(shí))。
4.當(dāng)WAL文件的數(shù)量超過hbase.regionserver.max.logs,region會(huì)按照時(shí)間順序依次進(jìn)行刷寫,直到WAL文件數(shù)量減小到hbase.regionserver.max.log以下(該屬性名已經(jīng)廢棄,現(xiàn)無需手動(dòng)設(shè)置,最大值為32)。
讀流程
1)整體流程

2) Merge細(xì)節(jié)

讀流程
1)Client先訪問zookeeper,獲取hbase:meta表位于哪個(gè)Region Server。
2)訪問對(duì)應(yīng)的Region Server,獲取hbase:meta表,根據(jù)讀請(qǐng)求的namespace:table/rowkey,查詢出目標(biāo)數(shù)據(jù)位于哪個(gè)Region Server中的哪個(gè)Region中。并將該table的region信息以及meta表的位置信息緩存在客戶端的meta cache,方便下次訪問。
3)與目標(biāo)Region Server進(jìn)行通訊;
4)分別在MemStore和Store File(HFile)中查詢目標(biāo)數(shù)據(jù),并將查到的所有數(shù)據(jù)進(jìn)行合并。此處所有數(shù)據(jù)是指同一條數(shù)據(jù)的不同版本(time stamp)或者不同的類型(Put/Delete)。
5)將查詢到的新的數(shù)據(jù)塊(Block,HFile數(shù)據(jù)存儲(chǔ)單元,默認(rèn)大小為64KB)緩存到Block Cache。
6)將合并后的最終結(jié)果返回給客戶端。
StoreFile Compaction
由于memstore每次刷寫都會(huì)生成一個(gè)新的HFile,且同一個(gè)字段的不同版本(timestamp)和不同類型(Put/Delete)有可能會(huì)分布在不同的HFile中,因此查詢時(shí)需要遍歷所有的HFile。為了減少HFile的個(gè)數(shù),以及清理掉過期和刪除的數(shù)據(jù),會(huì)進(jìn)行StoreFile Compaction。
Compaction分為兩種,分別是Minor Compaction和Major Compaction。Minor Compaction會(huì)將臨近的若干個(gè)較小的HFile合并成一個(gè)較大的HFile,并清理掉部分過期和刪除的數(shù)據(jù)。Major Compaction會(huì)將一個(gè)Store下的所有的HFile合并成一個(gè)大HFile,并且會(huì)清理掉所有過期和刪除的數(shù)據(jù)。

Region Split
默認(rèn)情況下,每個(gè)Table起初只有一個(gè)Region,隨著數(shù)據(jù)的不斷寫入,Region會(huì)自動(dòng)進(jìn)行拆分。剛拆分時(shí),兩個(gè)子Region都位于當(dāng)前的Region Server,但處于負(fù)載均衡的考慮,HMaster有可能會(huì)將某個(gè)Region轉(zhuǎn)移給其他的Region Server。
Region Split時(shí)機(jī):
1.當(dāng)1個(gè)region中的某個(gè)Store下所有StoreFile的總大小超過hbase.hregion.max.filesize,該Region就會(huì)進(jìn)行拆分(0.94版本之前)。
2.當(dāng)1個(gè)region中的某個(gè)Store下所有StoreFile的總大小超過Min(initialSizeR^3 ,hbase.hregion.max.filesize"),該Region就會(huì)進(jìn)行拆分。其中initialSize的默認(rèn)值為2hbase.hregion.memstore.flush.size,R為當(dāng)前Region Server中屬于該Table的Region個(gè)數(shù)(0.94版本之后)。
具體的切分策略為:
第一次split:1^3 * 256 = 256MB
第二次split:2^3 * 256 = 2048MB
第三次split:3^3 * 256 = 6912MB
第四次split:4^3 * 256 = 16384MB > 10GB,因此取較小的值10GB
后面每次split的size都是10GB了。
3.Hbase 2.0引入了新的split策略:如果當(dāng)前RegionServer上該表只有一個(gè)Region,按照2 * hbase.hregion.memstore.flush.size分裂,否則按照hbase.hregion.max.filesize分裂
