Hbase學習筆記

一、簡介

Hbase:全名Hadoop DataBase,是一種開源的薪前,可伸縮的,嚴格一致性(并非最終一致性)的分布式存儲系統(tǒng)图柏。具有最理想化的寫和極好的讀性能序六。它支持可插拔的壓縮算法(用戶可以根據(jù)其列族中的數(shù)據(jù)特性合理選擇其壓縮算法),充分利用了磁盤空間蚤吹。

類似于Google的BigTable例诀,其分布式計算采用MapReduce随抠,通過MapReduce完成大塊的數(shù)據(jù)加載和全表掃描操作等。文件存儲系統(tǒng)采用HDFS繁涂,通過Zookeeper來完成狀態(tài)管理協(xié)同服務(wù)拱她。不過BigTable只支持一級索引,Hbase不僅支持一級索引扔罪,還支持二級索引秉沼。

需要指出的是:很多人都認為Hbase是面向列的數(shù)據(jù)庫,其實不是矿酵。從典型的關(guān)系型數(shù)據(jù)庫概念上來說Hbase并不是面向列的數(shù)據(jù)庫唬复。但是充分利用了磁盤上列式存儲格式的特性。Hbase跟傳統(tǒng)的Columnar databases還是有區(qū)別的全肮。Columnar databases擅長的是實時數(shù)據(jù)的分析訪問敞咧,而Hbase在基于key的單值訪問和范圍掃描上比較突出。不過我們經(jīng)常談及到的Hbase是面向列的存儲系統(tǒng)辜腺,其實是因為Hbase是以列族的模式進行存儲的休建。


二、Hbase基本結(jié)構(gòu)

1)架構(gòu)圖


從上圖中可以看出评疗,Hbase內(nèi)部的核心結(jié)構(gòu)由以下幾大塊組成:HMaster测砂,HRegionServer,HLog百匆,HRegion等砌些。而Hbase依賴的外部系統(tǒng)有Zookeeper,HDFS等胧华。

1)HMaster(類似于HDFS中NameNode,MapReduce中的JobTrackers)是用來管理HRegionServer的寄症。它負責監(jiān)控集群中HRegionServer的狀態(tài)信息變化。主要功能點如下:

1矩动、管理HRegionServer的負載均衡有巧,調(diào)整Region分布。這個通過HMaster的后臺線程LoadBalancer來完成悲没。LoadBalancer會定期將Region進行移動篮迎,以使各個HRegionServer達到Load均衡。

2示姿、在Region Split后甜橱,負載新Region的分配。

3栈戳、HRegionServer的FailOver處理岂傲,當某一個HRegionServer出問題后,HMaster負責將其Region進行轉(zhuǎn)移子檀。

4镊掖、CatalogJanitor乃戈。 CatalogJanitor會定期檢查和清理.Meta.表。

在一個HBase集群中會存在多個HMaster亩进,不過zookeeper的Master Election機制會保證只有一個HMaster在運行症虑。當運行的HMaster出問題后,其他的HMaster就會立刻補上归薛。

2)從圖中可以看出谍憔,Hbase客戶端是只與zookeeper和HRegion Server打交道。并不會跟HMaster交互主籍。所以如果HMaster出問題了习贫,Hbase集群在短時間內(nèi)還是可以對外提供可靠服務(wù)的。但是崇猫,因為HMaster掌控了HRegionServer的一些功能沈条,如:HRegion Server的FailOver操作,Region切分等诅炉,HMaster長時間不可用還是會出問題的。

3)上面所提及的Catelog表有兩個:-Root-和.Meta.表屋厘。-Root-表中存儲了.Meta.表的位置涕烧。即.Meta.表的Region key。.Meta.表存儲了所有Region的位置及每個Region所包含的RowKey的范圍汗洒。-Root-表的存儲位置記錄在zookeeper中议纯,.Meta.表的存儲位置記錄在-Root-表中。

4)當客戶端發(fā)起一個查詢數(shù)據(jù)的請求后溢谤,首先瞻凤,客戶端會先連接上zookeeper集群,獲取-Root-表的存放在哪一個HRegionServer上世杀。接著找到對應(yīng)的HRegionServer后阀参,就能夠獲取到-Root-表中對應(yīng)的.Meta.表的位置。最后客戶端根據(jù).Meta.表存儲的HRegion的位置到相應(yīng)的HRegionServer中取對應(yīng)的Hregion中的數(shù)據(jù)信息瞻坝。經(jīng)過一次查詢后蛛壳,訪問Catalog表的過程就會被緩存起來,下次客戶端就可以直接到相應(yīng)的HRegion上獲取數(shù)據(jù)所刀。

5)Hbase已經(jīng)無縫集成了HDFS衙荐,其中所有的數(shù)據(jù)最終都會通過DFS客戶端API持久化到HDFS中。

6)一個Hbase集群中有許多個HRegionServer(類似于HDFS中的DataNode浮创,MapReduce中的TaskTrackers)忧吟,由一個HMaster進行管理。每個HRegionServer擁有一個WAL(write Ahead Log斩披,日志文件溜族,用作數(shù)據(jù)恢復)和多個HRegion(可以簡單認為是用來存儲一個表中的某些行)讹俊。一個HRegion擁有多個Store(存儲一個ColumnFamily)。一個Store又由一個MemStore(持有對該Store的所有修改于內(nèi)存中)和0至多個StoreFiles(HFile斩祭,數(shù)據(jù)存儲的地方)組成劣像。詳細圖如下:



2)基本元素

1、Row Key

行標示摧玫,類似于傳統(tǒng)數(shù)據(jù)庫表中的行號耳奕。Rowkeys具有不變性。除非該行別刪除或者被重新插入了新的數(shù)據(jù)诬像。Hbase中支持基于RowKey的單行查詢和范圍掃描屋群。在Hbase的Auto-Sharding中,也是基于RowKey進行自動切分的坏挠。


2芍躏、Column Family

在Hbase中最基本的單元就是列。而列族是由一個或者列組成降狠。一般在使用時对竣,盡量將經(jīng)常訪問的列作為一個列族。因為Hbase是面向列族的存儲榜配,也就是說一個列族中的所有列是存儲在一起的否纬。即上圖中的一個Store存儲一個列族。


不過有一點需要注意的是在一個表中列族被限定不能超過十個蛋褥。

3临燃、TimeStamp

Hbase中支持時間戳的概念。即允許Cell存儲多個版本值烙心。版本之間通過時間戳來區(qū)分膜廊。也就是說可能存在某一列的某一行有多個值。一般默認是3淫茵,且最近版本在最上面爪瓜。Hbase中有一個TTL(Time To Live)的配置,這個是基于列族維度的痘昌。一旦過期钥勋,列族就會自動刪除所有行。


4辆苔、HRegion Server

HRegionServer是負責服務(wù)和管理Region的算灸。類似于我們所說的主從服務(wù)器,HMaster就是主服務(wù)器驻啤,HRegionServer就是從服務(wù)器菲驴。當用戶執(zhí)行CRUD等操作時,都需要通過HRegionServer定位到相應(yīng)的Region上進行操作骑冗。


