什么是HBase?
是?個(gè)分布式准给、海量泄朴、列式重抖、?關(guān)系型 數(shù)據(jù)庫系統(tǒng),可以提供超?規(guī)模數(shù)據(jù)集的實(shí)時(shí)隨機(jī)讀寫
列存儲的優(yōu)點(diǎn):
- 1)減少存儲空間占?祖灰。
- 2)?持好多列
HBase的特點(diǎn)
-
海量存儲:底層基于
HDFS
存儲海量數(shù)據(jù) -
列式存儲:
HBase
表的數(shù)據(jù)是基于列族進(jìn)?存儲的钟沛,?個(gè)列族包含若?列 -
極易擴(kuò)展:底層依賴
HDFS
,當(dāng)磁盤空間不?的時(shí)候夫植,只需要?jiǎng)討B(tài)增加DataNode
服務(wù)節(jié)點(diǎn)就可以 - ?并發(fā):?持?并發(fā)的讀寫請求
- 稀疏:稀疏主要是針對HBase列的靈活性讹剔,在列族中,你可以指定任意多的列详民,在列數(shù)據(jù)為空的情況下延欠,是不會占?存儲空間的。
-
數(shù)據(jù)的多版本:
HBase
表中的數(shù)據(jù)可以有多個(gè)版本值沈跨,默認(rèn)情況下是根據(jù)版本號去區(qū)分由捎,版本號就是插?數(shù)據(jù)的時(shí)間戳 -
數(shù)據(jù)類型單?:所有的數(shù)據(jù)在
HBase
中是以字節(jié)數(shù)組進(jìn)?存儲
HBase應(yīng)用場景
-
HBase
適合海量明細(xì)數(shù)據(jù)的存儲饿凛,并且后期需要有很好的查詢性能(單表超千萬狞玛、上億,且并發(fā)要求?)
HBase數(shù)據(jù)模型
-
HBase
中的每一張表就是所謂的BigTable
涧窒。 -
BigTable
會存儲一系列的行記錄心肪,行記錄有三個(gè)基本類型的定義:-
RowKey
:是行在BigTable
中的唯一標(biāo)識 -
TimeStamp
:是每一次數(shù)據(jù)操作對應(yīng)關(guān)聯(lián)的時(shí)間戳,可以看作SVN
的版本 -
Column
:定義為<family>:<label>纠吴,通過這兩部分可以指定唯一的數(shù)據(jù)的存儲列-
family
:定義和修改需要對HBase
進(jìn)行類似于DB
的DDL
操作硬鞍,另一個(gè)作用體現(xiàn)在物理存儲優(yōu)化讀寫操作上,同family
的數(shù)據(jù)物理上保存的會比較接近 -
<label>
:不需要定義直接可以使用戴已,這也為動(dòng)態(tài)定制列提供了一種手段
-
-
邏輯存儲模型
-
RowKey:與
NoSQL
數(shù)據(jù)庫一樣固该,RowKey
是用來檢索記錄的主鍵- 訪問
HBase Table
中的行三種方式:- 通過單個(gè)
RowKey
訪問 - 通過
RowKey
的Range
- 全表掃描
- 通過單個(gè)
- 注意:
-
RowKey
行鍵可以任意字符串(最大長度64KB,實(shí)際應(yīng)用中長度一般為10-100bytes)糖儡,在HBase
內(nèi)部RowKey
保存為字節(jié)數(shù)組伐坏。 - 存儲時(shí),數(shù)據(jù)按照
RowKey
的字典序(byte order
)排序存儲握联,設(shè)計(jì)key
時(shí)桦沉,要充分了解這個(gè)特性,將經(jīng)常一起讀取的行存放在一起拴疤。 - 行的一次讀寫是原子操作(不論一次讀寫多少列)
-
- 訪問
-
列簇:
HBase
表中的每個(gè)列永部,都?xì)w屬于某個(gè)列簇,列簇是表的schema
的一部分(而列不是)呐矾,必須在使用表之前定義苔埋。- 列名都以列簇作為前綴,例如:
courses:history
,courses:math
都屬于courses
這個(gè)列簇蜒犯。 - 訪問控制组橄,磁盤和內(nèi)存的使用統(tǒng)計(jì)都是在列簇層面進(jìn)行的荞膘。
- 實(shí)際應(yīng)用中,列簇上的控制權(quán)限能幫助我們管理不同類型的應(yīng)用:我們允許一些應(yīng)用可以添加新的基本數(shù)據(jù)
- 列名都以列簇作為前綴,例如:
-
時(shí)間戳:
HBase
中通過row
和columns
確定的為一個(gè)存儲單元稱為cell
玉工。每個(gè)cell
都保存著同一份數(shù)據(jù)的多個(gè)版本羽资。版本通過時(shí)間戳來索引- 時(shí)間戳的類型是64位整型,時(shí)間戳可以由
HBase
在寫入時(shí)自動(dòng)賦值遵班,此時(shí)時(shí)間戳是精確到毫秒的當(dāng)前系統(tǒng)時(shí)間屠升。時(shí)間戳也可以由客戶顯示賦值
- 時(shí)間戳的類型是64位整型,時(shí)間戳可以由
-
Cell:由
{row key, column(=+), version}
唯一確定的單元-
Cell
中的數(shù)據(jù)是沒有類型的,全部是字節(jié)碼形式存儲
-
HBase整體架構(gòu)
-
HBase
仍然采用Master/Slave
架構(gòu)
Zookeeper:
- 實(shí)現(xiàn)了
HMaster
的?可? - 保存了
HBase
的元數(shù)據(jù)信息狭郑,是所有HBase
表的尋址?? - 對
HMaster
和HRegionServer
實(shí)現(xiàn)了監(jiān)控
HMaster(Master):
- 為
HRegionServer
分配Region
- 維護(hù)整個(gè)集群的負(fù)載均衡
- 維護(hù)集群的元數(shù)據(jù)信息
- 發(fā)現(xiàn)失效的
Region
腹暖,并將失效的Region
分配到正常的HRegionServer
上
HRegionServer(RegionServer)
- 負(fù)責(zé)管理
Region
- 接受客戶端的讀寫數(shù)據(jù)請求
- 切分在運(yùn)?過程中變?的
Region
Region
- 每個(gè)
HRegion
由多個(gè)Store
構(gòu)成, - 每個(gè)
Store
保存?個(gè)列族(Columns Family
)翰萨,表有?個(gè)列族脏答,則有?個(gè)Store
, - 每個(gè)
Store
由?個(gè)MemStore
和多個(gè)StoreFile
組成亩鬼,MemStore
是Store
在內(nèi)存中的內(nèi)容殖告,寫到?件后就是StoreFile
。StoreFile
底層是以HFile
的格式保存雳锋。
Hbase環(huán)境安裝
tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/servers
mv /opt/servers/hbase-1.3.1 /opt/servers/hbase
# 配置環(huán)境變量
export HBASE_HOME=/opt/servers/hbase
export PATH=$PATH:$HBASE_HOME/bin
修改配置?件
- 需要把
hadoop
中的配置core-site.xml
黄绩、hdfs-site.xml
拷?到hbase
安裝?錄下的conf
?件夾中
ln -s /opt/servers/hadoop-2.9.2/etc/hadoop/core-site.xml /opt/servers/hbase/conf/core-site.xml
ln -s /opt/servers/hadoop-2.9.2/etc/hadoop/hdfs-site.xml /opt/servers/hbase/conf/hdfs-site.xml
- 修改
hbase-env.sh
#添加java環(huán)境變量
export JAVA_HOME=/opt/servers/jdk1.8
#指定使?外部的zk集群
export HBASE_MANAGES_ZK=FALSE
- 修改
hbase-site.xml
<!-- 指定hbase在HDFS上存儲的路徑 -->
<property>
<name>hbase.rootdir</name>
<value>hdfs://os1:9000/hbase</value>
</property>
<!-- 指定hbase是分布式的 -->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 指定zk的地址,多個(gè)?“,”分割 -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>os1:2181,os2:2181,os3:2181</value>
</property>
- 修改
regionservers
?件
#指定regionserver節(jié)點(diǎn)
os1
os2
os3
-
hbase
的conf
?錄下創(chuàng)建?件backup-masters (Standby Master)
echo 'os2' > backup-masters
- 分發(fā)hbase?錄和環(huán)境變量到其他節(jié)點(diǎn)
HBase集群的啟動(dòng)和停?
- 前提條件:先啟動(dòng)
hadoop
和zookeeper
集群 - 啟動(dòng):
start-hbase.sh
- 停?:
stop-hbase.sh
HBase shell 基本操作
- 進(jìn)入
hbase
客戶端
hbase shell
創(chuàng)建?張表玷过, 包含兩個(gè)列族
create 'test1', 'base_info', ''
create 'test2', {NAME => 'base_info', VERSIONS => '3'},{NAME => 'extra_info',VERSIONS => '3'}
添加數(shù)據(jù)操作
put 'test1', 'rk1', 'base_info:name', 'test'
put 'test1', 'rk1', 'base_info:age', 30
查詢數(shù)據(jù)
- 通過
rowkey
進(jìn)?查詢
get 'test1', 'rk1'
- 查看
rowkey
下?的某個(gè)列族的信息
get 'test1', 'rk1', 'base_info'
get 'test1', 'rk1', 'base_info:name', 'base_info:age'
- 查看
rowkey
指定多個(gè)列族的信息
get 'test1', 'rk1', 'base_info', 'extra_info'
get 'test1', 'rk1', {COLUMN => ['base_info:name', 'extra_info:address']}
- 指定
rowkey
與列值查詢
get 'test1', 'rk1', {FILTER => "ValueFilter(=, 'binary:test')"}
- 指定
rowkey
模糊查詢
get 'test', 'rk1', {FILTER => "(QualifierFilter(=,'substring:e'))"}
- 查詢所有數(shù)據(jù)
scan 'test1'
- 列族查詢
scan 'test1', {COLUMNS => 'base_info', RAW => true, VERSIONS => 3}
- 指定
rowkey
模糊查詢
scan 'test1',{FILTER=>"PrefixFilter('rk')"}
更新
put 'test1', 'rk1', 'base_info:name', 'test2'
刪除數(shù)據(jù)和表
- 指定
rowkey
以及列名進(jìn)?刪除
delete 'test1', 'rk1', 'base_info:name'
- 刪除列族
alter 'test1', 'delete' => 'base_info'
- 清空表數(shù)據(jù)
truncate 'test1'
- 刪除表:先
disable
再drop
disable 'test1'
drop 'test1'
HBase原理深?
HBase讀數(shù)據(jù)流程
- 1)?先從
zk
找到meta
表的region
位置宝与,然后讀取meta
表中的數(shù)據(jù),meta
表中存儲了?戶表的region
信息 - 2)根據(jù)要查詢的
namespace
冶匹、表名和rowkey
信息。找到寫?數(shù)據(jù)對應(yīng)的region
信息 - 3)找到這個(gè)
region
對應(yīng)的regionServer
咆瘟,然后發(fā)送請求 - 4)查找對應(yīng)的
region
- 5)先從
memstore
查找數(shù)據(jù)嚼隘,如果沒有,再從BlockCache
上讀取
HBase
上Regionserver
的內(nèi)存分為兩個(gè)部分- ?部分作為
Memstore
袒餐,主要?來寫飞蛹; - 另外?部分作為
BlockCache
,主要?于讀數(shù)據(jù)灸眼;
- ?部分作為
- 6)如果
BlockCache
中也沒有找到卧檐,再到StoreFile
上進(jìn)?讀取- 從
storeFile
中讀取到數(shù)據(jù)之后,不是直接把結(jié)果數(shù)據(jù)返回給客戶端焰宣, ?是把數(shù)據(jù)先寫?到BlockCache
中霉囚,?的是為了加快后續(xù)的查詢; - 然后在返回結(jié)果給客戶端匕积。
- 從
HBase寫數(shù)據(jù)流程
- 1)?先從
zk
找到meta
表的region
位置盈罐,然后讀取meta
表中的數(shù)據(jù)榜跌,meta
表中存儲了?戶表的region
信息 - 2)根據(jù)
namespace
、表名和rowkey
信息盅粪。找到寫?數(shù)據(jù)對應(yīng)的region
信息 - 3)找到這個(gè)
region
對應(yīng)的regionServer
钓葫,然后發(fā)送PUT
請求 - 4)把數(shù)據(jù)分別寫到
HLog(write ahead log)
和memstore
各?份 - 5)
memstore
達(dá)到閾值后把數(shù)據(jù)刷到磁盤,?成storeFile
?件 - 6)刪除
HLog
中的歷史數(shù)據(jù)
HBase的flush(刷寫)及compact(合并)機(jī)制
Flush機(jī)制
- 當(dāng)
memstore
的??超過這個(gè)值的時(shí)候票顾,會flush
到磁盤础浮,默認(rèn)為128M
<property>
<name>hbase.hregion.memstore.flush.size</name>
<value>134217728</value>
</property>
- 當(dāng)
memstore
中的數(shù)據(jù)時(shí)間超過1?時(shí),會flush
到磁盤
<property>
<name>hbase.regionserver.optionalcacheflushinterval</name>
<value>3600000</value>
</property>
-
HregionServer
的全局memstore
的??奠骄,超過該??會觸發(fā)flush
到磁盤的操作,默認(rèn)是堆??的40%
<property>
<name>hbase.regionserver.global.memstore.size</name>
<value>0.4</value>
</property>
- ?動(dòng)
flush
flush tableName
阻塞機(jī)制
-
Hbase
中是周期性的檢查是否滿?以上標(biāo)準(zhǔn)滿?則進(jìn)?刷寫豆同,但是如果在下次檢查到來之前,數(shù)據(jù)瘋狂寫?Memstore
中戚揭,會觸發(fā)阻塞機(jī)制诱告,此時(shí)?法寫?數(shù)據(jù)到Memstore
,數(shù)據(jù)?法寫?Hbase
集群- 1)
memstore
中數(shù)據(jù)達(dá)到512MB
計(jì)算公式:
hbase.hregion.memstore.flush.size
刷寫的閥值民晒,默認(rèn)是134217728
精居,即128MB
。hbase.hregion.memstore.block.multiplier
是?個(gè)倍數(shù)潜必,默認(rèn)是4
靴姿。-
2)
RegionServer
全部memstore
達(dá)到規(guī)定值-
hbase.regionserver.global.memstore.size.lower.limit
是0.95
, -
hbase.regionserver.global.memstore.size
是0.4
磁滚, - 堆內(nèi)存總共是
16G
佛吓, - 觸發(fā)刷寫的閾值是:
6.08GB
觸發(fā)阻塞的閾值是:6.4GB
-
- 1)
Compact合并機(jī)制
- 在
hbase
中主要存在兩種類型的compact
合并
minor compact ?合并
- 在將
Store
中多個(gè)HFile(StoreFile)
合并為?個(gè)HFile
- 這個(gè)過程中,刪除和更新的數(shù)據(jù)僅僅只是做了標(biāo)記垂攘,并沒有物理移除维雇,這種合并的觸發(fā)頻率很?。
-
minor compact
?件選擇標(biāo)準(zhǔn)由以下?個(gè)參數(shù)共同決定
<!--待合并?件數(shù)據(jù)必須?于等于下?這個(gè)值-->
<property>
<name>hbase.hstore.compaction.min</name>
<value>3</value>
</property>
<!--待合并?件數(shù)據(jù)必須?于等于下?這個(gè)值-->
<property>
<name>hbase.hstore.compaction.max</name>
<value>10</value>
</property>
<!--默認(rèn)值為128m,
表示?件???于該值的store file ?定會加?到minor compaction的store file中
-->
<property>
<name>hbase.hstore.compaction.min.size</name>
<value>134217728</value>
</property>
<!--默認(rèn)值為LONG.MAX_VALUE晒他,
表示?件???于該值的store file ?定會被minor compaction排除-->
<property>
<name>hbase.hstore.compaction.max.size</name>
<value>9223372036854775807</value>
</property>
- 觸發(fā)條件
-
memstore flush
- 在進(jìn)?
memstore flush
前后都會進(jìn)?判斷是否觸發(fā)compact
- 在進(jìn)?
- 定期檢查線程
- 周期性檢查是否需要進(jìn)?
compaction
操作 - 由參數(shù):
hbase.server.thread.wakefrequency
決定吱型,默認(rèn)值是10000 millseconds
- 周期性檢查是否需要進(jìn)?
-
major compact ?合并
- 合并
Store
中所有的HFile
為?個(gè)HFile
- 這個(gè)過程有刪除標(biāo)記的數(shù)據(jù)會被真正移除,同時(shí)超過單元格
maxVersion
的版本記錄也會被刪除陨仅。 - 合并頻率?較低津滞,默認(rèn)
7
天執(zhí)??次,并且性能消耗?常?灼伤,建議?產(chǎn)關(guān)閉(設(shè)置為0
)触徐,在應(yīng)?空閑時(shí)間?動(dòng)觸發(fā)。 - ?般可以是?動(dòng)控制進(jìn)?合并狐赡,防?出現(xiàn)在業(yè)務(wù)?峰期撞鹉。
- 這個(gè)過程有刪除標(biāo)記的數(shù)據(jù)會被真正移除,同時(shí)超過單元格
major compaction觸發(fā)時(shí)間條件
<!--默認(rèn)值為7天進(jìn)??次?合并,-->
<property>
<name>hbase.hregion.majorcompaction</name>
<value>604800000</value>
</property>
?動(dòng)觸發(fā)
##使?major_compact命令
major_compact tableName
Region 拆分機(jī)制
-
Region
中存儲的是?量的rowkey
數(shù)據(jù) ,當(dāng)Region
中的數(shù)據(jù)條數(shù)過多的時(shí)候勤众,直接影響查詢效率 - 當(dāng)
Region
過?的時(shí)候绵估,HBase
會拆分Region
, 這也是Hbase
的?個(gè)優(yōu)點(diǎn)
拆分策略
ConstantSizeRegionSplitPolicy
- 0.94版本前默認(rèn)切分策略
- 當(dāng)
region
???于某個(gè)閾值(hbase.hregion.max.filesize=10G
)之后就會觸發(fā)切分 - ?個(gè)
region
等分為2個(gè)region
。 - 弊端:切分策略對于?表和?表沒有明顯的區(qū)分亲族。
- 閾值(
hbase.hregion.max.filesize
)設(shè)置較?對?表?較友好崔慧,但是?表就有可能不會觸發(fā)分裂拂蝎,極端情況下可能就1個(gè),這對業(yè)務(wù)來說并不是什么好事惶室。 - 如果設(shè)置較?則對?表友好温自,但?個(gè)?表就會在整個(gè)集群產(chǎn)??量的
region
,這對于集群的管理皇钞、資源使?悼泌、failover
來說都不是?件好事。
- 閾值(
IncreasingToUpperBoundRegionSplitPolicy
- 0.94版本~2.0版本前默認(rèn)切分策略
- ?個(gè)
region
???于設(shè)置閾值就會觸發(fā)切分夹界。 - 閾值在?定條件下不斷調(diào)整馆里,調(diào)整規(guī)則和
region
所屬表在當(dāng)前regionserver
上的region
個(gè)數(shù)有關(guān)系. -
region split
的計(jì)算公式是:
regioncount^3 * 128M * 2,當(dāng)region達(dá)到該size的時(shí)候進(jìn)?split
例:
第?次split:1^3 * 256 = 256MB
第?次split:2^3 * 256 = 2048MB
第三次split:3^3 * 256 = 6912MB
第四次split:4^3 * 256 = 16384MB > 10GB可柿,因此取較?的值10GB
SteppingSplitPolicy
- 2.0默認(rèn)版本
- 依然和待分裂
region
所屬表在當(dāng)前regionserver
上的region
個(gè)數(shù)有關(guān)系- 如果
region
個(gè)數(shù)等于1鸠踪,切分閾值為flush size * 2 - 否則為
MaxRegionFileSize
- 如果
KeyPrefixRegionSplitPolicy
- 根據(jù)
rowKey
的前綴對數(shù)據(jù)進(jìn)?分組 - 這?是指定
rowKey
的前多少位作為前綴
?如
rowKey
都是16位的,指定前5位是前綴复斥,那么前5位相同的rowKey
在進(jìn)?region split
的時(shí)候會分到相同的region
中
DelimitedKeyPrefixRegionSplitPolicy
- 保證相同前綴的數(shù)據(jù)在同?個(gè)
region
中
例如rowKey的格式為:
userid_eventtype_eventid
指定的delimiter
為_
营密,則split的的時(shí)候會確保userid
相同的數(shù)據(jù)在同?個(gè)region中。
DisabledRegionSplitPolicy
- 不啟??動(dòng)拆分, 需要指定?動(dòng)拆分
RegionSplitPolicy的應(yīng)?
-
Region
拆分策略可以全局統(tǒng)?配置目锭,也可以為單獨(dú)的表指定拆分策略评汰。- 通過
hbase-site.xml
全局統(tǒng)?配置(對hbase
所有表?效)
<property> <name>hbase.regionserver.region.split.policy</name> <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value> </property>
- 通過
Java API
為單獨(dú)的表指定Region
拆分策略
HTableDescriptor tableDesc = new HTableDescriptor("test1"); tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, IncreasingToUpperBoundRegionSplitPolicy.class.getName()); tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf1"))); admin.createTable(tableDesc);
- 通過
HBase Shell
為單個(gè)表指定Region
拆分策略
create 'test2', {METADATA => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy'}},{NAME => 'cf1'}
- 通過
HBase表的預(yù)分區(qū)(region)
為何要預(yù)分區(qū)?
- 當(dāng)?個(gè)
table
剛被創(chuàng)建的時(shí)候痢虹,Hbase
默認(rèn)的分配?個(gè)region
給table
- 這個(gè)時(shí)候被去,所有的讀寫請求都會訪問到同?個(gè)
regionServer
的同?個(gè)region
中 - 這時(shí),不到負(fù)載均衡的效果了奖唯,集群中的其他
regionServer
就可能會處于?較空閑的狀態(tài)编振。
- 這個(gè)時(shí)候被去,所有的讀寫請求都會訪問到同?個(gè)
- 解決這個(gè)問題可以?
pre-splitting
,在創(chuàng)建table
的時(shí)候就配置好臭埋,?成多個(gè)
region
- 增加數(shù)據(jù)讀寫效率
- 負(fù)載均衡,防?數(shù)據(jù)傾斜
- ?便集群容災(zāi)調(diào)度region
- 每?個(gè)
region
維護(hù)著startRow
與endRowKey
臀玄,如果加?的數(shù)據(jù)符合某個(gè)region
維護(hù)的rowKey
范圍瓢阴,則該數(shù)據(jù)交給這個(gè)region
維
- 每?個(gè)
?動(dòng)指定預(yù)分區(qū)
create 'person','info1','info2',SPLITS => ['1000','2000','3000']
- 也可以把分區(qū)規(guī)則創(chuàng)建于?件中
vi split.txt
aa
bb
cc
dd
# 執(zhí)行
create 'student','info',SPLITS_FILE => '/root/hbase/split.txt'
Region 合并
HBase API應(yīng)?和優(yōu)化
HBase API客戶端操作
HBase 協(xié)處理器
問題背景
- 訪問
HBase
的?式是使?scan
或get
獲取數(shù)據(jù),在獲取到的數(shù)據(jù)上進(jìn)?業(yè)務(wù)運(yùn)算 - 但是在數(shù)據(jù)量?常?的時(shí)候健无,?如?個(gè)有上億?及?萬個(gè)列的數(shù)據(jù)集荣恐,再按常?的
?式移動(dòng)獲取數(shù)據(jù)就會遇到性能問題。 - 客戶端也需要有強(qiáng)?的計(jì)算能?以及?夠的內(nèi)存來處理這么多的數(shù)據(jù)。
- 此時(shí)就可以考慮使?
Coprocessor
(協(xié)處理器)- 將業(yè)務(wù)運(yùn)算代碼封裝到
Coprocessor
中并在RegionServer
上運(yùn)?叠穆,即在數(shù)據(jù)實(shí)際存儲位置執(zhí)?少漆,最后將運(yùn)算結(jié)果返回到客戶端。 - 利?協(xié)處理器硼被,?戶可以編寫運(yùn)?在
HBase Server
端的代碼
- 將業(yè)務(wù)運(yùn)算代碼封裝到
Hbase Coprocessor類似概念
- 觸發(fā)器和存儲過程:
- ?個(gè)
Observer Coprocessor
有些類似于關(guān)系型數(shù)據(jù)庫中的觸發(fā)器示损,通過它我們可以在?些事件(如Get
或是`Scan)發(fā)?前后執(zhí)?特定的代碼。 -
Endpoint Coprocessor
則類似于關(guān)系型數(shù)據(jù)庫中的存儲過程嚷硫,因?yàn)樗试S我們在RegionServer
上直接對它存儲的數(shù)據(jù)進(jìn)?運(yùn)算检访,??是在客戶端完成運(yùn)算。
- ?個(gè)
-
MapReduce
:-
MapReduce
的原則就是將運(yùn)算移動(dòng)到數(shù)據(jù)所處的節(jié)點(diǎn)仔掸。Coprocessor
也是按照相同的原則去?作的脆贵。
-
-
AOP
:- 如果熟悉
AOP
的概念的話,可以將Coprocessor
的執(zhí)?過程視為在傳遞請求的過程中對請求進(jìn)?了攔截起暮,并執(zhí)?了?些?定義代碼卖氨。
- 如果熟悉
Observer 案例
通過協(xié)處理器Observer實(shí)現(xiàn)Hbase當(dāng)中t1表插?數(shù)據(jù),指定的另?張表t2也需要插?相對應(yīng)的數(shù)據(jù)
create 't1','info'
create 't2','info'
- 思路:通過
Observer
協(xié)處理器捕捉到t1
插?數(shù)據(jù)時(shí),將數(shù)據(jù)復(fù)制?份并保存到t2
表中 - 添加依賴
- 編寫
Observer
public class MyProcessor extends BaseRegionObserver {
@Override
public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException {
//把自己需要執(zhí)行的邏輯定義在此處负懦,向t2表插入數(shù)據(jù)筒捺,數(shù)據(jù)具體是什么內(nèi)容與Put一樣
//獲取t2表table對象
final HTable t2 = (HTable) e.getEnvironment().getTable(TableName.valueOf("t2"));
//解析t1表的插入對象put
final Cell cell = put.get(Bytes.toBytes("info"), Bytes.toBytes("name")).get(0);
//table對象.put
final Put put1 = new Put(put.getRow());
put1.add(cell);
t2.put(put1); //執(zhí)行向t2表插入數(shù)據(jù)
t2.close();
}
}
- 打成
jar
包,上傳HDFS
cd /opt/sw
mv original-hbaseStudy-1.0-SNAPSHOT.jar processor.jar
hdfs dfs -mkdir -p /processor
hdfs dfs -put processor.jar /processor
- 掛載協(xié)處理器
describe 't1'
alter 't1',METHOD =>
'table_att','Coprocessor'=>'hdfs://os1:9000/processor/processor.jar|com.test.hbase.processor.MyProcessor|1001|'