5赊瞬、WAL

WAL全名是Write Ahead Log先煎,類似于mysql中的Binary Log,WAL記錄了該HRegionServer上所有數(shù)據(jù)的變更巧涧。一旦這個HRegionServer死翹翹了薯蝎,導致數(shù)據(jù)丟失后,WAL就是救命稻草谤绳≌季猓可以通過WAL進行數(shù)據(jù)恢復。所以在平時WAL是沒什么用的缩筛,只是為了不可預知的災難做準備消略。當然,WAL起作用的前提是保證變更日志已經(jīng)記錄到了WAL中瞎抛。


WAL的實現(xiàn)類是HLog艺演。因為在一個HRegionServer中持有一個WAL,所以對于該HRegionServer上的所有Region來說桐臊,WAL是全局胎撤,共享的。當HRegion實例創(chuàng)建的時候断凶,在HRegionServer實例中的HLog就會被當做HRegion構(gòu)造函數(shù)的參數(shù)傳遞到HRegion哩照。當HRegion接收到一個變更操作時,HRegion就能直接通過HLog將變更日志追加(append()方法)到共享WAL中懒浮。當然基于性能考慮,HBase還提供了一個setWriteToWAL(false)方法识藤。一旦用戶調(diào)用了此方法砚著。變更日志就不會追加到WAL中。默認是需要寫入的痴昧,除非用戶自己保證數(shù)據(jù)不會丟失稽穆。

HLog還有一個重要的特性就是:跟蹤變更。在HLog類中有一個原子類型的變量赶撰,HLog會讀取StoreFiles中最大的sequence number(HLog中每一條變更日志都有一個number號舌镶,因為對于一個HRegionServer中的所有HRegion是共享HLog的,所以會將變更日志順序?qū)懭隬AL豪娜,StoreFiles中也持有該number)餐胀,并存放到變量中。這樣HLog就知道已經(jīng)已經(jīng)存儲到哪一個位置了瘤载。

WAL還有兩個比較重要的類否灾,一個是LogSyncer,另一個是LogRoller鸣奔。

1墨技、在創(chuàng)建表時惩阶,有一個參數(shù)設(shè)置:Deferred Log Flush,默認是false扣汪,表示log一旦更新就立即同步到filesystem断楷。如果設(shè)置為true,則HRegionServer會緩存那些變更崭别,并由后臺任務(wù)LogSyncer定時將變更信息同步到filesystem冬筒。

2、WAL是有容量限制的紊遵,LogRoller是一個后臺線程账千,會定時滾動logfile,用戶可以設(shè)定這個間隔時間(hbase.regionserver.logroll.period,默認是一小時)暗膜。當檢查到某個logfile文件中的所有sequence number均小于那個最大的sequence number時匀奏,就會將此logfile移到.oldLog目錄。

如下是WAL的文件結(jié)構(gòu)学搜,目前WAL采用的是Hadoop的SequenceFile娃善,其存儲記錄格式是key/value鍵值對的形式。其中Key保存了HLogkey的實例瑞佩,HLogKey包含數(shù)據(jù)所屬的表名及RegionName聚磺,timeStamp,sequenceNumber等信息炬丸。Value保存了WALEdit實例瘫寝,WALEdit包含客戶端每一次發(fā)來的變更信息。


6稠炬、Region

在Hbase中實現(xiàn)可擴展性和負載均衡的基本單元是Region焕阿。Region存儲著連續(xù)的RowKey的數(shù)據(jù)。剛開始時首启,一個表就只有一個Region暮屡,當一個表隨著數(shù)據(jù)增多而不斷變大時,如果達到指定的大小后就會根據(jù)Rowkey自動一分為二成兩個Region毅桃。每個Region中保存著一個【startkey,endkey】褒纲。隨著表的繼續(xù)增大,每個Region又會自動split成更多的Region钥飞。每個Region只會由一個HRegionServer服務(wù)莺掠。這就是所謂的Hbase的AutoSharding特性。當然代承,Region除了會spilt外汁蝶,也可能進行合并以減少Region數(shù)目(這就是Hbase的compaction特性,后面會談到)。


既然Region是表的基本元素掖棉。那么墓律,用戶如何獲取到對應(yīng)的Region呢?幔亥?前面已經(jīng)提及—通過Catalog表耻讽。

7、Store

Store是核心存儲單元帕棉。在一個HRegion中可能存在多個ColumnFamily针肥,那么Store中被指定只能存儲一個ColumnFamily。不同的ColumnFamily存儲在不同的Store中(所以在創(chuàng)建ColumnFamily時香伴,盡量將經(jīng)常需要一起訪問的列放到一個ColumnFamily中慰枕,這樣可以減少訪問Store的數(shù)目)。一個Store由一個MemStore和0至多個StoreFile組成即纲。


8具帮、MemStore

Hbase在將數(shù)據(jù)寫入StoreFile之前,會先寫入MemStore低斋。MemStore是一個有序的內(nèi)存緩沖器蜂厅。當MemStore中的數(shù)據(jù)量達到設(shè)定的大小時(Flush Size),HRegionServer就會執(zhí)行Flush操作膊畴,將MemStore中的數(shù)據(jù)flush到StoreFile中掘猿。


當HRegionServer正在將MemStore中的數(shù)據(jù)Flush到StoreFile時,MemStore還可以對外進行讀寫服務(wù)唇跨。這個是通過MemStore的滾動機制實現(xiàn)的稠通。通過滾動MemStore,新的空的塊就可以接收變更,而老的滿的塊就會執(zhí)行flush操作买猖。

9采记、StoreFile/HFile

StoreFile是HFile的實現(xiàn),對HFile做了一層包裝政勃。HFile是數(shù)據(jù)真正存儲的地方。HFile是基于BigTable的SSTable File和Hadoop的TFile兼砖。HFile是以keyvalue的格式存儲數(shù)據(jù)的奸远。(Hbase之前使用過Hadoop得MapFile,因為其性能上相當糟糕而放棄楷掉。)下圖是HFile中版本1的格式俯树,版本2稍有改變(詳見Hbase wiki):


從上圖中看出豺鼻,HFile是由多個數(shù)據(jù)塊組成。大部分數(shù)據(jù)塊是不定長的薛窥,唯一固定長度的只有兩個數(shù)據(jù)塊:File Info和Trailer。DataIndex和MetaIndex分別記錄了Data塊和Meta塊的起始位置。每個data塊由一些kevalue鍵值對和Magic header組成诅迷。Data塊的大小可以再創(chuàng)建表時通過HColumnDescriptor設(shè)定佩番。Magic記錄了一串隨機的數(shù)字,防治數(shù)據(jù)丟失和損壞罢杉。

如果用戶想繞過Hbase直接訪問HFile時趟畏,比如檢查HFile的健康狀態(tài),dump HFile的內(nèi)容滩租,可以通過HFile.main()方法完成赋秀。

如下圖是KeyValue的格式:

KeyValue是一個數(shù)組,對byte數(shù)組做了一層包裝律想。Key Length和Value Length都是固定長度的數(shù)值猎莲。Key包含的內(nèi)容有行RowKey的長度及值,列族的長度及值,列技即,時間戳著洼,key類型(Put, Delete, DeleteColumn, DeleteFamily)。

從上圖可以看出姥份,每一個keyValue只包含一列郭脂,即使對于同一行的不同列數(shù)據(jù),會創(chuàng)建多個KeyValue實例澈歉。此外KeyValue不能被Split展鸡,即使此KeyValue值超過Block的大小,比如:

Block大小為16Kb埃难,而KeyValue值有8Mb,那么KeyValue會通過相連的多個Block進行存儲莹弊。

3)總結(jié)

以上對Hbase的基本元素做了一個大體的介紹。下圖是Hbase的存儲結(jié)構(gòu)圖涡尘。記錄了客戶端發(fā)起變更或者新增操作時忍弛,Hbase內(nèi)部的存儲流程。


下面來分析下整個存儲流程:

1)當客戶端提交變更操作(如插入put考抄,刪除delete细疚,計數(shù)新增incr),首先客戶端會連接上Zookeeper找到-Root-表的存儲位置川梅,然后根據(jù)-Root-表所提供的.Meta.表的位置找到對應(yīng)的Region所在的HRegionServer疯兼。數(shù)據(jù)變更信息會先通過HRegionServer寫入一個commit log,也就是WAL贫途。當寫入WAL成功后吧彪,數(shù)據(jù)變更信息會存到MemStore中。當MemStore達到設(shè)定的maximum value(hbase.hregion.memstore.flush.size丢早,默認64MB)后姨裸,MemStore就會開始進行Flush操作秧倾,將其內(nèi)容持久化到一個新的HFile中。在Flush操作過程中傀缩,MemStore通過滾動機制繼續(xù)對用戶提供讀寫服務(wù)那先。隨著Flush操作的不斷進行,HFile文件越來越多扑毡。 當HFile文件超過設(shè)定的數(shù)量后胃榕,Hbase的HouseKeeping機制就會通過Compaction特性將HFile小文件合并成一個更大的HFile文件。在Compaction的過程中瞄摊,會進行版本的合并以及數(shù)據(jù)的刪除勋又。由于storeFiles是不變的,用戶執(zhí)行刪除操作時换帜,并不能簡單地通過刪除其鍵值對來刪除數(shù)據(jù)內(nèi)容楔壤。Hbase提供了一個delete marker機制(也稱為tombstone marker),會告訴HRegionServer那個指定的key已經(jīng)被刪除了惯驼。這樣其它用戶檢索這個key的內(nèi)容時蹲嚣,因為已經(jīng)被標記為刪除,所以也不會檢索出來祟牲。在進行Compaction操作中就會丟棄這些已經(jīng)打標的記錄隙畜。經(jīng)過多次Compaction后,HFile文件會越來越大说贝,當達到設(shè)定的值時议惰,會觸發(fā)Split操作。將當前的Region根據(jù)RowKey對等切分成兩個子Region乡恕,當期的那個Region被廢棄言询,兩個子Region會被分配到其他HRegionServer上。所以剛開始時一個表只有一個Region傲宜,隨著不斷的split运杭,會產(chǎn)生越來越多的Region,通過HMaster

的LoadBalancer調(diào)整函卒,Region會均勻遍布到所有的HRegionServer中辆憔。

2)當HLog滿時,HRegionServer就會啟動LogRoller,通過執(zhí)行rollWriter方法將那些所有sequence number均小于最大的那個sequence number的logfile移動到.oldLog目錄中等待被刪除报嵌。如果用戶設(shè)置了Deferred Log Flush為true躁愿,HRegionServer會緩存有關(guān)此表的所有變更,并通過LogSyncer調(diào)用sync()方法定時將變更信息同步到filesystem沪蓬。默認為false的話,一旦有變更就會立刻同步到filesystem来候。

3)在一個HRegionServer中只有一個WAL跷叉,所有Region共享此WAL。HLog會根據(jù)Region提交變更信息的先后順序依次順序?qū)懭隬AL中。如果用戶設(shè)置了setWriteToWAL(false)方法云挟,則有關(guān)此表的所有Region變更日志都不會寫入WAL中梆砸。這也是上圖中Region將變更日志寫入WAL的那個垂直向下的箭頭為什么是虛線的原因。


三园欣、Hbase基本操作

Hbase中主要的客戶端接口是HTable類帖世,HTable提供了對數(shù)據(jù)的所有CRUD操作。需要注意的是由于創(chuàng)建HTabe實例比較耗時沸枯, 所以在實際使用中最好創(chuàng)建單例模式的HTable實例日矫,不過如果需要多個HTable實例的話,可以考慮使用HBase的HTablePool特性(下面后講到)绑榴。Hbase不提供直接的update操作哪轿。由于Hbase中數(shù)據(jù)存儲有版本支持。所以如果需要update一條記錄翔怎,一般是通過put操作窃诉,這樣歷史版本會在Compaction操作中被合并掉,這樣就間接實現(xiàn)了更新赤套。(在MemStore中有一個變量MemstoreTS飘痛,該變量是隨put操作而遞增的。比如首先往列A容握,timeStamp為T1上put一條數(shù)據(jù)data1宣脉,假設(shè)此時MemstoreTS為1;之后如果想更新這條數(shù)據(jù)唯沮,只需要往列A脖旱,timeStamp為T1上put一條數(shù)據(jù)data2,此時MemstoreTS為2介蛉,Hbase會自動會將MemstoreTS大的排在前面萌庆。MemstoreTS小的在Compaction過程中就被過濾掉了。)


1)put操作

Put操作就是講數(shù)據(jù)插入到Hbase中币旧。有兩種模式践险,一種是對單行的操作(single put);還有一種是對多行的操作(List of put)吹菱。針對單行操作的方式如下:


1巍虫、創(chuàng)建put實例有如下構(gòu)造函數(shù):需要用戶指定某行,用戶也可以設(shè)定時間戳作為版本標示鳍刷。此外占遥,用戶還可以加入自定義的行鎖,以防其它用戶或者其它線程在變更期間訪問此行的數(shù)據(jù)输瓜。

Put(byte[] row)

Put(byte[] row, RowLock rowLock)

Put(byte[] row, long ts)

Put(byte[] row, long ts, RowLock rowLock)

在Hbase中參數(shù)的傳遞大多是byte數(shù)組類型瓦胎。Hbase提供了許多靜態(tài)方法將java類型轉(zhuǎn)換成byte數(shù)組類型芬萍。如下:

static byte[] toBytes(ByteBuffer bb)

static byte[] toBytes(String s)

static byte[] toBytes(boolean b)

static byte[] toBytes(long val)

static byte[] toBytes(float f)

static byte[] toBytes(int val)

2、一旦創(chuàng)建好put實例后搔啊,就可以通過put類提供的方法插入數(shù)據(jù)了柬祠。插入數(shù)據(jù)的操作需要指定列族,所在列等负芋。如下:

Put add(byte[] family, byte[] qualifier, byte[] value)

Put add(byte[] family, byte[] qualifier, long ts, byte[] value)

Put add(KeyValue kv) throws IOException

3漫蛔、put組裝完成后,就可以通過HTable提供的void put(Put put)throws IOException完成數(shù)據(jù)的插入操作旧蛾。

如果需要對多行進行put操作莽龟,可以組裝一系列的put實例,然后調(diào)用HTable提供的void put(List?puts) throws IOException來完成多行插入操作蚜点。不過需要指出的是:如果在這多個Put實例中存在一個put實例有誤(比如:往一個不存在的列族中插入數(shù)據(jù))轧房,那么該put實例會報錯,但是不影響其他的put實例绍绘。跟后面的get操作有點區(qū)別奶镶。

此外,Hbase還提供了一個原子型的put操作:Atomic compare-and-set?陪拘,方法如下:boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,byte[] value, Put put) throws IOException厂镇。只有校驗成功后才會完成put操作.

需要注意的是,因為每次的put操作相當于一個RPC左刽,將數(shù)據(jù)從客戶端傳遞到服務(wù)端并返回捺信。如果你的應(yīng)用中RPC非常頻繁,比如一秒內(nèi)成千上萬次欠痴,可能會有隱患迄靠。解決的辦法就是盡量降低RPC次數(shù),Hbase提供了一個嵌入的客戶端寫緩存器(Client-side Write Buffer)喇辽。它會緩存所有的put操作掌挚,然后再一次性提交。默認情況下Client-side Write Buffer是沒有激活的菩咨。用戶可以在創(chuàng)建HTable的時候通過調(diào)用table.setAutoFlush(false)方法來激活它吠式。并且可以通過isAutoFlush()來檢查是否已經(jīng)激活。默認是true抽米,表示一旦有put操作會立即發(fā)送到服務(wù)器端特占。當你想將所有put操作提交到服務(wù)器端時,可以調(diào)用flushCommits()操作云茸。它會將緩存器中所有變更提交到遠程服務(wù)器是目。Client-side Write Buffer還會自動對buffer中的所有變更進行分組,同一個HRegionServer的分到同一個組标捺。這樣每個HRegionServer通過一個RPC傳送.


2)get操作

Get操作就是從服務(wù)器端獲取數(shù)據(jù)懊纳。跟put操作一樣网持,get操作也分為兩種模式,一種是對單行的get操作(single get)长踊,另一種是對多行進行檢索操作(List of gets)。


1萍倡、HTable提供的get方法如下:其返回值為Result類身弊,該類包含了列族,列列敲,keyvalue阱佛,

RowKey等信息。該類提供的豐富的方法供用戶獲取返回的各種信息戴而。

Result get(Get get) throws IOException

2凑术、Get類的構(gòu)造函數(shù)如下,需要用戶傳入指定的行及行鎖等參數(shù)所意。

Get(byte[] row)

Get(byte[] row, RowLock rowLock)

3淮逊、 一旦創(chuàng)建的get實例后,用戶可以調(diào)用Get類提供的如下方法來框定你需要檢索的數(shù)據(jù)扶踊。如下:用戶可以指定列族泄鹏,列,時間戳秧耗,最大版本號等备籽。如果不設(shè)置版本號,默認是1分井,表示最大的版本车猬。

Get addFamily(byte[] family)

Get addColumn(byte[] family, byte[] qualifier)

Get setTimeRange(long minStamp, long maxStamp) throws IOException

Get setTimeStamp(long timestamp)

Get setMaxVersions()

Get setMaxVersions(int maxVersions) throws IOException

跟List of put 類似,對于多行的檢索操作尺锚,HTable也提供了類似的如下方法:用戶只要創(chuàng)建多個get實例珠闰,就可以通過如下方法獲取需要的數(shù)據(jù)。不過需要注意的是:跟List of put不同的是缩麸,如果Get實例列表中只要存在一個Get實例有誤(比如get一個不存在的列族的值)铸磅,那么整體就會拋出一個異常.

Result[] get(List?gets) throws IOException

3)delete操作

Delete操作也類似,HTable提供了兩種方法杭朱,支持單個delete實例和多個delete實例的操作阅仔。如下:


void delete(Delete delete) throws IOException

void delete(List?deletes) throws IOException

1、相應(yīng)的delete實例構(gòu)造函數(shù)有:

Delete(byte[] row)

Delete(byte[] row, long timestamp, RowLock rowLock)

2弧械、如果你需要添加一些限制條件八酒,可以使用delete類提供的相關(guān)方法,支持指定列族刃唐,列羞迷,時間戳等界轩。如果你指定了一個時間戳,則表示小于等于該時間戳的時間將被刪除衔瓮。如果指定了列和行號浊猾,但沒有指定時間戳,則默認會刪掉版本號最大的那個值热鞍。

Delete deleteFamily(byte[] family)

Delete deleteFamily(byte[] family, long timestamp)

Delete deleteColumns(byte[] family, byte[] qualifier)

Delete deleteColumns(byte[] family, byte[] qualifier, long timestamp)

Delete deleteColumn(byte[] family, byte[] qualifier)

Delete deleteColumn(byte[] family, byte[] qualifier, long timestamp)

void setTimestamp(long timestamp)

3葫慎、當使用List of delete時,如果有一個delete實例出錯薇宠,那么會拋出異常偷办。而且delete的實例列表中只會存在那個出問題的delete實例。Delete也支持原子型的Compare-and- Delete椒涯,如下:

boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,byte[] value, Delete delete) throws IOException

4)Batch操作

Hbase還支持批量操作泪喊。其實上面所談到的List of puts,gets,deletes都是基于Batch操作來的蚓再。不過List of puts,gets,deletes逐漸會被廢棄问畅。推薦使用Batch操作秩铆。HTable提供的batch操作方法如下:參數(shù)中Row類是Put寻仗,Delete林艘,Get類的父類爹凹。表示用戶可以同時傳入put,get及delete實例操作帽馋。不過在一個batch中,最好不要同時傳入針對同一行的put和delete實例。


(1) void batch(List?actions, Object[] results) throws IOException, InterruptedException

(2)? Object[] batch(List?actions) throws IOException, InterruptedException上面這兩個batch方法比較類似前标,但有比較大的區(qū)別稽犁。第一個batch方法需要用戶傳遞一個數(shù)組来屠,該數(shù)組用來填充batch操作中所有成功的操作的結(jié)果集虑椎。如果沒有指定這個數(shù)組,比如第二個方法俱笛。一旦batch操作中某一個實例出現(xiàn)問題绣檬,那么Hbase只會拋出一個異常。那些成功的操作的結(jié)果并不會返回嫂粟。而第一個方法則會將那些成功的操作的結(jié)果集返回給用戶娇未。

此外Batch操作不支持Client-side write buffer,Batch方法是同步的星虹,會直接將其包含的操作發(fā)往服務(wù)器零抬。這點需要注意!

Batch操作返回的結(jié)果可能的結(jié)果有如下幾種:

1宽涌、null:表示那個操作操作連接遠程服務(wù)器失敗平夜。

2、Empty Result:put和delete操作的返回結(jié)果卸亮,表示操作成功忽妒。

3、Result:get操作的返回結(jié)果集

4、Throwable:異常結(jié)果

5)Scan操作

Scan操作類似于傳統(tǒng)的RDBMS中的游標的概念段直。其目的跟get一樣吃溅,也是檢索服務(wù)器端數(shù)據(jù)。Hbase也提供了一個Scan類鸯檬。由于Scans類似于迭代器决侈,所以你需要通過getScanner()方法獲取。HTable提供了如下方法:如果你看了源碼就會知道喧务,后面那兩個方法其實是先創(chuàng)建一個scan實例赖歌,并加入傳入的參數(shù),然后再調(diào)用第一個方法功茴。


?ResultScanner getScanner(Scan scan) throws IOException

?ResultScanner getScanner(byte[] family) throws IOException

?ResultScanner getScanner(byte[] family, byte[] qualifier) throws IOException

1庐冯、Scan類提供了多個構(gòu)造函數(shù),如下:startRow和stopRow是左閉右開的坎穿。從構(gòu)造函數(shù)中可以看出肄扎,用戶只需要指定rowKey的范圍,或者添加相應(yīng)的過濾器赁酝,Hbase能夠自動檢索你指定的RowKey的范圍的數(shù)據(jù)。如果沒有指定startRow旭等,默認從第一行開始.

Scan()

Scan(byte[] startRow, Filter filter)

Scan(byte[] startRow)

Scan(byte[] startRow, byte[] stopRow)

2酌呆、當創(chuàng)建好Scan實例后,如果想添加更多的限制條件搔耕,可以通過調(diào)用Scan提供的如下方法:允許添加列族隙袁,列,時間戳等.

Scan addFamily(byte [] family)

Scan addColumn(byte[] family, byte[] qualifier)

Scan setTimeRange(long minStamp, long maxStamp) throws IOException

Scan setTimeStamp(long timestamp)

Scan setMaxVersions()

Scan setMaxVersions(int maxVersions)

GetScanner()方法返回的是一個ResultScanner實例弃榨。需要注意的是:如果結(jié)果集存在多行菩收,Scans并不會一次性將所有行在一個RPC里面?zhèn)魉徒o客戶端,而是基于一行一行傳送鲸睛。這樣做主要是因為多行需要耗費大量時間娜饵。

ResultScanner類包裝了Result類將其每行結(jié)果以迭代的方式輸出,使得Scan操作類似于get操作官辈。此外ResultScanner類提供了如下方法供用戶進行迭代使用:用戶可以選擇一次返回一行或者多行箱舞。不過不要認為是服務(wù)器端一次性返回多行。其實是客戶端循環(huán)調(diào)用nbRows 次next()方法而已拳亿。服務(wù)器端在一個RPC里面還是只傳送一行數(shù)據(jù)晴股。這個確實有點影響心情,但Hbase就喜歡惡心下你肺魁,不過它也提供的相應(yīng)的解決辦法:Scanner Caching电湘,默認是關(guān)閉的。

Result next() throws IOException

Result[] next(int?nbRows) throws IOException

void close()

close()方法表示釋放ResultScanner實例。因為ResultScanner實例持有了一定的資源,如果不及時釋放寂呛,可能隨著時間推移會占用很大的內(nèi)存空間怎诫。此外,close()操作最好放在finally模塊昧谊,原因你懂得刽虹!

四、Hbase特性

HBase提供了許多賞心悅目的特性呢诬。如Filters涌哲,Counters,Coprocessors尚镰,Compaction阀圾,HTablePool等。


1)Filters

當你通過Scan或者Get操作檢索數(shù)據(jù)時狗唉,會發(fā)現(xiàn)Scan和Get只支持基于RowKey初烘,列族,列分俯,時間戳等粗粒度的檢索肾筐。如果用戶想基于Key或者Value或者正則表達式等作為查詢條件進行查詢的話,Scan和Get是沒辦法做到的缸剪。而Filter就是干這事的吗铐。Hbase提供了一系列的Filters,用戶只要實現(xiàn)Filter杏节,也可以自定義Filters唬渗。


需要說明的是Hbase提供的這些Filters都是配置在客戶端,但應(yīng)用在服務(wù)器端奋渔,也叫做Predicate push-down镊逝。(比如用戶在進行Scan操作時可以傳入Filter,序列化后傳送到服務(wù)器端嫉鲸,HRegionServer就會將其反序列化撑蒜,并應(yīng)用到內(nèi)部Scanner)。這樣可以有效減少數(shù)據(jù)傳輸帶來的網(wǎng)絡(luò)開銷玄渗。

需要注意的是:Filters的通用約定是過濾掉你不需要的數(shù)據(jù)减江,而不是用來指定你需要的數(shù)據(jù)。不過凡是繼承CompareFilter過濾器的Filter捻爷,其作用剛好相反辈灼,用來指定你需要的數(shù)據(jù)。

Hbase提供的Filters有:

Ⅰ. Comparison Filters

Compartison Filters是基于比較的過濾器也榄。定義如下:

CompareFilter(CompareOp??? valueCompareOp,WritableByteArrayComparable valueComparator)

該構(gòu)造器有兩個特定的參數(shù)巡莹,一個是比較運算符司志,另一個是比較器。

A降宅、常見的比較運算符有:

LESS骂远,LESS_OR_EQUAL,EQUAL腰根,NOT_EQUAL激才,GREATER_OR_EQUAL,GREATER额嘿,NO_OP瘸恼。前面幾個運算符根據(jù)名字定義就能判斷其意思祠肥,最后一個是NO_OP时捌,表示排除任何數(shù)據(jù)。

B巩踏、常見的比較器有:其中NullComparator是判斷給定的值是否為空或者非空球拦。最后三個比較器只能搭配使用EQUAL靠闭,NOT_EQUAL比較運算符,返回0表示匹配坎炼,1表示不匹配愧膀。

BinaryComparator

BinaryPrefixComparator

NullComparator

BitComparator

RegexStringComparator

SubstringComparator

C、基于Comparison Filter的過濾器有好多種谣光,比如:

1檩淋、RowFilter

2、FamilyFilter

3抢肛、QualifierFilter

4、ValueFilter

5碳柱、DependentColumnFilter

(1)?? RowFilter過濾器顧名思義就是根據(jù)RowKey來過濾數(shù)據(jù)捡絮。所以RowFilter中的比較運算符和比較器參數(shù)都是基于RowKey來比較的。比如如下Filter表示RowKey包含-4的數(shù)據(jù)莲镣。

Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,new SubstringComparator("-4"))福稳。

(2)?FamilyFilter過濾器跟RowFilter類似,不過FamilyFilter是基于ColumnFamily的比較瑞侮。

QualifierFilter和ValueFilter過濾器也類似的圆,分別是基于列和數(shù)值的比較。

(3) DependentColumnFilter過濾器稍微復雜一點半火。它可以說是timeStamp Filter和ValueFilter的結(jié)合越妈。因為DependentColumnFilter需要指定一個參考列,然后獲取跟改參考列有相同時間戳的所有列钮糖,再在此基礎(chǔ)上獲取滿足ValueFilter的列值梅掠。構(gòu)造函數(shù)如下:用戶可以根據(jù)自己喜好省略valueFilter或者通過設(shè)置dropDependentColumn為true省略timestamp Filter酌住。不過需要注意的是:此過濾器不能跟Scan中的Batch操作結(jié)合使用。

A阎抒、DependentColumnFilter(byte[] family, byte[] qualifier)

B酪我、DependentColumnFilter(byte[] family, byte[] qualifier,boolean?dropDependentColumn)

C、DependentColumnFilter(byte[] family, byte[] qualifier,boolean dropDependentColumn, CompareOp valueCompareOp,WritableByteArrayComparable valueComparator)

Ⅱ. Dedicated Filters

專有的一些過濾器且叁,Hbase提供了許多個性化的專有過濾器都哭。常見的Dedicated Filters有:


A、SingleColumnValueFilter

B逞带、SingleColumnValueExcludeFilter

C欺矫、PrefixFilter

D、PageFilter

E掰担、KeyOnlyFilter

F汇陆、FirstKeyOnlyFilter

G、InclusiveStopFilter

H带饱、TimestampsFilter

I毡代、ColumnCountGetFilter

J、ColumnPaginationFilter

K勺疼、ColumnPrefixFilter

L教寂、RandomRowFilter

(1)?如果你想分頁獲取數(shù)據(jù),可以通過PageFilter來完成执庐。ColumnPaginationFilter跟PageFilter類似酪耕,只不過PageFilter是基于行的分頁,而ColumnPaginationFilter是基于列的分頁轨淌。如:

ColumnPaginationFilter(int limit, int offset)迂烁,表示獲取從offset列開始的連續(xù)limit列的數(shù)據(jù)。

(2)?如果只想獲取每一行的第一列的值递鹉,那么FirstKeyOnlyFilter是不錯的選擇盟步。此外,因為前面提到的Scan操作需要用戶指定一個startRow和EndRow躏结,其中這兩個參數(shù)時左閉右開區(qū)間的却盘。如果想EndRow也包含,可以通過InclusiveStopFilter來解決媳拴。如下:獲取從Row5至Row10的數(shù)據(jù)

黄橘。不過因為Hbase是字典排序的,所以得到的結(jié)果中可能會包含Row51,Row52等這些行的數(shù)據(jù)屈溉。

Filter filter = new InclusiveStopFilter(Bytes.toBytes("row-9"));

Scan scan = new Scan();

scan.setStartRow(Bytes.toBytes("row-5"));

scan.setFilter(filter);

ResultScanner scanner = table.getScanner(scan);

(3)?如果想獲取某個版本的所有數(shù)據(jù)塞关。可以通過TimestampsFilter來設(shè)置子巾,用戶需要傳入版本號描孟。如下:

TimestampsFilter(List?timestamps)

(4)?PrefixFilter和ColumnPrefixFilter都是基于前綴的過濾器驶睦,不過PrefixFilter是基于行的前綴過濾,而后者是基于列的前綴過濾匿醒。

(5) RandomRowFilter是基于隨機行的過濾器场航,用戶需要指定一個在0到1之間的隨機數(shù),構(gòu)造函數(shù)如下:如果chance大于1廉羔,則會返回所有行溉痢。如果小于0,則過濾掉所有行憋他。

RandomRowFilter(float chance)

Ⅲ. Decorating Filters

Decorating Filters稱為裝飾型的過濾器孩饼。它的作用是為其他過濾器返回的結(jié)果提供一些附加的校驗操作。常見的Decorating Filters有:


A竹挡、SkipFilter

B镀娶、WhileMatchFilter

(1)?? SkipFilter包裝了其它的過濾器,只要被包裝的過濾器返回的結(jié)果中有一行的某一列或者某個KeyValue被過濾掉了揪罕,那么SkipFilter會將該列或者KeyValue所處的整行全部過濾梯码。被包裝的過濾器必須實現(xiàn)filterKeyValue()方法。因為SkipFilter會依靠filterKeyValue()返回的結(jié)果進行附加的處理好啰。比如:

Filter filter = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL,new BinaryComparator(Bytes.toBytes("val-1")));

上面這樣一個filter轩娶,表示返回的結(jié)果中值不能等于val-1,這樣值為val-1的那個列就不會展示框往,但該行的其他列只要滿足值不等于val-1都會返回鳄抒。

不過一旦使用了SkipFilter,如:Filter filter2 = new SkipFilter(filter);只要存在某一行中的某個列的值等于val-1椰弊,那么該行的所有數(shù)據(jù)都不會返回许溅。

(2)?WhileMatchFilter跟SkipFilter類似,不過區(qū)別之處在于WhileMatchFilter一旦找到某一行中的某些列值或者KeyValue不滿足條件秉版,那么整個Scan操作就會被終止贤重。SkipFilter只是會將此行過濾,不作為返回值沐飘,但Scan操作會繼續(xù)游桩。

Ⅳ. Custom Filters

如果想實現(xiàn)自定義的Filter牲迫,可以實現(xiàn)Filter接口或者擴展FilterBase類耐朴。FilterBase類提供了基本的Filter實現(xiàn)。


如果用戶想在一次檢索數(shù)據(jù)的過程中使用多個Filter盹憎,那么可以使用FilterList特性筛峭。其構(gòu)造函數(shù)如下:

FilterList(List?rowFilters)

FilterList(Operator operator)

FilterList(Operator operator, List?rowFilters)

其參數(shù)operator其枚舉值有兩個:MUST_PASS_ALL(表示返回的結(jié)果集數(shù)據(jù)必須通過所有過濾器的過濾),MUST_PASS_ONE(表示返回的結(jié)果集數(shù)據(jù)只要通過了其中一個過濾器就行)陪每。

2)Counters

Hbase提供了計數(shù)器Counters機制影晓。它將列當做Counters镰吵,通過對列的操作來完成計數(shù)。在命令行下用戶可以通過如下命令增加計數(shù)挂签。


incr?‘

’,’’,’’,[]


如果想獲取當前計數(shù)器的值疤祭,可以通過get命令或者get_counter或者incr命令。如下:

get ‘

’,’’;


get_counter ‘

’,’’;


incr?‘

’,’’,’’,0;


第一個和第二個的區(qū)別就是第一個返回的值是字節(jié)數(shù)組類型饵婆,用戶很難立刻知道到底代表什么值勺馆。第二個返回的是可讀的值。第三個命令采用比較投機取巧的辦法侨核,通過incr計數(shù)加0來返回當前值草穆。如果將減少計數(shù),可以通過incr命令來增加一個負數(shù)的值搓译。

HTable提供了單個計數(shù)器(Single Counters)和多個計數(shù)器(Multiple Counters)悲柱。對于單個的Counters,需要指定準確的列名些己,跟命令行的incr一樣豌鸡,可以通過增加正數(shù)和負數(shù)或者零來達到增加計數(shù),減少計數(shù)以及訪問當期計數(shù)的目的轴总。構(gòu)造函數(shù)如下:

long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier,long amount) throws IOException

long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier,long amount, boolean writeToWAL) throws IOException

對于多重計數(shù)器直颅,HTable提供的方法如下:

Result increment(Increment increment) throws IOException

1、用戶需要創(chuàng)建一個Increment實例怀樟,可以采用如下構(gòu)造函數(shù):

Increment() {}

Increment(byte[] row)

Increment(byte[] row, RowLock rowLock)

2功偿、如果想為這個Increment實例添加必要的條件,如列名往堡,或者時間戳范圍械荷,可以通過如下方法來完成÷腔遥可以在一個Increment實例中通過增加多列來實現(xiàn)多重計數(shù)器吨瞎。

Increment addColumn(byte[] family, byte[] qualifier, long amount)

Increment setTimeRange(long minStamp, long maxStamp) throws IOException

3)Coprocessors

Coprocessors是Hbase提供的另一大特性∧赂溃可以認為是簡化的MapReduce組件颤诀。Coprocessors是一組內(nèi)嵌于RegionServer和HMaster進程的框架(BigTable的coprocessors擁有獨立進程和地址空間),支持用戶請求在每個Region上并行運行对湃,類似于傳統(tǒng)數(shù)據(jù)庫中觸發(fā)器的功能崖叫。


1、Hbase提供的Coprocessors有兩種類型:observer和endpoint拍柒。其中observer類似于RDBMS中的觸發(fā)器心傀,即鉤子函數(shù),其代碼部署在服務(wù)器端運行拆讯,在真實的方法前添加pre(),實現(xiàn)后加入

post(),以實現(xiàn)對真實方法的輔助操作脂男。而endpoint類似于存儲過程养叛。

2、Coprocessors框架有三個模塊組成:Coprocessors宰翅,CoprocessorEnvironment弃甥,

CoprocessorHost。CoprocessorEnvironment提供Coprocessors實例運行的環(huán)境以及持有

Coprocessors實例的生命周期狀態(tài)汁讼。CoprocessorHost是用來維護Coprocessors實例和

Coprocessors運行環(huán)境的潘飘。

三元體類圖如下(Hbase94版本):用戶可以通過繼承BaseRegionObserver, WALObserver掉缺,

BaseMasterObserver或者BaseEndpointCoprocessor來實現(xiàn)自定義的Coprocessors卜录。


A、coprocessors Load

Coprocessors有兩種加載方式:通過配置文件方式的靜態(tài)加載和動態(tài)加載方式眶明。

a艰毒、配置文件加載

靜態(tài)加載方式就是通過hbase-site.xml配置文件配置指定的coprocessors來加載。配置方式如下搜囱,其執(zhí)行順序就是按照配置文件指定的順序:

hbase.coprocessor.region.classes

coprocessor.RegionObserverExample,coprocessor.otherCoprocessor

hbase.coprocessor.master.classes

coprocessor.MasterObserverExample



hbase.coprocessor.wal.classes

coprocessor.WALObserverExample, bar.foo.MyWALObserver



需要注意的是:通過這種方式加載的RegionObserver是針對所有Region和表的丑瞧。用戶無法指定某一具體的Region或者table。

b蜀肘、通過table description加載

通過這種方式的加載是細化到具體的表的維度绊汹。只有跟該表有關(guān)的Region操作才會加載。所以這種方式的加載只能針對RegionCoprocessor扮宠。加載方法是:


HTableDescriptor.setValue(),其中key是Coprocessor西乖,value是||

B、observer


observer又有三種實現(xiàn)類型:

a坛增、RegionObserver

RegionObserver一般用來進行數(shù)據(jù)操作的coprocessor获雕,比如數(shù)據(jù)訪問前的權(quán)限身份驗證,F(xiàn)ilter收捣,二級索引等届案。如:

void preFlush(...) / void postFlush(...) MemStore中內(nèi)容flush到Storefile前后添加輔助型操作。

void preGet(...) / void postGet(...)?獲取數(shù)據(jù)的前后添加輔助操作

b罢艾、MasterObserver

MasterObserver是面向整個集群的事件楣颠,比如基于管理員的操作和DDL類型的操作的監(jiān)控。如:

void preCreateTable(...) / void postCreateTable(...)?創(chuàng)建表前后做些輔助操作

void preAddColumn(...) / void postAddColumn(...)?創(chuàng)建列前后做些輔助操作

void preMove(...) / void postMove(...)?? ????移動Region的前后添加輔助操作

c咐蚯、WALObserver

WALObserver則是提供鉤子函數(shù)對Write Ahead Log的的操作童漩。

C、Endpoint

Endpoint動態(tài)擴展了RPC協(xié)議仓蛆。只支持Region的操作睁冬,不支持Master和WAL的操作挎春。用戶可以通過Endpoint完成一些聚集函數(shù)的功能看疙,如AVG豆拨,Count,SUM等能庆。其原理是通過包裝客戶端的實現(xiàn)施禾,類似于MapReduce,比如getSum()操作搁胆,Map端endpoint通過并行的scan完成對每個Region的操作弥搞,每個Region的scan結(jié)果匯總到endpoint包裝的客戶端,將每個Region反饋的結(jié)果進行匯總即可得到getSum()的結(jié)果渠旁。

?D攀例、小結(jié)

a、Coprocessors有兩種類型:observer和endpoint顾腊。observer類似于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中的觸發(fā)器粤铭,通過鉤子函數(shù)來完成對被鉤的方法的輔助功能,endpoint類似于關(guān)系型數(shù)據(jù)庫中的存儲過程杂靶,用來實現(xiàn)聚合函數(shù)的相關(guān)功能梆惯。

b、Coprocessors支持動態(tài)加載吗垮,擁有多種加載方式垛吗。

c、Coprocessors可以將多個Coprocessor鏈接在一起使用烁登,類似于Servlet中的filters過濾器怯屉。

d、Coprocessors中有優(yōu)先級的概念饵沧,SYSTEM級別的Coprocessor優(yōu)先處理蚀之,USER級別的Coprocessor優(yōu)先級更低。

4)Split And Comcaption

A捷泞、Region Split

當創(chuàng)建一個表時足删,此時該表只對應(yīng)一個Region。隨著不斷了往表中插入記錄锁右,表數(shù)據(jù)越來越多失受,當超過設(shè)定的值hbase.hregion.max.filesize時,該Region就會Split成兩個子Region咏瑟。原來的那個Region就會被刪除拂到。具體操作如下:

a、HRegionServer創(chuàng)建一個splits目錄码泞,并且關(guān)閉其父Region以防接收其它請求兄旬。

b、HRegionServer會在splits目錄準備好兩個子Region,父Region的RowKey對半切领铐。然后將其移動到表目錄下悯森,并且更細.Meta.表的數(shù)據(jù),指示該父Region正在被執(zhí)行Split操作绪撵。

c瓢姻、讀取父Region的數(shù)據(jù)到子Region中。更新.Meta.表音诈。

d幻碱、清理父Region,通知HMaster將新的子Region遷移到其它RegionServer中细溅。

Split過程核心代碼如下:如果想了解有關(guān)Split的詳細流程褥傍,可以參考:

http://punishzhou.iteye.com/blog/1233802


B、Compaction

當Hbase將MemStore中的內(nèi)容flush到StoreFile中后喇聊,由于每次flush都會產(chǎn)生一個新的HFile文件摔桦。隨著一次次的flush,HFile文件越來越多承疲,當達到設(shè)定的閥值時邻耕,Hbase提供了Compaction特性,會通過此機制將HFile文件進行壓縮燕鸽。

Compaction機制分為兩種方式:minor compactions和major compactions 兄世。minor compactions是將相鄰的一些小的HFile合并成一個稍大的HFile,表演一個多路合并的過程啊研,其文件的數(shù)目由(hbase.hstore.compaction.min)指定御滩;而major compactions會將一個Store中的所有HFile合并成一個HFile,并且在壓縮的過程中會進行版本合并和刪除過濾操作党远。比如對于那些同一個Cell中且同一個時間戳的數(shù)據(jù)削解,只保留最新的那個值,其他的值將被廢棄沟娱。此外標記了刪除樣式的數(shù)據(jù)以及過期的數(shù)據(jù)也將被過濾氛驮。

其實Compaction就是將多個有序的HFile文件合并成一個有序的HFile文件的一個過程。它會創(chuàng)建一個StoreFileScanner來包裝每一個StoreFile,然后再通過一個StoreFileScanner實例來組裝StoreFile對應(yīng)的StoreFileScanner列表济似。通過StoreFileScanner實例提供的next()和seek()方法獲取每個storeFile中的數(shù)據(jù)矫废,最后再將此數(shù)據(jù)append到一個新的HFile中。


5)HTablePool

如果用戶每次發(fā)起一個請求時都創(chuàng)建一個HTable實例砰蠢,如下創(chuàng)建方式:


Configuration conf = HBaseConfiguration.create();

HTable table = new HTable(conf, "testtable");

這種方式雖然可以滿足要求蓖扑,但對于請求數(shù)比較多的情況或者要求響應(yīng)時間比較快的情況,如上創(chuàng)建HTable實例就比較落伍了台舱。因為創(chuàng)建Htable是一個比較耗時的過程律杠,此外,HTable并不能保證線程安全,在多線程處理下就可能產(chǎn)生莫名其妙的問題柜去。

HBase提供了HTable池特性可以解決此問題灰嫉。用戶可以直接從HTable池中獲取HTable實例。

1诡蜓、可以通過如下構(gòu)造函數(shù)來創(chuàng)建HTablePool實例,如下:

HTablePool()

HTablePool(Configuration config, int?maxSize)

? ? ? HTablePool(Configuration config, int maxSize,HTableInterfaceFactory tableFactory)

上面的第一個構(gòu)造函數(shù)會默認獲取classpath下的配置胰挑,并且創(chuàng)建無窮大的HTable個數(shù)蔓罚。用戶可以提供定制的創(chuàng)建的HTable實例的工廠來,這樣創(chuàng)建的HTablePool中的HTable就是用戶定制的

HTable實例瞻颂。maxSize參數(shù)是指定HTable池中最大持有多少個HTable實例豺谈。比如如果此size為5,

而用戶通過getTable獲取了10次引用贡这,那么當用戶通過putTable方法將實例放回HTable池中時茬末,只能放回5個實例,另外的5次將被忽略掉了盖矫。

2丽惭、創(chuàng)建HTablePool實例后,就可以通過getTable方法獲取對應(yīng)的表的HTable實例了辈双。如下:

HTableInterface getTable(String tableName)

HTableInterface getTable(byte[] tableName)

3责掏、當使用完HTable實例后,需要將HTable實例關(guān)閉湃望,可以采用如下方法:

void closeTablePool(String tableName)

void closeTablePool(byte[] tableName)

void putTable(HTableInterface table)

closeTablePool(tableName)相當于直接將此Table實例關(guān)閉换衬。建議使用此方法。PutTable(FilterBase)表示將此實例放回HTable池中供下次使用证芭。建議不要使用此方法瞳浦,目前此方法也在逐漸廢棄。需要注意的是以上操作最好放到finally模塊進行處理废士。


五叫潦、總結(jié)

A、總的來說Hbase因為其面向列族的key-value存儲特性使得其擁有列式數(shù)據(jù)庫的優(yōu)勢官硝。分布式的Hbase應(yīng)用是由客戶端和服務(wù)端進程組成诅挑,通過HDFS作為其持久層,采用Zookeeper來完成集群的管理和狀態(tài)監(jiān)控協(xié)調(diào)服務(wù)泛源。對于全表掃描和大數(shù)據(jù)的加載通過MapReduce來完成拔妥。Hbase無縫集成了Apache的這幾大組件來實現(xiàn)可伸縮,面向列族的分布式存儲系統(tǒng)达箍。


B没龙、Hbase是嚴格一致性的分布式存儲系統(tǒng),從兩個方面來保證嚴格一致性問題:它提供行鎖,但不提供多行鎖和事務(wù)硬纤,保證了讀寫的原子性解滓。此外Hbase數(shù)據(jù)存儲支持多版本和時間戳的特性。

C筝家、Hbase可以認為是BigTable的開源實現(xiàn)洼裤,但跟BigTable還是有很多區(qū)別。比如:Hbase的Coprocessors跟BigTable不同溪王。Hbase支持服務(wù)器端的Filter以減少網(wǎng)絡(luò)傳輸開銷腮鞍。此外Hbase支持可插拔的文件系統(tǒng),目前文件系統(tǒng)是HDFS莹菱,BigTable是GFS移国。

D、Hbase通過實現(xiàn)服務(wù)器端的鉤子(Coprocessors)來完成二級索引道伟。這也是BigTable沒有實現(xiàn)的迹缀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蜜徽,隨后出現(xiàn)的幾起案子祝懂,更是在濱河造成了極大的恐慌,老刑警劉巖拘鞋,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫂易,死亡現(xiàn)場離奇詭異,居然都是意外死亡掐禁,警方通過查閱死者的電腦和手機怜械,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來傅事,“玉大人缕允,你說我怎么就攤上這事〔湓剑” “怎么了障本?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長响鹃。 經(jīng)常有香客問我驾霜,道長,這世上最難降的妖魔是什么买置? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任粪糙,我火速辦了婚禮,結(jié)果婚禮上忿项,老公的妹妹穿的比我還像新娘蓉冈。我一直安慰自己城舞,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布寞酿。 她就那樣靜靜地躺著家夺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伐弹。 梳的紋絲不亂的頭發(fā)上拉馋,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音惨好,去河邊找鬼煌茴。 笑死,一個胖子當著我的面吹牛昧狮,可吹牛的內(nèi)容都是我干的景馁。 我是一名探鬼主播板壮,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼逗鸣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绰精?” 一聲冷哼從身側(cè)響起撒璧,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笨使,沒想到半個月后卿樱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡硫椰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年繁调,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片靶草。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹄胰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奕翔,到底是詐尸還是另有隱情裕寨,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布派继,位于F島的核電站宾袜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏驾窟。R本人自食惡果不足惜庆猫,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绅络。 院中可真熱鬧阅悍,春花似錦好渠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寻行,卻和暖如春霍掺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留夜郁,地道東北人左权。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像栈妆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容