hbase权威指南学习笔记
生活随笔
收集整理的這篇文章主要介紹了
hbase权威指南学习笔记
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、簡(jiǎn)介
1.列式存儲(chǔ)數(shù)據(jù)庫(kù)
以列為單位聚合數(shù)據(jù),然后將列值順序的存入磁盤,而傳統(tǒng)數(shù)據(jù)庫(kù)時(shí)為行式數(shù)據(jù)庫(kù),連續(xù)地存儲(chǔ)整行
列式數(shù)據(jù)庫(kù):對(duì)于特定的查詢,不需要所有的值,在分析型數(shù)據(jù)庫(kù)最常見(jiàn)
1)關(guān)系型數(shù)據(jù)庫(kù)存在的問(wèn)題
高并發(fā)的解決步驟
增加用于讀取的從服務(wù)器,將讀寫分離
增加緩存,如Memcached,但無(wú)法保證數(shù)據(jù)的一致性
將數(shù)據(jù)分區(qū)到多個(gè)數(shù)據(jù)庫(kù)中,運(yùn)維成本高。分區(qū)主要描述了邏輯上水平劃分?jǐn)?shù)據(jù)的方案,特點(diǎn)是將數(shù)據(jù)分文件或分服務(wù)器存儲(chǔ),而不是連續(xù)存儲(chǔ)。數(shù)據(jù)的分區(qū)是在固定范圍內(nèi)實(shí)施的:在傳入數(shù)據(jù)之前,必須提前劃分好數(shù)據(jù)的存儲(chǔ)范圍
一致性模型:數(shù)據(jù)庫(kù)必須保證每一步操作都是從一致的狀態(tài)到下一個(gè)一致的狀態(tài) 按照嚴(yán)格強(qiáng)度劃分: 嚴(yán)格一致性:數(shù)據(jù)的變化是原子的,一經(jīng)改變及時(shí)生效 順序一致性:每個(gè)客戶端看到的數(shù)據(jù)依照它們操作執(zhí)行的順序而變化 因果一致性:客戶端以因果關(guān)系順序觀察到數(shù)據(jù)的改變 最終一致性:在沒(méi)有更新數(shù)據(jù)的一段時(shí)間里,系統(tǒng)將通過(guò)廣播早證副本之間的數(shù)據(jù)一致性 弱一致性:沒(méi)有做出保證的情況下,所有的更新會(huì)通過(guò)廣播的形式傳遞,展現(xiàn)給不同客戶端的數(shù)據(jù)順序可能是不一樣
阻抗匹配:為一個(gè)給定問(wèn)題找到一個(gè)理想的解決方案,除了使用通用的解決方案,還應(yīng)該知道有什么可用的解決方案,從而找到最適合解決該問(wèn)題的系統(tǒng)
2.表、行、列和單元格 最基本的單位是列,一列或多列形成一行,并由唯一的行健(row key)來(lái)確定存儲(chǔ),一個(gè)表有若干行,其中每列可能有多個(gè)版本,在每個(gè)單元格中存儲(chǔ)了不同的值 一行由若干列組成,若干列又構(gòu)成了一個(gè)列族,一個(gè)列族的所有列存儲(chǔ)在同一個(gè)底層文件中,這個(gè)存儲(chǔ)文件叫做HFile,列族需要在表創(chuàng)建的時(shí)候就定義好,常見(jiàn)的引用列的格式為family:qualifer,列族的數(shù)量有限制,但是列的數(shù)量沒(méi)有限制,列值也沒(méi)有長(zhǎng)度和類型的限制 在Hbase中空值是沒(méi)有任何消耗的,它們不占用任何的存儲(chǔ)空間 每列或每個(gè)單元格的值都具有時(shí)間戳,默認(rèn)由系統(tǒng)指定,也可以由用戶顯示設(shè)置 BigTable和Hbase的典型使用場(chǎng)景是webtable,存儲(chǔ)從互聯(lián)網(wǎng)中抓取的網(wǎng)頁(yè) 行數(shù)據(jù)的存儲(chǔ)操作都是原子的,可以讀寫任意數(shù)目的列,目前還不支持跨行事務(wù)和跨表事務(wù)
3.自動(dòng)分區(qū) Hbase中擴(kuò)展和負(fù)載均衡的基本單元稱為region,region本質(zhì)上是以行健排序的連續(xù)存儲(chǔ)的區(qū)間
4.存儲(chǔ)API API提供了建表、刪表、增加列族和刪除列族的操作,同時(shí)還提供了修改表和列族元數(shù)據(jù)的功能 scanAPI提供了高效遍歷某個(gè)范圍的行的功能 在服務(wù)器的地址空間中執(zhí)行來(lái)自客戶端的代碼,支持這種功能的服務(wù)器框架叫做協(xié)處理器(coprocessor)
5.實(shí)現(xiàn) 每次更新數(shù)據(jù)時(shí),都會(huì)先將數(shù)據(jù)記錄在提交日志上(commit log)中,在Hbase中這叫預(yù)寫日志(write-ahead log,WAL),然后才將這些數(shù)據(jù)寫入內(nèi)存中的memstore中,到超過(guò)給定的最大值值,就寫到磁盤的HFile文件,HFile是不可被改變的 合并HFile機(jī)制 minor合并:將多個(gè)小文件(默認(rèn)最小3個(gè),最大10個(gè))重寫到數(shù)據(jù)較少的大文件中,每個(gè)HFile都是經(jīng)過(guò)歸類的,所以合并的速度很快,只受磁盤IO的影響 major合并:將一個(gè)region中一個(gè)列族的若干個(gè)HFile重寫到一個(gè)新的HFile中,major合并能掃描所有的鍵值對(duì),順序重寫全部的數(shù)據(jù)
二、客戶端API:基礎(chǔ)知識(shí) 1.概述 Hbase主要的客戶端接口是有org.apache.hadoop.hbase.client包中的HTable提供的HTable類提供的,通過(guò)這個(gè)類用戶可以向Hbase存儲(chǔ)和檢索數(shù)據(jù) 所有修改數(shù)據(jù)的操作都保證了行級(jí)別的原子性 創(chuàng)建HTable實(shí)例是有代價(jià)的,每個(gè)實(shí)例都需要掃描.META.表,以檢查該表是否存在,是否可用,以及一些其他操作,因此推薦用戶在每個(gè)線程(在開(kāi)始時(shí))只創(chuàng)建一次HTable實(shí)例,而后在客戶端應(yīng)用的生存期內(nèi)復(fù)用這個(gè)對(duì)象,如果用戶需要使用多個(gè)HTable實(shí)例,應(yīng)考慮使用HTablePool類 Hable(Configuration conf,"tableName")
2.CRUD操作 2.CRUD操作 2.1 put方法:向Hbase存儲(chǔ)數(shù)據(jù) 1)調(diào)用HTable的put方法格式: void put(Put put)或void put(List<put> puts) Put對(duì)象的構(gòu)造方法如下 創(chuàng)建Put實(shí)例之后,就可以使用add方法 向該實(shí)例添加數(shù)據(jù)了,每一次調(diào)用add()都可以特定的添加一列數(shù)據(jù),如果再加上一個(gè)時(shí)間戳選項(xiàng),就能形成一個(gè)數(shù)據(jù)單元格。每個(gè)KeyValue實(shí)例包含器完成地址(行健、列族、列以及時(shí)間戳)和實(shí)際數(shù)據(jù),KeyValue是Hbase在存儲(chǔ)架構(gòu)中最底層的類 可以使用如下方法檢查是否存在特定的單元格,而不需要遍歷整個(gè)集合 通過(guò)客戶端訪問(wèn)配置文件 當(dāng)你調(diào)用任何一個(gè)靜態(tài)create()方法時(shí),代碼會(huì)嘗試使用當(dāng)前的java classpath來(lái)載入兩個(gè)配置文件hbase-default.xml和hbase-site.xml
Hbase的一個(gè)特殊功能是能為一個(gè)單元格存儲(chǔ)多個(gè)版本的數(shù)據(jù),這個(gè)版本使用一個(gè)時(shí)間戳,必須確保所有服務(wù)器的時(shí)間都是正確的,并且相互之間是同步的,默認(rèn)情況下Hbase會(huì)保留3個(gè)版本的數(shù)據(jù) 若需要頻繁的修改某些行,用戶有必要?jiǎng)?chuàng)建一個(gè)RowLock實(shí)例來(lái)防止其他用戶訪問(wèn)這些行
2)KeyValue類 數(shù)據(jù)和坐標(biāo)都是以java的byte[]形式存儲(chǔ)的,使用這種類型的目的是允許存儲(chǔ)任意類型的數(shù)據(jù)
3)客戶端的寫緩沖區(qū) 每一個(gè)put操作實(shí)際上都是一個(gè)RPC操作,它將客戶端數(shù)據(jù)傳送到服務(wù)器后返回,這只適合小數(shù)據(jù)量的操作,Hbase的API配備了一個(gè)客戶端的寫緩沖區(qū)(write buffer),緩沖區(qū)負(fù)責(zé)收集put操作,然后調(diào)用RPC操作一次性將put送往服務(wù)器,全局交換機(jī)制控制著該緩沖區(qū)是否在使用,其方法如下 void setAutoFlush(boolean autoFlush) 默認(rèn)情況下,客戶端緩沖區(qū)是禁用的,可以通過(guò)將autoflush設(shè)置為false來(lái)激活緩沖區(qū),通過(guò)setBufferSize(long size)來(lái)配置客戶端寫緩沖區(qū)的大小,默認(rèn)大小是2M,為每一個(gè)用戶創(chuàng)建的HTable實(shí)例都設(shè)置緩沖器大小十分麻煩,可以在hbase-site.xml中添加一個(gè)較大的預(yù)設(shè)值,配置如下 <property> <name>hbase.client.write.value</name> <value>20971520</value> </property>
當(dāng)需要強(qiáng)制把數(shù)據(jù)寫到服務(wù)器端時(shí),用flushCommit()函數(shù) 隱式刷寫:在用戶調(diào)用put()或setBufferSize()時(shí)觸發(fā),這兩個(gè)方法都會(huì)將目前占用的緩沖區(qū)大小和用戶配置的緩沖區(qū)大小進(jìn)行比較,此外調(diào)用HTable的close()也會(huì)無(wú)條件地隱式刷寫 用戶可以通過(guò)訪問(wèn)ArrayList<Put> getWriteBuffer()來(lái)訪問(wèn)客戶端寫緩沖區(qū)的內(nèi)容 如果用戶只存儲(chǔ)大單元格,那么客戶端緩沖區(qū)的作用就不大了 4)Put列表 調(diào)用void put(List<put> puts)時(shí),客戶端先把所有的Put實(shí)例插入到本地寫緩沖區(qū)中,然后隱式的調(diào)用flushCache(),如果其中有失敗的Put實(shí)例(有些檢查是在客戶端完成的,如確認(rèn)Put實(shí)例的內(nèi)容是否為null或是否指定了列),那么后面的Put實(shí)例不會(huì)被添加到緩沖區(qū),也不會(huì)觸發(fā)刷寫命令,當(dāng)使用基于列表的Put調(diào)用時(shí),用戶需要特別注意:用戶無(wú)法控制服務(wù)器執(zhí)行put的順序,如果要保證寫入的順序,需要小心地使用這個(gè)操作。
5)原子性操作compare-and-set 有一種特別的put調(diào)用,其能保證自身操作的原子性:checkAndPut(row,family,qualifier,value,Put put),這種有原子性的操作經(jīng)常被用于賬戶結(jié)余,狀態(tài)轉(zhuǎn)換或數(shù)據(jù)處理等場(chǎng)景 有一種特別的檢查通過(guò)checkAndPut()調(diào)用來(lái)完成,即只有在另外一個(gè)值不存在的情況下,才執(zhí)行這個(gè)修改,要執(zhí)行這種操作只需要將參數(shù)value設(shè)置為null Hbase提供的compare-and-set操作,只能檢查和修改同一行數(shù)據(jù)
2.2 get方法:客戶端獲取已存儲(chǔ)數(shù)據(jù)的方法 Result get(Get get); 1)單行Get 構(gòu)造Get實(shí)例: Get(rowkey) Get(rowkey,RowLock rowLock) 可以通過(guò)多種標(biāo)準(zhǔn)篩選目標(biāo)數(shù)據(jù): Get addFamily(family):只能取得一個(gè)指定的列族 Get addColumn(family,qualifier):獲取指定的列 Get setTimeRange(long minStamp,long masStamp)、 Get setTimeStamp(long timeStamp) Get setMaxVersions(int maxVersions)
2)result類 get()返回的結(jié)果包含所有匹配的單元格數(shù)據(jù),被封裝成一個(gè)Result類 常用方法: byte[] getValue(family,qualifier):取得特定單元格的值 byte[] value():返回第一列對(duì)應(yīng)的最新單元格的值 byte[] getRow():返回行健 int size():檢查是否有對(duì)應(yīng)的記錄 boolean isEmpty():檢查是否有對(duì)應(yīng)的記錄 KeyValue[] raw() List<KeyValue> list():用戶可以方便的迭代數(shù)據(jù) List<KeyValue> getColumn(family,qualifier) KeyValue getColumnLatest(family,qualifier) boolean containsColumn(family,qualifier) NavigableMap<byte[],NavigableMap[],NavigableMap<Long,byte[]>>> getMap():把請(qǐng)求返回的內(nèi)容都裝入一個(gè)Map類實(shí)例中,可以遍歷所有結(jié)果
3)get列表 Result[] get(List<Get> gets); boolean exists(Get get):查看存儲(chǔ)的數(shù)據(jù)是否存在 getRowOrBefore(row,family):
2.3 刪除方法 1)單行刪除 void delete(Delete delete) Delete實(shí)例構(gòu)造方法 Delete(rowkey) Delete(rowkey,long timestamp,RowLock rowLock) 常用方法 Delete deleteFamily(family[,long timestamp]) Delete deleteColumns(family,qualifier[,long timestamp]):沒(méi)指定timestamp,則刪除所有版本 Delete deleteColumn(family,qualifier[,long timestamp]):沒(méi)指定timestamp,則刪除最新版本
2)Delete的列表 void delete(List<Delete> deletes)
3)原子性操作compare-and-delete boolean checkAndDelete(row,qualifier,value,Delete delete)
2.4批處理操作 事實(shí)上許多基于列表的操作都是基于batch()方法是實(shí)現(xiàn)的。 方法: void batch(List<Row> actions,Object[] results) Object[] batch(List<Row> actions) 注:不可以將針對(duì)同一行數(shù)據(jù)的Put和Delete操作放在同一個(gè)批處理請(qǐng)求中 Row是Put、Get、Delete類的父類 當(dāng)用戶使用batch()功能時(shí),Put實(shí)例不會(huì)被客戶端寫入緩沖區(qū)中緩沖,batch()請(qǐng)求是同步的,會(huì)把操作直接發(fā)送給服務(wù)器 兩種方法相同點(diǎn): get、put、delete操作都支持,如果執(zhí)行時(shí)出現(xiàn)問(wèn)題,客戶端將拋出異常并報(bào)告問(wèn)題,都不適用客戶端的寫緩沖區(qū) 不同點(diǎn): void batch(acitons,results):能訪問(wèn)成功操作的結(jié)果,同時(shí)也可以獲取遠(yuǎn)程失敗的異常 Object[] batch(actions):只返回客戶端異常,不能訪問(wèn)程序執(zhí)行中的部分結(jié)果 注:在檢查結(jié)果之前,所有的批處理操作都已經(jīng)執(zhí)行了:即使用戶收到異常,其他的操作也都已經(jīng)執(zhí)行了 批量處理可以感知暫時(shí)性錯(cuò)誤(如NoServingRegionException)會(huì)多次重試這個(gè)操作,用戶可以通過(guò)調(diào)整hbase.client.retries.number配置項(xiàng)(默認(rèn)為10)來(lái)增加或減少重試次數(shù)
2.5 行鎖 region服務(wù)器提供一個(gè)行鎖的特性,保證了只有一個(gè)客戶端能獲取一行的數(shù)據(jù)相應(yīng)的鎖,同時(shí)對(duì)該行進(jìn)行修改。用戶應(yīng)該盡可能的避免使用行鎖,如果必須使用,那么一定要節(jié)約占用鎖的時(shí)間 Get不需要鎖:服務(wù)器應(yīng)用了一個(gè)多版本的并發(fā)控制機(jī)制來(lái)保證行級(jí)讀操作,只有當(dāng)一個(gè)變動(dòng)被應(yīng)用到整個(gè)行之后,客戶端才能讀出這個(gè)改動(dòng),當(dāng)改動(dòng)進(jìn)行中時(shí),所有的客戶端讀取到的數(shù)據(jù)都是將是所有列以前的版本
2.6 掃描 類似于數(shù)據(jù)庫(kù)中的游標(biāo) ResultScanner getScanner(Scan scan) ResultScanner getScanner(family) ResultScanner getScanner(family,qualifier) scan類的構(gòu)造器 Scan() Scan(startRow,Filter filter) Scan(startRow) Scan(startRow,stopRow) 注:如果用戶只需要數(shù)據(jù)的子集,那么限制掃面的范圍就能發(fā)揮Hbase的優(yōu)勢(shì),如果不讀取整個(gè)列族,那么整個(gè)列族的文件都不會(huì)讀取,這就是列族存儲(chǔ)架構(gòu)的優(yōu)勢(shì) 1)ResultScanner類 掃描操作不會(huì)通過(guò)一次RPC請(qǐng)求返回所有匹配的行,而是以"行"為單位進(jìn)行返回 Result next() Result[] next(int nbRows) void close() 要確保盡早釋放掃描器實(shí)例,當(dāng)使用完ResultScanner之后應(yīng)調(diào)用它的close()方法,釋放所有由掃描器控制的資源 就像行級(jí)鎖一樣,掃描器也使用同樣的租約超時(shí)限制,保護(hù)其不被時(shí)效的客戶端阻塞太久,通過(guò)如下配置 <property> <name>hbase.regionserver.lease.period</name> <value>120000</value> </property> 2)緩存與批量處理 如果一次RPC請(qǐng)求可以返回多行數(shù)據(jù),這樣使用掃描器更有意義,可以由掃描器緩存實(shí)現(xiàn),默認(rèn)情況下,這個(gè)緩存是關(guān)閉的??梢詮膬蓚€(gè)層面打開(kāi)它 在表的層面,這個(gè)表的所有掃描器實(shí)例的緩存都會(huì)生效,用戶使用一下的Htable方法設(shè)置表級(jí)的掃描器緩存: void setScannerCaching(int scannerCaching), int getScannerCaching():默認(rèn)是1 在掃描器層面,這樣只會(huì)影響當(dāng)前的掃描實(shí)例,用戶使用一下的Scan類的方法設(shè)置掃描器級(jí)的掃描器緩存: void setCaching(int scannerCaching) int getCaching():默認(rèn)是1 此外用戶可以修改整個(gè)集群的配置 <property> <name>hbase.client.scanner.caching</name> <value>10</value> </property> 這樣所有scan的實(shí)例的掃描器緩存就都被設(shè)置為10了 注:當(dāng)數(shù)據(jù)量非常大的行,可能超過(guò)客戶端進(jìn)程的內(nèi)存容量,解決方法:使用Scan類的批量操作 setBatch(int batch) int getBatch() 緩存是面向行一級(jí)的操作,而批量是面向列一級(jí)的操作。
2.8 各種特性 1)Htable使用方法 void close():使用完一個(gè)HTable實(shí)例后,需要調(diào)用一次close(),它會(huì)刷寫所有客戶端緩沖的寫操作 HTableDescriptor getTableDescripor():每個(gè)表都使用一個(gè)HTableDescriptor實(shí)例類來(lái)定義表結(jié)構(gòu) Map<HRegion,HServerAddress> getRegionInfo():獲取某一行數(shù)據(jù)的具體位置信息
三、客戶端API:高級(jí)特性 1.過(guò)濾器 Get和Scan兩個(gè)類都支持過(guò)濾器,過(guò)濾器的基本接口叫做Filter,用戶還可以通過(guò)繼承Filter類實(shí)現(xiàn)自己的需求 1.1 比較運(yùn)算符 1.2 比較器 1.3 Hbase提供的第一類:比較過(guò)濾器 用戶創(chuàng)建實(shí)例時(shí)需要一個(gè)比較運(yùn)算符和一個(gè)比較器實(shí)例 CompareFilter(CompareOp op,WriteableByteArrayComparable valueComparator)
1.4 Hbase提供的第二類:專用過(guò)濾器
1.5 附加過(guò)濾器(應(yīng)用在其他過(guò)濾器上) 跳轉(zhuǎn)過(guò)濾器:SkipFilter(Filter filter):當(dāng)被包裝的過(guò)濾器遇到一個(gè)需要過(guò)濾的KeyValue時(shí),用戶可以擴(kuò)展并過(guò)濾整行數(shù)據(jù) 全匹配過(guò)濾器:WhileMatchFilter
1.6 FilterList 需要多個(gè)過(guò)濾器共同限制返回到客戶端的結(jié)果 FilterList(List<Filter> rowFilters) FilterList(Operator op) FilterList(List<Filter> rowFilters,Operator op) 參數(shù)rowFilters以列表的形式組合過(guò)濾器,參數(shù)operator決定了組合它們的結(jié)果,默認(rèn)是為MUST_PASS_ALL,使用ArrayList可以保證過(guò)濾器的執(zhí)行順序與它們添加到列表中的順序一致
1.7 自定義過(guò)濾器 用戶可以實(shí)現(xiàn)Filter接口或者直接繼承FilterBase類
用戶自定義過(guò)濾器部署 編寫代碼-->打成jar包-->把文件發(fā)送到每個(gè)region服務(wù)器上-->修改hbase-env.sh文件如下 export HBASE_CLASSPATH="/hbase-book/target.aa.jar"-->重啟hbase
2 計(jì)數(shù)器 2.1 簡(jiǎn)介 許多收集統(tǒng)計(jì)信息的應(yīng)用有點(diǎn)擊流和在線廣告意見(jiàn),這些需要被收集到日志文件中用戶后續(xù)的分析,用戶可以使用計(jì)數(shù)器做實(shí)時(shí)統(tǒng)計(jì),從而放棄延遲較高的批處理操作 雖然用戶可以一次更新多個(gè)計(jì)數(shù)器,但是它們必須屬于同一行,更新多個(gè)計(jì)數(shù)器需要通過(guò)獨(dú)立的API調(diào)用,即多個(gè)RPC請(qǐng)求 初始化計(jì)數(shù)器:用戶不用初始化計(jì)數(shù)器,當(dāng)用戶第一次使用計(jì)數(shù)器時(shí),計(jì)數(shù)器自動(dòng)設(shè)置為0,即當(dāng)用戶創(chuàng)建一個(gè)新列時(shí),計(jì)數(shù)器的值是0 在shell中操作計(jì)數(shù)器使用incr '<table>','<row>','<column>',[increment-value]與get_counter '<table>','<row>','<column>' 客戶端API操作計(jì)數(shù)器 1)單計(jì)數(shù)器 只能操作一個(gè)計(jì)數(shù)器:用戶需要自己設(shè)定列,方法由HTable提供的 long incrementColumnValue(row,family,qualifier,long amount) long incrementColumnValue(row,family,qualifier,long amount,boolean writeToWAL) 2)多計(jì)數(shù)器 Result increment(Increment increment) 需要?jiǎng)?chuàng)建一個(gè)Increment實(shí)例,構(gòu)造方法如下 Increment() Increment(row) Increment(row,RowLock rowLock) 向其中加入實(shí)際的計(jì)數(shù)器:addColumn(family,qualifier,long maxStamp)
3.協(xié)處理器 協(xié)處理器允許用戶在region服務(wù)器上運(yùn)行自己的代碼,也就是允許用戶執(zhí)行region級(jí)的操作,并可以使用如觸發(fā)器類似的功能 另一類適合使用協(xié)處理器的場(chǎng)景就是權(quán)限控制 協(xié)處理器框架提供了一些類,用戶可以通過(guò)繼承這些類擴(kuò)展自己的功能,主要有兩類,即observer和endpoint observer:回調(diào)函數(shù)(也被稱為鉤子函數(shù),hook)在一些特定時(shí)間發(fā)生時(shí)。這些事件包括用戶產(chǎn)生的事件和服務(wù)器內(nèi)部自動(dòng)產(chǎn)生的事件 RegionObserver:用戶可以用這種處理器處理數(shù)據(jù)修改事件,它們與表的region聯(lián)系緊密 MasterObserver:可以被用作管理或DDL類型的操作,這些是集群級(jí)事件 WALObserver:提供控制WAL的鉤子函數(shù)
endpoint:通過(guò)添加一些遠(yuǎn)程調(diào)用來(lái)動(dòng)態(tài)擴(kuò)展RPC協(xié)議,可以把它理解為與RDBMS中類似的存儲(chǔ)過(guò)程。endpoint可以與observer的實(shí)現(xiàn)組合起來(lái)直接作用于服務(wù)器的狀態(tài)
Coprocesspor類 所有協(xié)處理器的類都必須實(shí)現(xiàn)這個(gè)接口,它定義了協(xié)處理器的基本預(yù)定。提供了兩個(gè)被應(yīng)用于框架的枚舉類Priority(SYSTEM,USER)和State 待續(xù)!!!!
4.HtablePool 為Hbase集群提供一個(gè)客戶端連接池,用戶可以通過(guò)以下任意一個(gè)構(gòu)造器來(lái)創(chuàng)建池: HTablePool() HtablePool(Configuration conf,int maxSize) HtablePool(Configuration conf,int maxSize,HTableInterfaceFactory fac) HTableInterfaceFactory:用戶可以創(chuàng)建自定義的工廠類,例如,為Htable實(shí)例使用特定的配置,或可以讓實(shí)例完成一些初始化操作。如果用戶想自己擴(kuò)展HtableInterfaceFactory,則必須實(shí)現(xiàn)兩個(gè)方法createHTableInterface(conf,tableName)和releaseHtableInterface 使用表實(shí)例池方式:getTable(String tableName);getTable(byte[] tableName);void putTable(HtableInterface table)
5.連接管理 每個(gè)HTable實(shí)例都需要建立和遠(yuǎn)程主機(jī)的連接,這些連接在內(nèi)部使用HConnection類表示,被HConnectionManager類管理并共享。用戶沒(méi)必要和這兩個(gè)類打交道,只需要?jiǎng)?chuàng)建一個(gè)Configuration實(shí)例,然后利用客戶端API使用這些類。 Hbase內(nèi)部使用鍵值映射來(lái)存儲(chǔ)連接,使用Configuration實(shí)例作為鍵值映射的鍵。 HtablePool類,所有連接池中的Htable實(shí)例都自動(dòng)共用一個(gè)提供的Configuration實(shí)例,共享它們的連接。 共享連接的缺點(diǎn)在于釋放,如果用戶不顯示關(guān)閉連接,它將一直存在,直到客戶端退出,建議用戶不在需要使用Htable時(shí)主動(dòng)調(diào)用其close(),釋放資源,以下是顯式清理連接方法 deleteConnection(Configuration conf,boolean stop); deleteAllConnection(boolean stop)
四、客戶端API:管理功能 1.模式定義 1)表:使用表的主要原因是控制表中的所有列以達(dá)到共享表內(nèi)的某些特性的目的 表描述符的構(gòu)造函數(shù): HTableDescriptor(); HTableDescriptor(String name); HTableDescriptor(byte[] name); HTableDescriptor(HTableDescriptor desc);
任意不相交的系統(tǒng)間的遠(yuǎn)程通信都使用到了Hadoop RPC框架,需要遠(yuǎn)程方法中參數(shù)都實(shí)現(xiàn)Writeable接口,進(jìn)而能夠序列化對(duì)象并遠(yuǎn)程傳輸
2)表屬性 表名一定不能以".","-"開(kāi)頭,表名只能包含拉丁字母或數(shù)字、下劃線、".","-"
列族: void addFamily(HColumnDescriptor family) boolean hasFamily(byte[] c) HColumnDescriptor[] getColumnFamilies() HColumnDescriptor getFamily(byte[] column)
文件大小限制: long getMaxFileSize() void setMaxFileSize(long maxFileSize) 如果一個(gè)列族的存儲(chǔ)單元已使用的存儲(chǔ)空間超過(guò)了大小限制,region將發(fā)生拆分,maxFileSize默認(rèn)值是256M 這個(gè)參數(shù)只是大致的預(yù)期值,而在某些特殊條件下,文件大小可能超過(guò)這個(gè)預(yù)期值(一行數(shù)據(jù)不能跨region存儲(chǔ))
只讀:默認(rèn)所有的表都可寫,對(duì)于特殊的表來(lái)說(shuō),只讀參數(shù)有特殊的用途。調(diào)用setReadOnly(boolean readOnly)設(shè)置
memstore刷寫大小:寫操作會(huì)寫入到寫緩沖區(qū),人后按照合適的條件順序?qū)懭氲揭粋€(gè)新的存儲(chǔ)文件(磁盤)中,可以通過(guò)setMemStoreFlushSize(long memstoreFlushSize),這個(gè)memstoreFlushSize的默認(rèn)值是64MB
延遲日志刷寫: Hbase有兩種將WAL保存到磁盤的方式,一種是延遲日志刷寫,另一種不是,通過(guò)setDeferredLogFlush(boolean isDeferredLogFlush),isDeferredLogFlush的默認(rèn)值為false
3)列族 列族定義了所有列的共享信息,并且可以通過(guò)客戶端創(chuàng)建任意數(shù)量的列。定位到某個(gè)具體的列需要列族名和列名合并在一起,以:分隔,如family:qualifier 構(gòu)造方法: 列族名:getName()或getNameAsString() 不能被重命名,通常的做法是新建一個(gè)列族,然后使用API從舊列族中復(fù)制數(shù)據(jù)到新列族 列族名不能以"."開(kāi)頭,也不能包含":"、"\"或ISO控制符
最大版本數(shù):所有列族都限定了每個(gè)值能夠保留的最大版本數(shù),Hbase會(huì)移除超過(guò)最大版本數(shù)的數(shù)據(jù),通過(guò)setMaxVersions(int maxVersion)設(shè)置,這個(gè)maxVersion默認(rèn)為3.
壓縮: Hbase支持插件式的壓縮算法,允許用戶選擇最合適的壓縮算法 塊大小: 在Hbase中,所有的存儲(chǔ)文件都被劃分為若干個(gè)小存儲(chǔ)塊,這些小存儲(chǔ)塊在get或scan操作時(shí)會(huì)加載到內(nèi)存中,通過(guò)setBlockSize(int size)設(shè)置,默認(rèn)大小是64KB 注:HFile的不同于HDFS中的塊,HDFS提到的塊是用于拆分大文件以提供分布式存儲(chǔ),且便于MapReduce框架進(jìn)行并行計(jì)算的存儲(chǔ)單元;而HBase中的塊主要用于高效加載和緩沖數(shù)據(jù)
緩存塊: Hbase順序的讀取一個(gè)數(shù)據(jù)塊到內(nèi)存緩存中,這個(gè)參數(shù)默認(rèn)是為true,每次讀取的塊都會(huì)緩存到內(nèi)存中,但是如果順序讀取某個(gè)特定的列族,最好將這個(gè)屬性設(shè)置為false,通過(guò)setBlockCacheEnabled(boolean blockCacheEnabled)方法設(shè)置
生存期TTL: Hbase支持版本數(shù)據(jù)保存的時(shí)間,TTL設(shè)置了一個(gè)基于時(shí)間戳的臨界值,內(nèi)部管理會(huì)自動(dòng)檢查TTL的值是否達(dá)到上限,在major合并過(guò)程中時(shí)間戳被判定為超過(guò)TTL的數(shù)據(jù)會(huì)被刪掉,可以通過(guò)setTimeToLive(int timestamp)方法設(shè)置,TTL的參數(shù)為秒,默認(rèn)值是Integer.MAX_VALUE,理解為永久保留
在內(nèi)存中:setInMemory(boolean inMemory) 將inMemory設(shè)置為true只是一種承諾,或者說(shuō)高優(yōu)先級(jí)。在正常數(shù)據(jù)讀取過(guò)程中,塊數(shù)據(jù)被加載到緩沖區(qū)中并長(zhǎng)期駐留在內(nèi)存中,除非堆壓力過(guò)大,這個(gè)時(shí)候才會(huì)強(qiáng)制從內(nèi)存中卸載這部分?jǐn)?shù)據(jù)
布隆過(guò)濾器: 能夠減少特定訪問(wèn)模式下的查詢時(shí)間,由于這種模式增加了內(nèi)存和存儲(chǔ)的負(fù)擔(dān),這個(gè)模式默認(rèn)為關(guān)閉狀態(tài) 復(fù)制范圍:Hbase提供跨集群同步的功能,本地集群的數(shù)據(jù)更新可以及時(shí)同步到其他集群,復(fù)制范圍參數(shù)默認(rèn)為0,即這個(gè)功能處于關(guān)閉狀態(tài)。可以通過(guò)setScope(int scope)設(shè)置,1表示開(kāi)啟實(shí)時(shí)同步
2.HBaseAdmin HBaseAdmin提供了創(chuàng)建表、列族、檢查表是否存在,修改表結(jié)構(gòu)和列族結(jié)構(gòu)、以及刪除表功能 構(gòu)造方法:HbaseAdmin(Configuration conf)
1)表操作 建表: void createTable(HTableDescriptor desc) void createTable(HTableDescriptor desc,byte[] startKey,byte[] endKey,int numRegions) void createTable(HTableDescriptor desc,byte[][] splitKeys) void createTableAsync(HTableDescriptor desc,byte[][] splitKeys) HTable類中的方法getStartEndKey()來(lái)獲取所有region的邊界
獲取所有表的列表,以及判斷是否存在 boolean tableExists(String tableName) boolean tableExists(byte[] tableName) HTableDescriptor[] listTables() HTableDescriptor getTableDescriptor(byte[] tableName)
刪除表: void deleteTable(String tableName) void deleteTable(byte[] tableName)
在刪除表之前需要將表禁用,region服務(wù)器會(huì)先將內(nèi)存中近期內(nèi)還未提交的已修改的數(shù)據(jù)刷寫到磁盤,然后關(guān)閉所有region,并更新這樣表的元數(shù)據(jù),將所有region標(biāo)記為下線狀態(tài)。
2)集群管理 允許用戶查看集群當(dāng)前的狀態(tài): static void checkHBaseAvailable(Configuration) ClusterStatus getClusterStatus() void closeRegion(String regionname,String hostAndport) 注:所有可用表的region都應(yīng)該是在線狀態(tài) void majorCompact(String tableNameOrRegionName)
五、可用的客戶端 1.REST、Thrift,Avro介紹 它們都支持大量的語(yǔ)言,Protocol Buffer與Thrift和Avro最大的不同是它沒(méi)有自己的RPC堆,而它生成的RPC定義需要被后來(lái)其他的RPC庫(kù)使用,Hbase提供了REST、Thrift、Avro的輔助服務(wù),它們可以實(shí)現(xiàn)成專門的網(wǎng)關(guān)服務(wù),這些服務(wù)運(yùn)行在共享或?qū)S玫臋C(jī)器上。Thrift和Avro都有各自的RPC實(shí)現(xiàn),所以網(wǎng)關(guān)服務(wù)僅是在它們的基礎(chǔ)上進(jìn)行了封裝,至于REST,HBase則采用了自己的實(shí)現(xiàn),并提供了訪問(wèn)存儲(chǔ)數(shù)據(jù)的路徑。 每個(gè)請(qǐng)求使用一個(gè)服務(wù)而非建立一個(gè)連接的優(yōu)勢(shì)在于用戶可以復(fù)用連接來(lái)獲得最優(yōu)性能。 2.交互 1)使用原生Java:直接使用HTable并通過(guò)原生的RPC調(diào)用與HBase服務(wù)器進(jìn)行交互。 2)REST: 操作:基于REST服務(wù)的客戶端是在能夠與HBase通信之前需要先啟動(dòng)REST網(wǎng)關(guān)服務(wù),使用hbase-daemon.sh start rest命令。REST服務(wù)提供了HBase表提供的所有操作,REST服務(wù)器返回的值都經(jīng)過(guò)了base64Binary編碼。 支持的格式:通過(guò)使用HTTP Content-Type和Accept頭,調(diào)用者可以自動(dòng)選擇發(fā)送和接收信息的數(shù)據(jù)格式 Plain(text/plain): XML(text/xml):默認(rèn)的存儲(chǔ)和查詢格式是XML JSON(application/json):curl -H "Accept:application/json" http://<servername>:testtable/%01%02%03/colfam1:col1
REST的java客戶端: REST服務(wù)器同樣具有全面的java客戶端API,位于org.apache.hadoop.hbase.rest.client包中,其中核心類為RemoteHTable和RemoteAdmin
3)Thrift 在使用Thrift之前需要安裝Thrift,并且需要啟動(dòng)HBase提供的Thrift Server 啟動(dòng)Thrift命令:hbase-daemon.sh start thrift
4)Avro 在使用Thrift之前需要安裝Avro,并且需要啟動(dòng)HBase提供的Avro Server 啟動(dòng)Avro命令:hbase-daemon.sh start Avro
3.批量處理客戶端 1)Mapreduce:兩種方式,原生java API或Clojure 2)Hive Hive與Hbase之前的版本需要匹配,細(xì)微的RPC變化可能影響交互 3)pig 4)Cascading
4.shell 1)命令 引用名:命令行要求在使用表名和列名時(shí)需要通過(guò)單引號(hào)或雙引號(hào)對(duì)其進(jìn)行引用。 引用值:命令行支持二進(jìn)制、八進(jìn)制、十六進(jìn)制的輸入和輸出,用戶在引用時(shí)必須使用雙引號(hào) 使用逗號(hào)分隔參數(shù) Ruby散列屬性: 一些命令中需要設(shè)置鍵值對(duì)屬性,使用Ruby散列按照以下方式來(lái)完成 {'key1'=>'val1','key2'=>'val2',...}
DDL命令 alter 使用modifyTable()修改現(xiàn)有表結(jié)構(gòu)
DML命令:
工具命令: assgn 分配一個(gè)region到一臺(tái)region服務(wù)器中
復(fù)制命令:
腳本: 可以使用Nagios或其他監(jiān)控工具發(fā)送腳本 用戶還以使用管道的形式運(yùn)行命令
5.基于Web UI 1)master的web默認(rèn)端口是60010,region服務(wù)默認(rèn)端口是60030
六、與Mapreduce集成 1.類 InputFormat InputFormat負(fù)責(zé):拆分輸入數(shù)據(jù),同時(shí)返回一個(gè)RecordReader實(shí)例,定義了鍵值對(duì)象的類,并提供了next()遍歷數(shù)據(jù) 就HBase而言,它提供了一組專用的實(shí)現(xiàn),叫TableInputFormatBase,該實(shí)現(xiàn)的子類是TableInputFormat mapper HBase提供了一個(gè)TableMapper類,將鍵的類型強(qiáng)制轉(zhuǎn)換為ImmutableBytesWritable類,同時(shí)將改制的類型強(qiáng)制轉(zhuǎn)換為Result類型,TableMapper類沒(méi)有實(shí)現(xiàn)具體的功能,它只是添加了鍵值對(duì)的簽名 Reducer HBase提供了一個(gè)TableReducer類 OutputFormat Hbase提供了一個(gè)TableOutputFormat
2.支撐類 Mapreduce的支撐類與TableMapReduceUtil類一同協(xié)作在HBase上執(zhí)行Mapreduce任務(wù),它有一個(gè)靜態(tài)方法能配置作業(yè),病并使作業(yè)可以使用Hbase作為數(shù)據(jù)源或目標(biāo)
3.在HBase上的Mapreduce 當(dāng)運(yùn)行Mapreduce作業(yè)所需庫(kù)中的文件不是綁定在Hadoop或Mapreduce框架中時(shí),用戶就必須確保這些庫(kù)文在作業(yè)之前已經(jīng)可用,用戶一般兩個(gè)選擇:在所有的任務(wù)節(jié)點(diǎn)上準(zhǔn)備靜態(tài)的庫(kù)或直接提供作業(yè)所需的所有庫(kù) 1)靜態(tài)配置: 將jar文件復(fù)制到所有節(jié)點(diǎn)的常用路徑中 將這些jar文件的完整路徑寫入hadoop-env.sh配置文件中,按照如右方式編輯HADOOP-CLASSPATH變量:HADOOP-CLASSPATH="<extra-entries>":HADOOP-CLASSPATH 重啟所有的任務(wù)的NodeManager使變更生效 2)動(dòng)態(tài)配置:Hadoop有一個(gè)特殊的功能,它可以讀取操作目錄中/lib目錄下所包含的所有庫(kù)的jar文件,用戶可以使用此功能生成所謂的胖jar文件,胖jar文件使用maven的Maven Assembly插件
七、架構(gòu) 1.數(shù)據(jù)查找和傳輸 1)B+樹:它的葉節(jié)點(diǎn)項(xiàng)目鏈接并且有序,能夠通過(guò)主鍵對(duì)記錄進(jìn)行高效的插入、查找以及刪除,它表能為一個(gè)動(dòng)態(tài)、多層并由上下界的索引,同時(shí)要注意維護(hù)每一段所包含的鍵數(shù)目
2)LSM樹(log-structured merge-tree):輸入數(shù)據(jù)首先存儲(chǔ)在日志文件,這些文件內(nèi)的數(shù)據(jù)完全有序,當(dāng)有日志文件被修改時(shí),對(duì)應(yīng)的更新會(huì)被保存在內(nèi)存中加速查詢,修改數(shù)據(jù)文件的操作通過(guò)滾動(dòng)合并完成。
2.存儲(chǔ) 1)概覽 注:HBase主要處理兩種文件:一種是WAL文件,另一種是實(shí)際的數(shù)據(jù)文件,這兩種文件都是由HRegionServer管理
2)讀取數(shù)據(jù)流程
HRegionServer負(fù)責(zé)打開(kāi)region,并創(chuàng)建一個(gè)對(duì)應(yīng)的HRegion實(shí)例,它會(huì)為每個(gè)表的HColumnFamily創(chuàng)建一個(gè)Store實(shí)例,每個(gè)Store實(shí)例包含多個(gè)StoreFile(HFile的輕量級(jí)封裝)和一個(gè)MemStore,一個(gè)HRegionServer共享一個(gè)HLog實(shí)例
3)寫路徑
4)region拆分
5)合并 minor合并:負(fù)責(zé)重寫最后生成的幾個(gè)文件到一個(gè)更大的文件中,文件數(shù)量有hbase.hstore.compaction.min決定,默認(rèn)值是3,minor合并處理的最大文件數(shù)默認(rèn)為10,用戶可以通過(guò)hbase.hstore.compaction.max來(lái)配置 major合并:把所有文件壓縮成一個(gè)單獨(dú)的文件,在memstore被刷寫到磁盤后出發(fā)檢查,或shell命令major-compact后觸發(fā),配置相關(guān)參數(shù) hbase.hregion.majorcompaction(默認(rèn)為24小時(shí))和hbase.hregion.majorcompaction.jitter(默認(rèn)為0.2)
6)HFile 注:文件長(zhǎng)度可變,唯一固定的塊是File Info和Trailer,Trailer是指向其他快遞的指針,塊大小是由HColumnDescriptor配置的,該配置可以在創(chuàng)建表的時(shí)候由用戶指定,默認(rèn)大小時(shí)64K,每一個(gè)塊都包含一個(gè)magic頭部和一定數(shù)量的序列化的KeyValue實(shí)例
7)WAL WAL存儲(chǔ)了對(duì)數(shù)據(jù)的所有更改,實(shí)現(xiàn)了WAL的類叫HLog類,HLog類的一個(gè)特性就是跟蹤修改,通過(guò)使用序列號(hào)來(lái)實(shí)現(xiàn)
3.ZooKeeper HBase使用ZooKeeper作為其協(xié)同服務(wù)組件,其主要功能包括跟蹤region服務(wù)器、保存root region的地址等 HBase建立的znode列表,默認(rèn)為/hbase,這個(gè)znode的名稱由zookeeper.znode.parent屬性決定, 以下是znode的列表以及他們的作用 /hbase/hbaseid:包括clusterID,與存儲(chǔ)在HDFS上的hbase.id文件內(nèi)容相同。 /hbase/master:包含服務(wù)器名稱 /hbase/replication:包含副本信息 /hbase/root-region-server:包含-ROOT-region所在的region服務(wù)器的機(jī)器名,這個(gè)經(jīng)常在region定位中使用 /hbase/rs:所偶region服務(wù)器的根節(jié)點(diǎn),集群使用它來(lái)跟蹤服務(wù)器異常 /hbase/shutdown:集群的啟動(dòng)事假和關(guān)閉時(shí)間 /hbase/table:當(dāng)表被禁用,信息會(huì)被添加到這個(gè)znode之下
4.復(fù)制 HBase復(fù)制可以作為一種災(zāi)難恢復(fù)的方法,并且可以提供HBase層的高可用性 HBase復(fù)制中最基本的機(jī)構(gòu)模式是"主推送",因?yàn)槊總€(gè)region服務(wù)器都有自己的WAL,所以很容易保存現(xiàn)在正在復(fù)制的位置 注:參與復(fù)制的集群可以不相等,主機(jī)群會(huì)通過(guò)隨機(jī)分配盡量均衡從集群的負(fù)載
1)常規(guī)處理 客戶端發(fā)送Put、Delete、或Increment到region服務(wù)器,這些請(qǐng)求包含的鍵值對(duì)會(huì)被region服務(wù)器轉(zhuǎn)化為WALEdit,同時(shí)WALEdit會(huì)被復(fù)制程序檢查,并以列族為單元復(fù)制數(shù)據(jù)。修改被添加到WAL中,并把實(shí)際數(shù)據(jù)添加到Memstore。 2)沒(méi)有反饋的從集群 如果從集群的region服務(wù)器沒(méi)有響應(yīng)rpc請(qǐng)求,主集群的region服務(wù)器將會(huì)睡眠并按照配置的次數(shù)重試。如果從集群的region服務(wù)器還是不可用,主機(jī)全會(huì)重新選擇一臺(tái)其他的機(jī)器來(lái)提交修改 3)挑選要復(fù)制的目標(biāo)集群 主集群的region服務(wù)器連接從集群的ZooKeeper群組,然后掃描/hbase/rs目錄來(lái)發(fā)現(xiàn)所有可用的并隨機(jī)選擇一部分服務(wù)器來(lái)復(fù)制數(shù)據(jù)(默認(rèn)是10%)
八、高級(jí)用法 1.rowkey設(shè)計(jì) 1)高表與寬表 HBase中的表可以設(shè)計(jì)為高表和寬表,前者指表中列少兒行多,后者則正好相反。用戶應(yīng)當(dāng)盡量將需要查詢的維度或信息存儲(chǔ)在行健中,應(yīng)為用它篩選的效率最高 此外,HBase只能按行分片,因此高表更有優(yōu)勢(shì)
2)時(shí)間序列:當(dāng)處理流式事件時(shí),最常用的就是按時(shí)間序列組織數(shù)據(jù),這些數(shù)據(jù)會(huì)被有序的存儲(chǔ)在一個(gè)特定的范圍內(nèi),到時(shí)系統(tǒng)產(chǎn)生讀寫熱點(diǎn),解決這個(gè)問(wèn)題的方法就是想辦法將數(shù)據(jù)分散到所有的region服務(wù)器上,有很多中方法,例如在行鍵前價(jià)格,通常情況下如下選擇
時(shí)間順序關(guān)系 每個(gè)列族下的列可以作為輔助索引單獨(dú)進(jìn)行排序,主要內(nèi)容在主要的列族下,索引放在另外一個(gè)列族下,為了編碼創(chuàng)建太多的列族,可以把所有輔助索引存儲(chǔ)在有一個(gè)單獨(dú)的列族下,同時(shí)列鍵的最左端使用索引ID這個(gè)前綴來(lái)表示不同的順序
2.輔助索引 輔助索引存儲(chǔ)了新坐標(biāo)和現(xiàn)有坐標(biāo)之間的映射關(guān)系,一些為可行的解決方案 由客戶端管理索引: 把責(zé)任完全轉(zhuǎn)移到應(yīng)用層的典型做法是把一個(gè)數(shù)據(jù)表和一個(gè)查找/映射表結(jié)合起來(lái),每當(dāng)程序?qū)憯?shù)據(jù)表的時(shí)候,它也同時(shí)更新映射表(輔助索引表)。讀數(shù)據(jù)時(shí)可以直接在主表進(jìn)行查詢,從輔助索引表中先查找原表的行鍵,再在原表中讀取實(shí)際數(shù)據(jù)。優(yōu)點(diǎn):用戶可以按照需求設(shè)計(jì)映射表。缺點(diǎn):Hbase不能保證跨行操作的原子性 用戶可以自由設(shè)計(jì)主索引和輔助索引之間的映射關(guān)系時(shí),必須接受的缺點(diǎn)是用戶需要實(shí)現(xiàn)所有存儲(chǔ)和查找數(shù)據(jù)必需的方法
帶索引的事務(wù)型HBase 開(kāi)源的ITHBase,擴(kuò)展了HBase,最核心的擴(kuò)展是增加了保證所有輔助索引,提供了一個(gè)IndexedTableDescriptor,提供了數(shù)據(jù)表的輔助索引操作支持,大多數(shù)類被添加了索引支持功能的類替換了
帶索引的HBase IHBase是完全在內(nèi)存中維護(hù)索引,索引永遠(yuǎn)都是同步的,不需要額外的事務(wù)控制,索引的定義由IdxIndexDescriptor類完成
3.搜索集成 使用任意關(guān)鍵字來(lái)搜索數(shù)據(jù),滿足這種需要往往是集成一個(gè)完整的搜索引擎 Lucene:獨(dú)立于HBase使用的Lucene或其他派生類的解決方案可以通過(guò)Mapreduce建立索引。 HBasene:選擇的方法是直接在HBase內(nèi)部建立搜索索引,同時(shí)為用戶提供Lucene的API,它把每個(gè)文檔的字段、詞存儲(chǔ)在一個(gè)單獨(dú)的行,同時(shí)包含這個(gè)詞的文檔儲(chǔ)存在這一行的列中
九、監(jiān)控集群 1.監(jiān)控框架 每個(gè)HBase進(jìn)程都會(huì)提供一系列監(jiān)控指標(biāo),這些監(jiān)控指標(biāo)可以被各種監(jiān)控API和工具使用,包括JMX和Ganglia。每種服務(wù)器都有多組監(jiān)控指標(biāo),這些監(jiān)控指標(biāo)按子系統(tǒng)分組并隸屬于一種服務(wù)器 HBase使用Hadoop的監(jiān)控框架,并繼承了其所有類和特性,這個(gè)框架基于MetricsContext接口來(lái)處理監(jiān)控?cái)?shù)據(jù)點(diǎn)的生成,并使用這些數(shù)據(jù)點(diǎn)監(jiān)控和繪圖 1)可用的實(shí)現(xiàn)列表: GangliaContext:用來(lái)推送監(jiān)控指標(biāo)到Ganglia FileContext:將監(jiān)控指標(biāo)寫入磁盤上一個(gè)文件中 TimeStampingFileContext:將監(jiān)控指標(biāo)寫入磁盤上一個(gè)文件中,但是為每個(gè)監(jiān)控指標(biāo)添加一個(gè)時(shí)間戳前綴 CompositeContext:允許為監(jiān)控指標(biāo)生成不止一個(gè)上下文 NullContext:監(jiān)控指標(biāo)框架的關(guān)閉選項(xiàng),使用這個(gè)上下文時(shí),不生成也不聚合監(jiān)控指標(biāo) NullContextWithUpdateThread:不生成任何監(jiān)控指標(biāo),但是啟動(dòng)聚合統(tǒng)計(jì)線程。這種上下文在通過(guò)JMX檢索監(jiān)控指標(biāo)時(shí)使用
多重監(jiān)控指標(biāo)使用MetricsRecored分組,來(lái)描述一個(gè)具體的子系統(tǒng)。HBase使用這些組分別來(lái)保存master、region機(jī)器,以及其他服務(wù)器的統(tǒng)計(jì)信息,每個(gè)組都有唯一的名字:<context-name>.<record-name>.<metrics-name>。上下文有內(nèi)置的定時(shí)器來(lái)觸發(fā)并將監(jiān)控指標(biāo)推送至目標(biāo)
2)各種指標(biāo)類型: 整型值:(IV) 長(zhǎng)整型值:(LV) 速率(R):一個(gè)代表速率的浮點(diǎn)型值,可以是每秒操作或者消息數(shù) 字符串:存儲(chǔ)靜態(tài)的,基于文本的信息。并用來(lái)報(bào)告HBase版本信息和構(gòu)建時(shí)間 時(shí)間變化整型(TVI):上下文會(huì)維護(hù)一個(gè)單調(diào)遞增累加計(jì)數(shù)器??蚣苁褂眠@個(gè)方法對(duì)各種消息進(jìn)行技術(shù) 時(shí)間變化長(zhǎng)整型(TVL):用于增速較快的計(jì)數(shù)器 時(shí)間變化率(TVR):需要追蹤操作數(shù)或消息的數(shù)量,以及完成操作所用的時(shí)間,通常用來(lái)計(jì)算一次操作完成的平均時(shí)間 持續(xù)型時(shí)間變化率(PTVR):添加了對(duì)持續(xù)的周期性的監(jiān)控指標(biāo)的必要的支持。 3)master提供的監(jiān)控指標(biāo)
4)region服務(wù)器監(jiān)控指標(biāo): 塊緩存監(jiān)控指標(biāo) 塊緩存用來(lái)保存底層HFile從HDFS讀取的存儲(chǔ)塊。count(LV)監(jiān)控指標(biāo)反映了當(dāng)前緩存中保存的塊數(shù)目,size(LV)監(jiān)控指標(biāo)時(shí)占用java堆空間大小,free(LV)監(jiān)控指標(biāo)時(shí)堆空間為緩存保留的可用空間,evicted(LV)反映了命中緩存總數(shù)與請(qǐng)求緩存總數(shù)的關(guān)系 塊緩存追蹤追蹤緩存命中hit(LV)和緩存失效miss(LV)的數(shù)目,以及命中率hit radio(LV),其反映了命中緩存總數(shù)與請(qǐng)求緩存總數(shù)的關(guān)系。所有讀操作使用緩存,不管用戶是否制定過(guò)將使用的塊保留在緩存中。使用setCacheBlocks()僅僅影響塊的保留策略 合并監(jiān)控 compaction size(PTVR)和compaction time(PTVR)分別代表需要合并的存儲(chǔ)文件總大小和操作花費(fèi)時(shí)間 compaction queue size:用來(lái)監(jiān)測(cè)一個(gè)region服務(wù)器有多少文件當(dāng)前正在排隊(duì)等待合并
memstore監(jiān)控指標(biāo) memstore size MB(IV):服務(wù)器上所有memstore總共占用的堆大小 flush queue zie(IV):將要被刷寫的region的數(shù)目
存儲(chǔ)監(jiān)控指標(biāo): store files(IV):所有存儲(chǔ)文件的數(shù)目 store file index MB(IV):所有存儲(chǔ)文件的塊索引和元數(shù)據(jù)的總和大小
I/O監(jiān)控指標(biāo): fs read latency(TVR):文件系統(tǒng)的讀延遲 fs write latency:寫延遲 fs sync latency:統(tǒng)計(jì)了預(yù)寫日志記錄同步到文件系統(tǒng)的延遲
RPC監(jiān)控指標(biāo) Ganglia 組成: Ganglia監(jiān)控守護(hù)進(jìn)程(gmond):監(jiān)控守護(hù)進(jìn)程需要在每臺(tái)需要監(jiān)控的機(jī)器上運(yùn)行,它搜集本地?cái)?shù)據(jù),準(zhǔn)備統(tǒng)計(jì),然后被其他系統(tǒng)拉取。通過(guò)單一或組播方網(wǎng)絡(luò)消息傳播的主機(jī)變化情況,使用組播方式,每個(gè)監(jiān)控守護(hù)進(jìn)程可以獲取集群完整狀態(tài),所有的服務(wù)器擁有同樣的組播地址 Ganglia元數(shù)據(jù)守護(hù)進(jìn)程(gmetad):元數(shù)據(jù)守護(hù)進(jìn)程安裝在一個(gè)中心節(jié)點(diǎn)上,作為整個(gè)集群的管理節(jié)點(diǎn)。元數(shù)據(jù)守護(hù)進(jìn)程從一個(gè)或多個(gè)監(jiān)控守護(hù)進(jìn)程拉去數(shù)據(jù)來(lái)獲取整個(gè)集群的狀態(tài),然后使用RDTool將這些信息存放在一個(gè)用于輪詢的時(shí)間序列數(shù)據(jù)庫(kù)中。 GangliaPHP:展示統(tǒng)計(jì)信息
十、性能優(yōu)化 1.垃圾回收優(yōu)化 垃圾回收時(shí)master通常不會(huì)產(chǎn)生問(wèn)題,只需要添加到region服務(wù)器的啟動(dòng)參數(shù)中。 用戶可以通過(guò)向hbase-env.sh配置文件中添加HBASE_OPTS或者HBASE_REGIONSERVER_OPTS變量來(lái)設(shè)置垃圾回收的相關(guān)選項(xiàng)。后者僅影響region服務(wù)器進(jìn)程,也是推薦的修改方式 指定新生代的方式:-XX:MaxNewSize=128m -XX:NewSize=128m或-Xmn128m 注意:默認(rèn)值對(duì)于多數(shù)region服務(wù)器面對(duì)的負(fù)載還是太小,所以她必須增大
建議在JRE日志中輸入垃圾回收的詳細(xì)信息,通過(guò)添加以下JRE選項(xiàng): -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$HBASE-HOME/logs/gc-hbase.log 該日志不會(huì)按日期定時(shí)滾動(dòng),需要手動(dòng)處理(例如:使用基于crontab的每日滾動(dòng)轉(zhuǎn)存任務(wù))
通過(guò)不同的JRE參數(shù)來(lái)指定不同的垃圾回收實(shí)現(xiàn)策略,推薦的值是: -XX:+UseParNewGC and -XX:+UseConcMarkSweepGC UseParNewGC:停止運(yùn)行java進(jìn)程二期清空年輕代堆 ConcMarkSweepGC:不停止java進(jìn)程的情況下異步并行的完成工作
2.預(yù)拆分region 管理接口中createTable()方法或shell中的create命令可以接受列表形式提供的拆分行健作為參數(shù)
3.負(fù)載均衡: master有一個(gè)內(nèi)置的叫做均衡器的特性,在默認(rèn)的情況下,均衡器每五分鐘運(yùn)行一次,可以通過(guò)hbase.balancer.period屬性設(shè)置 均衡器有一個(gè)可以限制自身運(yùn)行時(shí)間的上限,用戶可以通過(guò)hbase.balance.max.balancing屬性來(lái)設(shè)置,默認(rèn)為均衡器間隔周期的一半
4.合并region HBase集成了一個(gè)工具能夠讓用戶在集群沒(méi)有工作時(shí)河北那個(gè)兩個(gè)相鄰的region,工具為org.apache.hadoop.hbase.util.Merge
5.客戶端API:最佳實(shí)踐 1)禁止自動(dòng)刷寫:當(dāng)有大量的寫入操作時(shí),使用setAutoFlush(false)方法,確認(rèn)HTable自動(dòng)刷寫的特性已經(jīng)關(guān)閉,如果禁用了自動(dòng)刷寫,add(Put)操作指導(dǎo)寫緩沖區(qū)被填滿時(shí)才會(huì)被送出,可以調(diào)用HTable的flushCommits()方法顯式刷寫數(shù)據(jù),調(diào)用HTable的close()也會(huì)隱式調(diào)用flushCommits() 2)使用掃面緩存:如果HBase被用作一個(gè)MapReduce作業(yè)的輸入源,請(qǐng)最好將作為MapReduce作業(yè)輸入掃描器實(shí)例的緩存用setCaching()方法設(shè)置為比默認(rèn)值1大得多的值,使用默認(rèn)值意味著map任務(wù)處理每條記錄都請(qǐng)求region服務(wù)器 3)限定掃描范圍 當(dāng)Scan用來(lái)處理大量行時(shí)注意哪些屬性被選中了,從而限制掃描范圍 4)關(guān)閉ResultScanner 如果用戶忘記關(guān)閉由HTable.getScanner()返回的ResultScanner實(shí)例,則可能對(duì)服務(wù)器端造成影響,一定要在try/catche的finally塊中關(guān)閉ResultScanner 5)塊緩存用法 Scan實(shí)例通過(guò)setCacheBlock()方法來(lái)設(shè)置使用region服務(wù)器中的塊緩存,如果MapReduce作業(yè)中使用掃描,這個(gè)方法應(yīng)當(dāng)被設(shè)為false,對(duì)于那些頻繁訪問(wèn)行的行,建議使用塊緩存 6)關(guān)閉Put上WAL 提高吞吐量方式,使用Put的writeToWAL(false)來(lái)關(guān)閉WAL,不過(guò)一旦region服務(wù)器故障就會(huì)丟失數(shù)據(jù)
6.配置 1)減少Zookeeper超時(shí) 默認(rèn)在region服務(wù)器和ZooKeeper集群之間的超時(shí)時(shí)間是3分鐘,通過(guò)zookeeper.session.timeout屬性設(shè)置,在改變值之前,確認(rèn)用戶服務(wù)器上JVM的垃圾回收機(jī)制是受控的 2)增加處理線程 hbase.regionserver.handler.count屬性定義了響應(yīng)外部用戶訪問(wèn)數(shù)據(jù)表請(qǐng)求的線程數(shù),默認(rèn)值10有些偏小,將這個(gè)值設(shè)置的高也有可能產(chǎn)生問(wèn)題,并發(fā)的寫請(qǐng)求造成壓力 3)增加堆大小 如果用戶使用更好的服務(wù)器,可以給HBase分配8G內(nèi)存或更大,用戶可以在hbase-env.sh文件中調(diào)整HBASE_HEAPSIZE的設(shè)置,master會(huì)默認(rèn)1GB的堆運(yùn)行,region服務(wù)器則會(huì)按照用戶單獨(dú)指定的堆空間運(yùn)行 4)啟動(dòng)數(shù)據(jù)壓縮 用戶應(yīng)當(dāng)為存儲(chǔ)文件啟動(dòng)壓縮,尤其推薦使用Snappy或LZO壓縮 5)增加region大小 默認(rèn)region大小為256M,用戶可以增加其大小,但是該參數(shù)的大小要仔細(xì)評(píng)估 6)調(diào)整塊緩存大小 控制堆中塊緩存大小的屬性是一個(gè)浮動(dòng)點(diǎn)數(shù)類型的百分比,默認(rèn)值是20%,可以通過(guò)perf.hfile.block.cache.size屬性改變這個(gè)值,看看是否存在許多塊被換出的情況,如果存在,則可以考慮增加塊緩存的大小。用戶負(fù)載大多數(shù)為讀請(qǐng)求是另一個(gè)增加緩存大小的原因。 7)調(diào)整memstore限制 內(nèi)存存儲(chǔ)占用的堆大小用hbase.regionserver.global.memstore.upperLimit屬性來(lái)配置,默認(rèn)值為40%,此外hbase.regionserver.global.memstore.lowerLimit屬性(默認(rèn)為35%)用戶控制當(dāng)服務(wù)器清空memstore之后剩余的大小,當(dāng)用戶主要在處理讀請(qǐng)求時(shí),可以考慮通知減少memstore的上線限來(lái)增加塊緩存的空間 8)增加阻塞時(shí)存儲(chǔ)文件數(shù)目 這個(gè)值通過(guò)hbase.hstore.blockingStoreFiles屬性來(lái)設(shè)置的,它決定了當(dāng)存儲(chǔ)文件的數(shù)據(jù)達(dá)到閾值時(shí),更新操作將會(huì)被阻塞,當(dāng)應(yīng)用經(jīng)常遇到大負(fù)載的突發(fā)寫請(qǐng)求時(shí),用戶可以稍微增加這個(gè)值來(lái)應(yīng)對(duì)這種情況,其默認(rèn)值是7 9)增加阻塞倍率 屬性hbase.hregion.memstore.block.multiplier的默認(rèn)值是2,當(dāng)memstore達(dá)到屬性multiplier乘以flush的大小限制時(shí)會(huì)阻止進(jìn)一步更新 10)減少最大日志文件的限制 設(shè)置hbase.regionserver.maxlogs屬性使得用戶能夠控制基于磁盤的WAL文件數(shù)目,進(jìn)而控制刷寫頻率,該參數(shù)的默認(rèn)值是32
負(fù)載測(cè)試 Hbase有自己的性能評(píng)價(jià)工具,名為PE,使用命令:hbase org.apache.hadoop.hbase.PerformanceEvaluation YCSB:Yahoo的云服務(wù)基準(zhǔn)測(cè)試系統(tǒng)也可用于對(duì)HBase集群進(jìn)行超負(fù)荷測(cè)試
十一、集群管理 1.運(yùn)維任務(wù) 1)減少節(jié)點(diǎn) 使用hbase-daemon.sh stop regionserver停止region服務(wù)器 如果關(guān)閉節(jié)點(diǎn)時(shí)負(fù)載均衡還在運(yùn)行,則在復(fù)雜均衡和master恢復(fù)下線的region服務(wù)器之間可能存在競(jìng)爭(zhēng),要避免這種情況,使用shell命令:balance_switch false禁用負(fù)載均衡 HBase0.90.2之后引入了一種可以讓region服務(wù)器逐漸減少其負(fù)載并停止服務(wù)的方法,使用graceful_stop.sh腳本來(lái)完成 用戶也可以用graceful_stop.sh腳本來(lái)重啟服務(wù)器,并將之前屬于它的region移回原味(用戶可能選擇后者以保持?jǐn)?shù)據(jù)的局部性),最簡(jiǎn)單的滾動(dòng)重啟可以使用如下命令(確認(rèn)之前已經(jīng)關(guān)閉負(fù)載均衡): for i in 'cat conf/regionservers|sort; do ./bin/graceful_stop.sh --restart --reload --debug $i; done $> /tmp/log.txt &
2.數(shù)據(jù)任務(wù) 1)導(dǎo)入/導(dǎo)出 HBase發(fā)布了一些有用的工具,其中兩個(gè)支持導(dǎo)入和導(dǎo)出MapReduce作業(yè)。這些工具包含在HBase的JAR文件中,用戶可以通過(guò)hadoop jar命令來(lái)獲得這些工具,使用格式:hadoop jar $HBASE_HOME/HBASE-0.91.0-SNAPSHOT.jar <command>
一致性模型:數(shù)據(jù)庫(kù)必須保證每一步操作都是從一致的狀態(tài)到下一個(gè)一致的狀態(tài) 按照嚴(yán)格強(qiáng)度劃分: 嚴(yán)格一致性:數(shù)據(jù)的變化是原子的,一經(jīng)改變及時(shí)生效 順序一致性:每個(gè)客戶端看到的數(shù)據(jù)依照它們操作執(zhí)行的順序而變化 因果一致性:客戶端以因果關(guān)系順序觀察到數(shù)據(jù)的改變 最終一致性:在沒(méi)有更新數(shù)據(jù)的一段時(shí)間里,系統(tǒng)將通過(guò)廣播早證副本之間的數(shù)據(jù)一致性 弱一致性:沒(méi)有做出保證的情況下,所有的更新會(huì)通過(guò)廣播的形式傳遞,展現(xiàn)給不同客戶端的數(shù)據(jù)順序可能是不一樣
阻抗匹配:為一個(gè)給定問(wèn)題找到一個(gè)理想的解決方案,除了使用通用的解決方案,還應(yīng)該知道有什么可用的解決方案,從而找到最適合解決該問(wèn)題的系統(tǒng)
2.表、行、列和單元格 最基本的單位是列,一列或多列形成一行,并由唯一的行健(row key)來(lái)確定存儲(chǔ),一個(gè)表有若干行,其中每列可能有多個(gè)版本,在每個(gè)單元格中存儲(chǔ)了不同的值 一行由若干列組成,若干列又構(gòu)成了一個(gè)列族,一個(gè)列族的所有列存儲(chǔ)在同一個(gè)底層文件中,這個(gè)存儲(chǔ)文件叫做HFile,列族需要在表創(chuàng)建的時(shí)候就定義好,常見(jiàn)的引用列的格式為family:qualifer,列族的數(shù)量有限制,但是列的數(shù)量沒(méi)有限制,列值也沒(méi)有長(zhǎng)度和類型的限制 在Hbase中空值是沒(méi)有任何消耗的,它們不占用任何的存儲(chǔ)空間 每列或每個(gè)單元格的值都具有時(shí)間戳,默認(rèn)由系統(tǒng)指定,也可以由用戶顯示設(shè)置 BigTable和Hbase的典型使用場(chǎng)景是webtable,存儲(chǔ)從互聯(lián)網(wǎng)中抓取的網(wǎng)頁(yè) 行數(shù)據(jù)的存儲(chǔ)操作都是原子的,可以讀寫任意數(shù)目的列,目前還不支持跨行事務(wù)和跨表事務(wù)
3.自動(dòng)分區(qū) Hbase中擴(kuò)展和負(fù)載均衡的基本單元稱為region,region本質(zhì)上是以行健排序的連續(xù)存儲(chǔ)的區(qū)間
4.存儲(chǔ)API API提供了建表、刪表、增加列族和刪除列族的操作,同時(shí)還提供了修改表和列族元數(shù)據(jù)的功能 scanAPI提供了高效遍歷某個(gè)范圍的行的功能 在服務(wù)器的地址空間中執(zhí)行來(lái)自客戶端的代碼,支持這種功能的服務(wù)器框架叫做協(xié)處理器(coprocessor)
5.實(shí)現(xiàn) 每次更新數(shù)據(jù)時(shí),都會(huì)先將數(shù)據(jù)記錄在提交日志上(commit log)中,在Hbase中這叫預(yù)寫日志(write-ahead log,WAL),然后才將這些數(shù)據(jù)寫入內(nèi)存中的memstore中,到超過(guò)給定的最大值值,就寫到磁盤的HFile文件,HFile是不可被改變的 合并HFile機(jī)制 minor合并:將多個(gè)小文件(默認(rèn)最小3個(gè),最大10個(gè))重寫到數(shù)據(jù)較少的大文件中,每個(gè)HFile都是經(jīng)過(guò)歸類的,所以合并的速度很快,只受磁盤IO的影響 major合并:將一個(gè)region中一個(gè)列族的若干個(gè)HFile重寫到一個(gè)新的HFile中,major合并能掃描所有的鍵值對(duì),順序重寫全部的數(shù)據(jù)
二、客戶端API:基礎(chǔ)知識(shí) 1.概述 Hbase主要的客戶端接口是有org.apache.hadoop.hbase.client包中的HTable提供的HTable類提供的,通過(guò)這個(gè)類用戶可以向Hbase存儲(chǔ)和檢索數(shù)據(jù) 所有修改數(shù)據(jù)的操作都保證了行級(jí)別的原子性 創(chuàng)建HTable實(shí)例是有代價(jià)的,每個(gè)實(shí)例都需要掃描.META.表,以檢查該表是否存在,是否可用,以及一些其他操作,因此推薦用戶在每個(gè)線程(在開(kāi)始時(shí))只創(chuàng)建一次HTable實(shí)例,而后在客戶端應(yīng)用的生存期內(nèi)復(fù)用這個(gè)對(duì)象,如果用戶需要使用多個(gè)HTable實(shí)例,應(yīng)考慮使用HTablePool類 Hable(Configuration conf,"tableName")
2.CRUD操作 2.CRUD操作 2.1 put方法:向Hbase存儲(chǔ)數(shù)據(jù) 1)調(diào)用HTable的put方法格式: void put(Put put)或void put(List<put> puts) Put對(duì)象的構(gòu)造方法如下 創(chuàng)建Put實(shí)例之后,就可以使用add方法 向該實(shí)例添加數(shù)據(jù)了,每一次調(diào)用add()都可以特定的添加一列數(shù)據(jù),如果再加上一個(gè)時(shí)間戳選項(xiàng),就能形成一個(gè)數(shù)據(jù)單元格。每個(gè)KeyValue實(shí)例包含器完成地址(行健、列族、列以及時(shí)間戳)和實(shí)際數(shù)據(jù),KeyValue是Hbase在存儲(chǔ)架構(gòu)中最底層的類 可以使用如下方法檢查是否存在特定的單元格,而不需要遍歷整個(gè)集合 通過(guò)客戶端訪問(wèn)配置文件 當(dāng)你調(diào)用任何一個(gè)靜態(tài)create()方法時(shí),代碼會(huì)嘗試使用當(dāng)前的java classpath來(lái)載入兩個(gè)配置文件hbase-default.xml和hbase-site.xml
Hbase的一個(gè)特殊功能是能為一個(gè)單元格存儲(chǔ)多個(gè)版本的數(shù)據(jù),這個(gè)版本使用一個(gè)時(shí)間戳,必須確保所有服務(wù)器的時(shí)間都是正確的,并且相互之間是同步的,默認(rèn)情況下Hbase會(huì)保留3個(gè)版本的數(shù)據(jù) 若需要頻繁的修改某些行,用戶有必要?jiǎng)?chuàng)建一個(gè)RowLock實(shí)例來(lái)防止其他用戶訪問(wèn)這些行
2)KeyValue類 數(shù)據(jù)和坐標(biāo)都是以java的byte[]形式存儲(chǔ)的,使用這種類型的目的是允許存儲(chǔ)任意類型的數(shù)據(jù)
3)客戶端的寫緩沖區(qū) 每一個(gè)put操作實(shí)際上都是一個(gè)RPC操作,它將客戶端數(shù)據(jù)傳送到服務(wù)器后返回,這只適合小數(shù)據(jù)量的操作,Hbase的API配備了一個(gè)客戶端的寫緩沖區(qū)(write buffer),緩沖區(qū)負(fù)責(zé)收集put操作,然后調(diào)用RPC操作一次性將put送往服務(wù)器,全局交換機(jī)制控制著該緩沖區(qū)是否在使用,其方法如下 void setAutoFlush(boolean autoFlush) 默認(rèn)情況下,客戶端緩沖區(qū)是禁用的,可以通過(guò)將autoflush設(shè)置為false來(lái)激活緩沖區(qū),通過(guò)setBufferSize(long size)來(lái)配置客戶端寫緩沖區(qū)的大小,默認(rèn)大小是2M,為每一個(gè)用戶創(chuàng)建的HTable實(shí)例都設(shè)置緩沖器大小十分麻煩,可以在hbase-site.xml中添加一個(gè)較大的預(yù)設(shè)值,配置如下 <property> <name>hbase.client.write.value</name> <value>20971520</value> </property>
當(dāng)需要強(qiáng)制把數(shù)據(jù)寫到服務(wù)器端時(shí),用flushCommit()函數(shù) 隱式刷寫:在用戶調(diào)用put()或setBufferSize()時(shí)觸發(fā),這兩個(gè)方法都會(huì)將目前占用的緩沖區(qū)大小和用戶配置的緩沖區(qū)大小進(jìn)行比較,此外調(diào)用HTable的close()也會(huì)無(wú)條件地隱式刷寫 用戶可以通過(guò)訪問(wèn)ArrayList<Put> getWriteBuffer()來(lái)訪問(wèn)客戶端寫緩沖區(qū)的內(nèi)容 如果用戶只存儲(chǔ)大單元格,那么客戶端緩沖區(qū)的作用就不大了 4)Put列表 調(diào)用void put(List<put> puts)時(shí),客戶端先把所有的Put實(shí)例插入到本地寫緩沖區(qū)中,然后隱式的調(diào)用flushCache(),如果其中有失敗的Put實(shí)例(有些檢查是在客戶端完成的,如確認(rèn)Put實(shí)例的內(nèi)容是否為null或是否指定了列),那么后面的Put實(shí)例不會(huì)被添加到緩沖區(qū),也不會(huì)觸發(fā)刷寫命令,當(dāng)使用基于列表的Put調(diào)用時(shí),用戶需要特別注意:用戶無(wú)法控制服務(wù)器執(zhí)行put的順序,如果要保證寫入的順序,需要小心地使用這個(gè)操作。
5)原子性操作compare-and-set 有一種特別的put調(diào)用,其能保證自身操作的原子性:checkAndPut(row,family,qualifier,value,Put put),這種有原子性的操作經(jīng)常被用于賬戶結(jié)余,狀態(tài)轉(zhuǎn)換或數(shù)據(jù)處理等場(chǎng)景 有一種特別的檢查通過(guò)checkAndPut()調(diào)用來(lái)完成,即只有在另外一個(gè)值不存在的情況下,才執(zhí)行這個(gè)修改,要執(zhí)行這種操作只需要將參數(shù)value設(shè)置為null Hbase提供的compare-and-set操作,只能檢查和修改同一行數(shù)據(jù)
2.2 get方法:客戶端獲取已存儲(chǔ)數(shù)據(jù)的方法 Result get(Get get); 1)單行Get 構(gòu)造Get實(shí)例: Get(rowkey) Get(rowkey,RowLock rowLock) 可以通過(guò)多種標(biāo)準(zhǔn)篩選目標(biāo)數(shù)據(jù): Get addFamily(family):只能取得一個(gè)指定的列族 Get addColumn(family,qualifier):獲取指定的列 Get setTimeRange(long minStamp,long masStamp)、 Get setTimeStamp(long timeStamp) Get setMaxVersions(int maxVersions)
2)result類 get()返回的結(jié)果包含所有匹配的單元格數(shù)據(jù),被封裝成一個(gè)Result類 常用方法: byte[] getValue(family,qualifier):取得特定單元格的值 byte[] value():返回第一列對(duì)應(yīng)的最新單元格的值 byte[] getRow():返回行健 int size():檢查是否有對(duì)應(yīng)的記錄 boolean isEmpty():檢查是否有對(duì)應(yīng)的記錄 KeyValue[] raw() List<KeyValue> list():用戶可以方便的迭代數(shù)據(jù) List<KeyValue> getColumn(family,qualifier) KeyValue getColumnLatest(family,qualifier) boolean containsColumn(family,qualifier) NavigableMap<byte[],NavigableMap[],NavigableMap<Long,byte[]>>> getMap():把請(qǐng)求返回的內(nèi)容都裝入一個(gè)Map類實(shí)例中,可以遍歷所有結(jié)果
3)get列表 Result[] get(List<Get> gets); boolean exists(Get get):查看存儲(chǔ)的數(shù)據(jù)是否存在 getRowOrBefore(row,family):
2.3 刪除方法 1)單行刪除 void delete(Delete delete) Delete實(shí)例構(gòu)造方法 Delete(rowkey) Delete(rowkey,long timestamp,RowLock rowLock) 常用方法 Delete deleteFamily(family[,long timestamp]) Delete deleteColumns(family,qualifier[,long timestamp]):沒(méi)指定timestamp,則刪除所有版本 Delete deleteColumn(family,qualifier[,long timestamp]):沒(méi)指定timestamp,則刪除最新版本
2)Delete的列表 void delete(List<Delete> deletes)
3)原子性操作compare-and-delete boolean checkAndDelete(row,qualifier,value,Delete delete)
2.4批處理操作 事實(shí)上許多基于列表的操作都是基于batch()方法是實(shí)現(xiàn)的。 方法: void batch(List<Row> actions,Object[] results) Object[] batch(List<Row> actions) 注:不可以將針對(duì)同一行數(shù)據(jù)的Put和Delete操作放在同一個(gè)批處理請(qǐng)求中 Row是Put、Get、Delete類的父類 當(dāng)用戶使用batch()功能時(shí),Put實(shí)例不會(huì)被客戶端寫入緩沖區(qū)中緩沖,batch()請(qǐng)求是同步的,會(huì)把操作直接發(fā)送給服務(wù)器 兩種方法相同點(diǎn): get、put、delete操作都支持,如果執(zhí)行時(shí)出現(xiàn)問(wèn)題,客戶端將拋出異常并報(bào)告問(wèn)題,都不適用客戶端的寫緩沖區(qū) 不同點(diǎn): void batch(acitons,results):能訪問(wèn)成功操作的結(jié)果,同時(shí)也可以獲取遠(yuǎn)程失敗的異常 Object[] batch(actions):只返回客戶端異常,不能訪問(wèn)程序執(zhí)行中的部分結(jié)果 注:在檢查結(jié)果之前,所有的批處理操作都已經(jīng)執(zhí)行了:即使用戶收到異常,其他的操作也都已經(jīng)執(zhí)行了 批量處理可以感知暫時(shí)性錯(cuò)誤(如NoServingRegionException)會(huì)多次重試這個(gè)操作,用戶可以通過(guò)調(diào)整hbase.client.retries.number配置項(xiàng)(默認(rèn)為10)來(lái)增加或減少重試次數(shù)
2.5 行鎖 region服務(wù)器提供一個(gè)行鎖的特性,保證了只有一個(gè)客戶端能獲取一行的數(shù)據(jù)相應(yīng)的鎖,同時(shí)對(duì)該行進(jìn)行修改。用戶應(yīng)該盡可能的避免使用行鎖,如果必須使用,那么一定要節(jié)約占用鎖的時(shí)間 Get不需要鎖:服務(wù)器應(yīng)用了一個(gè)多版本的并發(fā)控制機(jī)制來(lái)保證行級(jí)讀操作,只有當(dāng)一個(gè)變動(dòng)被應(yīng)用到整個(gè)行之后,客戶端才能讀出這個(gè)改動(dòng),當(dāng)改動(dòng)進(jìn)行中時(shí),所有的客戶端讀取到的數(shù)據(jù)都是將是所有列以前的版本
2.6 掃描 類似于數(shù)據(jù)庫(kù)中的游標(biāo) ResultScanner getScanner(Scan scan) ResultScanner getScanner(family) ResultScanner getScanner(family,qualifier) scan類的構(gòu)造器 Scan() Scan(startRow,Filter filter) Scan(startRow) Scan(startRow,stopRow) 注:如果用戶只需要數(shù)據(jù)的子集,那么限制掃面的范圍就能發(fā)揮Hbase的優(yōu)勢(shì),如果不讀取整個(gè)列族,那么整個(gè)列族的文件都不會(huì)讀取,這就是列族存儲(chǔ)架構(gòu)的優(yōu)勢(shì) 1)ResultScanner類 掃描操作不會(huì)通過(guò)一次RPC請(qǐng)求返回所有匹配的行,而是以"行"為單位進(jìn)行返回 Result next() Result[] next(int nbRows) void close() 要確保盡早釋放掃描器實(shí)例,當(dāng)使用完ResultScanner之后應(yīng)調(diào)用它的close()方法,釋放所有由掃描器控制的資源 就像行級(jí)鎖一樣,掃描器也使用同樣的租約超時(shí)限制,保護(hù)其不被時(shí)效的客戶端阻塞太久,通過(guò)如下配置 <property> <name>hbase.regionserver.lease.period</name> <value>120000</value> </property> 2)緩存與批量處理 如果一次RPC請(qǐng)求可以返回多行數(shù)據(jù),這樣使用掃描器更有意義,可以由掃描器緩存實(shí)現(xiàn),默認(rèn)情況下,這個(gè)緩存是關(guān)閉的??梢詮膬蓚€(gè)層面打開(kāi)它 在表的層面,這個(gè)表的所有掃描器實(shí)例的緩存都會(huì)生效,用戶使用一下的Htable方法設(shè)置表級(jí)的掃描器緩存: void setScannerCaching(int scannerCaching), int getScannerCaching():默認(rèn)是1 在掃描器層面,這樣只會(huì)影響當(dāng)前的掃描實(shí)例,用戶使用一下的Scan類的方法設(shè)置掃描器級(jí)的掃描器緩存: void setCaching(int scannerCaching) int getCaching():默認(rèn)是1 此外用戶可以修改整個(gè)集群的配置 <property> <name>hbase.client.scanner.caching</name> <value>10</value> </property> 這樣所有scan的實(shí)例的掃描器緩存就都被設(shè)置為10了 注:當(dāng)數(shù)據(jù)量非常大的行,可能超過(guò)客戶端進(jìn)程的內(nèi)存容量,解決方法:使用Scan類的批量操作 setBatch(int batch) int getBatch() 緩存是面向行一級(jí)的操作,而批量是面向列一級(jí)的操作。
2.8 各種特性 1)Htable使用方法 void close():使用完一個(gè)HTable實(shí)例后,需要調(diào)用一次close(),它會(huì)刷寫所有客戶端緩沖的寫操作 HTableDescriptor getTableDescripor():每個(gè)表都使用一個(gè)HTableDescriptor實(shí)例類來(lái)定義表結(jié)構(gòu) Map<HRegion,HServerAddress> getRegionInfo():獲取某一行數(shù)據(jù)的具體位置信息
三、客戶端API:高級(jí)特性 1.過(guò)濾器 Get和Scan兩個(gè)類都支持過(guò)濾器,過(guò)濾器的基本接口叫做Filter,用戶還可以通過(guò)繼承Filter類實(shí)現(xiàn)自己的需求 1.1 比較運(yùn)算符 1.2 比較器 1.3 Hbase提供的第一類:比較過(guò)濾器 用戶創(chuàng)建實(shí)例時(shí)需要一個(gè)比較運(yùn)算符和一個(gè)比較器實(shí)例 CompareFilter(CompareOp op,WriteableByteArrayComparable valueComparator)
- 行過(guò)濾器(父類為比較過(guò)濾器)RowFilter
- 列族過(guò)濾器(父類為比較過(guò)濾器)FamilyFilter
- 列名過(guò)濾器(父類為比較過(guò)濾器)QualifierFilter
- 值過(guò)濾器(父類為比較過(guò)濾器)ValueFilter
- 參考列過(guò)濾器(父類為比較過(guò)濾器)DependentColumnFilter:可以把它理解為一個(gè)ValueFilter和一個(gè)時(shí)間戳過(guò)濾器的組合
1.4 Hbase提供的第二類:專用過(guò)濾器
- 單列值過(guò)濾器:SingleColumnValueFilter,用一列的值決定是否一行數(shù)據(jù)被過(guò)濾
- SingleColumnValueFilter(family,qualifier,CompareOp op,value)
- 單列值排除過(guò)濾器:SingleColumnValueExcludeFilter
- 前綴過(guò)濾器:PrefixFilte(byte[] prefix):返回所有與前綴匹配的行
- 分頁(yè)過(guò)濾器:PageFilter(int pageSize):用戶可以使用這個(gè)過(guò)濾器對(duì)結(jié)果進(jìn)行分頁(yè)。當(dāng)用戶創(chuàng)建分頁(yè)過(guò)濾器實(shí)例時(shí),需要執(zhí)行pageSize參數(shù),注:物理上分離的服務(wù)器中并行執(zhí)行過(guò)濾器操作時(shí),需要注意,在不同的region服務(wù)器上并行執(zhí)行的過(guò)濾器操作不能共享它們現(xiàn)在的狀態(tài)和邊界,因此每個(gè)過(guò)濾器都會(huì)在完成掃描前獲取pageCount行的結(jié)果,這種情況可能使分頁(yè)過(guò)濾器可能失效
- 行健過(guò)濾器:KeyOnlyFilter:只返回結(jié)果中的鍵
- FirstKeyOnlyFilter:訪問(wèn)一行中第一列,這種過(guò)濾器通常用在行數(shù)統(tǒng)計(jì)的應(yīng)用場(chǎng)景中
- InclusiveStopFilter(byte[] endRow):掃描操作中的開(kāi)始行被包含在結(jié)果中,但終止行被排除在外,使用這個(gè)過(guò)濾器時(shí),用戶可以將結(jié)束行包含在結(jié)果中
- 時(shí)間戳過(guò)濾器:TimestampFilter(List<Long> timestamps):當(dāng)用戶需要在掃描結(jié)果中對(duì)版本進(jìn)行細(xì)粒度的控制時(shí),可以使用該過(guò)濾器
- 列計(jì)數(shù)過(guò)濾器:ColumnCountGetFilter(int limit,int offset):限制每行最多取回多少列,不太適合掃描操作,適合get()方法
- 列分頁(yè)過(guò)濾器:ColumnPaginationFilter(int limit,int offset):可以對(duì)一行的所有列進(jìn)行分頁(yè),它將跳過(guò)所有偏移量小于offset的列,并包含之后所有偏移量在limit之前(包含limit)的列
- 列前綴過(guò)濾器:ColumnPrefixFilter(byte[] prefix)
- 隨機(jī)行過(guò)濾器:RandomRowFilter(float chance)change在0到1之間
1.5 附加過(guò)濾器(應(yīng)用在其他過(guò)濾器上) 跳轉(zhuǎn)過(guò)濾器:SkipFilter(Filter filter):當(dāng)被包裝的過(guò)濾器遇到一個(gè)需要過(guò)濾的KeyValue時(shí),用戶可以擴(kuò)展并過(guò)濾整行數(shù)據(jù) 全匹配過(guò)濾器:WhileMatchFilter
1.6 FilterList 需要多個(gè)過(guò)濾器共同限制返回到客戶端的結(jié)果 FilterList(List<Filter> rowFilters) FilterList(Operator op) FilterList(List<Filter> rowFilters,Operator op) 參數(shù)rowFilters以列表的形式組合過(guò)濾器,參數(shù)operator決定了組合它們的結(jié)果,默認(rèn)是為MUST_PASS_ALL,使用ArrayList可以保證過(guò)濾器的執(zhí)行順序與它們添加到列表中的順序一致
1.7 自定義過(guò)濾器 用戶可以實(shí)現(xiàn)Filter接口或者直接繼承FilterBase類
用戶自定義過(guò)濾器部署 編寫代碼-->打成jar包-->把文件發(fā)送到每個(gè)region服務(wù)器上-->修改hbase-env.sh文件如下 export HBASE_CLASSPATH="/hbase-book/target.aa.jar"-->重啟hbase
2 計(jì)數(shù)器 2.1 簡(jiǎn)介 許多收集統(tǒng)計(jì)信息的應(yīng)用有點(diǎn)擊流和在線廣告意見(jiàn),這些需要被收集到日志文件中用戶后續(xù)的分析,用戶可以使用計(jì)數(shù)器做實(shí)時(shí)統(tǒng)計(jì),從而放棄延遲較高的批處理操作 雖然用戶可以一次更新多個(gè)計(jì)數(shù)器,但是它們必須屬于同一行,更新多個(gè)計(jì)數(shù)器需要通過(guò)獨(dú)立的API調(diào)用,即多個(gè)RPC請(qǐng)求 初始化計(jì)數(shù)器:用戶不用初始化計(jì)數(shù)器,當(dāng)用戶第一次使用計(jì)數(shù)器時(shí),計(jì)數(shù)器自動(dòng)設(shè)置為0,即當(dāng)用戶創(chuàng)建一個(gè)新列時(shí),計(jì)數(shù)器的值是0 在shell中操作計(jì)數(shù)器使用incr '<table>','<row>','<column>',[increment-value]與get_counter '<table>','<row>','<column>' 客戶端API操作計(jì)數(shù)器 1)單計(jì)數(shù)器 只能操作一個(gè)計(jì)數(shù)器:用戶需要自己設(shè)定列,方法由HTable提供的 long incrementColumnValue(row,family,qualifier,long amount) long incrementColumnValue(row,family,qualifier,long amount,boolean writeToWAL) 2)多計(jì)數(shù)器 Result increment(Increment increment) 需要?jiǎng)?chuàng)建一個(gè)Increment實(shí)例,構(gòu)造方法如下 Increment() Increment(row) Increment(row,RowLock rowLock) 向其中加入實(shí)際的計(jì)數(shù)器:addColumn(family,qualifier,long maxStamp)
3.協(xié)處理器 協(xié)處理器允許用戶在region服務(wù)器上運(yùn)行自己的代碼,也就是允許用戶執(zhí)行region級(jí)的操作,并可以使用如觸發(fā)器類似的功能 另一類適合使用協(xié)處理器的場(chǎng)景就是權(quán)限控制 協(xié)處理器框架提供了一些類,用戶可以通過(guò)繼承這些類擴(kuò)展自己的功能,主要有兩類,即observer和endpoint observer:回調(diào)函數(shù)(也被稱為鉤子函數(shù),hook)在一些特定時(shí)間發(fā)生時(shí)。這些事件包括用戶產(chǎn)生的事件和服務(wù)器內(nèi)部自動(dòng)產(chǎn)生的事件 RegionObserver:用戶可以用這種處理器處理數(shù)據(jù)修改事件,它們與表的region聯(lián)系緊密 MasterObserver:可以被用作管理或DDL類型的操作,這些是集群級(jí)事件 WALObserver:提供控制WAL的鉤子函數(shù)
endpoint:通過(guò)添加一些遠(yuǎn)程調(diào)用來(lái)動(dòng)態(tài)擴(kuò)展RPC協(xié)議,可以把它理解為與RDBMS中類似的存儲(chǔ)過(guò)程。endpoint可以與observer的實(shí)現(xiàn)組合起來(lái)直接作用于服務(wù)器的狀態(tài)
Coprocesspor類 所有協(xié)處理器的類都必須實(shí)現(xiàn)這個(gè)接口,它定義了協(xié)處理器的基本預(yù)定。提供了兩個(gè)被應(yīng)用于框架的枚舉類Priority(SYSTEM,USER)和State 待續(xù)!!!!
4.HtablePool 為Hbase集群提供一個(gè)客戶端連接池,用戶可以通過(guò)以下任意一個(gè)構(gòu)造器來(lái)創(chuàng)建池: HTablePool() HtablePool(Configuration conf,int maxSize) HtablePool(Configuration conf,int maxSize,HTableInterfaceFactory fac) HTableInterfaceFactory:用戶可以創(chuàng)建自定義的工廠類,例如,為Htable實(shí)例使用特定的配置,或可以讓實(shí)例完成一些初始化操作。如果用戶想自己擴(kuò)展HtableInterfaceFactory,則必須實(shí)現(xiàn)兩個(gè)方法createHTableInterface(conf,tableName)和releaseHtableInterface 使用表實(shí)例池方式:getTable(String tableName);getTable(byte[] tableName);void putTable(HtableInterface table)
5.連接管理 每個(gè)HTable實(shí)例都需要建立和遠(yuǎn)程主機(jī)的連接,這些連接在內(nèi)部使用HConnection類表示,被HConnectionManager類管理并共享。用戶沒(méi)必要和這兩個(gè)類打交道,只需要?jiǎng)?chuàng)建一個(gè)Configuration實(shí)例,然后利用客戶端API使用這些類。 Hbase內(nèi)部使用鍵值映射來(lái)存儲(chǔ)連接,使用Configuration實(shí)例作為鍵值映射的鍵。 HtablePool類,所有連接池中的Htable實(shí)例都自動(dòng)共用一個(gè)提供的Configuration實(shí)例,共享它們的連接。 共享連接的缺點(diǎn)在于釋放,如果用戶不顯示關(guān)閉連接,它將一直存在,直到客戶端退出,建議用戶不在需要使用Htable時(shí)主動(dòng)調(diào)用其close(),釋放資源,以下是顯式清理連接方法 deleteConnection(Configuration conf,boolean stop); deleteAllConnection(boolean stop)
四、客戶端API:管理功能 1.模式定義 1)表:使用表的主要原因是控制表中的所有列以達(dá)到共享表內(nèi)的某些特性的目的 表描述符的構(gòu)造函數(shù): HTableDescriptor(); HTableDescriptor(String name); HTableDescriptor(byte[] name); HTableDescriptor(HTableDescriptor desc);
任意不相交的系統(tǒng)間的遠(yuǎn)程通信都使用到了Hadoop RPC框架,需要遠(yuǎn)程方法中參數(shù)都實(shí)現(xiàn)Writeable接口,進(jìn)而能夠序列化對(duì)象并遠(yuǎn)程傳輸
2)表屬性 表名一定不能以".","-"開(kāi)頭,表名只能包含拉丁字母或數(shù)字、下劃線、".","-"
列族: void addFamily(HColumnDescriptor family) boolean hasFamily(byte[] c) HColumnDescriptor[] getColumnFamilies() HColumnDescriptor getFamily(byte[] column)
文件大小限制: long getMaxFileSize() void setMaxFileSize(long maxFileSize) 如果一個(gè)列族的存儲(chǔ)單元已使用的存儲(chǔ)空間超過(guò)了大小限制,region將發(fā)生拆分,maxFileSize默認(rèn)值是256M 這個(gè)參數(shù)只是大致的預(yù)期值,而在某些特殊條件下,文件大小可能超過(guò)這個(gè)預(yù)期值(一行數(shù)據(jù)不能跨region存儲(chǔ))
只讀:默認(rèn)所有的表都可寫,對(duì)于特殊的表來(lái)說(shuō),只讀參數(shù)有特殊的用途。調(diào)用setReadOnly(boolean readOnly)設(shè)置
memstore刷寫大小:寫操作會(huì)寫入到寫緩沖區(qū),人后按照合適的條件順序?qū)懭氲揭粋€(gè)新的存儲(chǔ)文件(磁盤)中,可以通過(guò)setMemStoreFlushSize(long memstoreFlushSize),這個(gè)memstoreFlushSize的默認(rèn)值是64MB
延遲日志刷寫: Hbase有兩種將WAL保存到磁盤的方式,一種是延遲日志刷寫,另一種不是,通過(guò)setDeferredLogFlush(boolean isDeferredLogFlush),isDeferredLogFlush的默認(rèn)值為false
3)列族 列族定義了所有列的共享信息,并且可以通過(guò)客戶端創(chuàng)建任意數(shù)量的列。定位到某個(gè)具體的列需要列族名和列名合并在一起,以:分隔,如family:qualifier 構(gòu)造方法: 列族名:getName()或getNameAsString() 不能被重命名,通常的做法是新建一個(gè)列族,然后使用API從舊列族中復(fù)制數(shù)據(jù)到新列族 列族名不能以"."開(kāi)頭,也不能包含":"、"\"或ISO控制符
最大版本數(shù):所有列族都限定了每個(gè)值能夠保留的最大版本數(shù),Hbase會(huì)移除超過(guò)最大版本數(shù)的數(shù)據(jù),通過(guò)setMaxVersions(int maxVersion)設(shè)置,這個(gè)maxVersion默認(rèn)為3.
壓縮: Hbase支持插件式的壓縮算法,允許用戶選擇最合適的壓縮算法 塊大小: 在Hbase中,所有的存儲(chǔ)文件都被劃分為若干個(gè)小存儲(chǔ)塊,這些小存儲(chǔ)塊在get或scan操作時(shí)會(huì)加載到內(nèi)存中,通過(guò)setBlockSize(int size)設(shè)置,默認(rèn)大小是64KB 注:HFile的不同于HDFS中的塊,HDFS提到的塊是用于拆分大文件以提供分布式存儲(chǔ),且便于MapReduce框架進(jìn)行并行計(jì)算的存儲(chǔ)單元;而HBase中的塊主要用于高效加載和緩沖數(shù)據(jù)
緩存塊: Hbase順序的讀取一個(gè)數(shù)據(jù)塊到內(nèi)存緩存中,這個(gè)參數(shù)默認(rèn)是為true,每次讀取的塊都會(huì)緩存到內(nèi)存中,但是如果順序讀取某個(gè)特定的列族,最好將這個(gè)屬性設(shè)置為false,通過(guò)setBlockCacheEnabled(boolean blockCacheEnabled)方法設(shè)置
生存期TTL: Hbase支持版本數(shù)據(jù)保存的時(shí)間,TTL設(shè)置了一個(gè)基于時(shí)間戳的臨界值,內(nèi)部管理會(huì)自動(dòng)檢查TTL的值是否達(dá)到上限,在major合并過(guò)程中時(shí)間戳被判定為超過(guò)TTL的數(shù)據(jù)會(huì)被刪掉,可以通過(guò)setTimeToLive(int timestamp)方法設(shè)置,TTL的參數(shù)為秒,默認(rèn)值是Integer.MAX_VALUE,理解為永久保留
在內(nèi)存中:setInMemory(boolean inMemory) 將inMemory設(shè)置為true只是一種承諾,或者說(shuō)高優(yōu)先級(jí)。在正常數(shù)據(jù)讀取過(guò)程中,塊數(shù)據(jù)被加載到緩沖區(qū)中并長(zhǎng)期駐留在內(nèi)存中,除非堆壓力過(guò)大,這個(gè)時(shí)候才會(huì)強(qiáng)制從內(nèi)存中卸載這部分?jǐn)?shù)據(jù)
布隆過(guò)濾器: 能夠減少特定訪問(wèn)模式下的查詢時(shí)間,由于這種模式增加了內(nèi)存和存儲(chǔ)的負(fù)擔(dān),這個(gè)模式默認(rèn)為關(guān)閉狀態(tài) 復(fù)制范圍:Hbase提供跨集群同步的功能,本地集群的數(shù)據(jù)更新可以及時(shí)同步到其他集群,復(fù)制范圍參數(shù)默認(rèn)為0,即這個(gè)功能處于關(guān)閉狀態(tài)。可以通過(guò)setScope(int scope)設(shè)置,1表示開(kāi)啟實(shí)時(shí)同步
2.HBaseAdmin HBaseAdmin提供了創(chuàng)建表、列族、檢查表是否存在,修改表結(jié)構(gòu)和列族結(jié)構(gòu)、以及刪除表功能 構(gòu)造方法:HbaseAdmin(Configuration conf)
1)表操作 建表: void createTable(HTableDescriptor desc) void createTable(HTableDescriptor desc,byte[] startKey,byte[] endKey,int numRegions) void createTable(HTableDescriptor desc,byte[][] splitKeys) void createTableAsync(HTableDescriptor desc,byte[][] splitKeys) HTable類中的方法getStartEndKey()來(lái)獲取所有region的邊界
獲取所有表的列表,以及判斷是否存在 boolean tableExists(String tableName) boolean tableExists(byte[] tableName) HTableDescriptor[] listTables() HTableDescriptor getTableDescriptor(byte[] tableName)
刪除表: void deleteTable(String tableName) void deleteTable(byte[] tableName)
在刪除表之前需要將表禁用,region服務(wù)器會(huì)先將內(nèi)存中近期內(nèi)還未提交的已修改的數(shù)據(jù)刷寫到磁盤,然后關(guān)閉所有region,并更新這樣表的元數(shù)據(jù),將所有region標(biāo)記為下線狀態(tài)。
2)集群管理 允許用戶查看集群當(dāng)前的狀態(tài): static void checkHBaseAvailable(Configuration) ClusterStatus getClusterStatus() void closeRegion(String regionname,String hostAndport) 注:所有可用表的region都應(yīng)該是在線狀態(tài) void majorCompact(String tableNameOrRegionName)
五、可用的客戶端 1.REST、Thrift,Avro介紹 它們都支持大量的語(yǔ)言,Protocol Buffer與Thrift和Avro最大的不同是它沒(méi)有自己的RPC堆,而它生成的RPC定義需要被后來(lái)其他的RPC庫(kù)使用,Hbase提供了REST、Thrift、Avro的輔助服務(wù),它們可以實(shí)現(xiàn)成專門的網(wǎng)關(guān)服務(wù),這些服務(wù)運(yùn)行在共享或?qū)S玫臋C(jī)器上。Thrift和Avro都有各自的RPC實(shí)現(xiàn),所以網(wǎng)關(guān)服務(wù)僅是在它們的基礎(chǔ)上進(jìn)行了封裝,至于REST,HBase則采用了自己的實(shí)現(xiàn),并提供了訪問(wèn)存儲(chǔ)數(shù)據(jù)的路徑。 每個(gè)請(qǐng)求使用一個(gè)服務(wù)而非建立一個(gè)連接的優(yōu)勢(shì)在于用戶可以復(fù)用連接來(lái)獲得最優(yōu)性能。 2.交互 1)使用原生Java:直接使用HTable并通過(guò)原生的RPC調(diào)用與HBase服務(wù)器進(jìn)行交互。 2)REST: 操作:基于REST服務(wù)的客戶端是在能夠與HBase通信之前需要先啟動(dòng)REST網(wǎng)關(guān)服務(wù),使用hbase-daemon.sh start rest命令。REST服務(wù)提供了HBase表提供的所有操作,REST服務(wù)器返回的值都經(jīng)過(guò)了base64Binary編碼。 支持的格式:通過(guò)使用HTTP Content-Type和Accept頭,調(diào)用者可以自動(dòng)選擇發(fā)送和接收信息的數(shù)據(jù)格式 Plain(text/plain): XML(text/xml):默認(rèn)的存儲(chǔ)和查詢格式是XML JSON(application/json):curl -H "Accept:application/json" http://<servername>:testtable/%01%02%03/colfam1:col1
REST的java客戶端: REST服務(wù)器同樣具有全面的java客戶端API,位于org.apache.hadoop.hbase.rest.client包中,其中核心類為RemoteHTable和RemoteAdmin
3)Thrift 在使用Thrift之前需要安裝Thrift,并且需要啟動(dòng)HBase提供的Thrift Server 啟動(dòng)Thrift命令:hbase-daemon.sh start thrift
4)Avro 在使用Thrift之前需要安裝Avro,并且需要啟動(dòng)HBase提供的Avro Server 啟動(dòng)Avro命令:hbase-daemon.sh start Avro
3.批量處理客戶端 1)Mapreduce:兩種方式,原生java API或Clojure 2)Hive Hive與Hbase之前的版本需要匹配,細(xì)微的RPC變化可能影響交互 3)pig 4)Cascading
4.shell 1)命令 引用名:命令行要求在使用表名和列名時(shí)需要通過(guò)單引號(hào)或雙引號(hào)對(duì)其進(jìn)行引用。 引用值:命令行支持二進(jìn)制、八進(jìn)制、十六進(jìn)制的輸入和輸出,用戶在引用時(shí)必須使用雙引號(hào) 使用逗號(hào)分隔參數(shù) Ruby散列屬性: 一些命令中需要設(shè)置鍵值對(duì)屬性,使用Ruby散列按照以下方式來(lái)完成 {'key1'=>'val1','key2'=>'val2',...}
DDL命令 alter 使用modifyTable()修改現(xiàn)有表結(jié)構(gòu)
DML命令:
工具命令: assgn 分配一個(gè)region到一臺(tái)region服務(wù)器中
復(fù)制命令:
腳本: 可以使用Nagios或其他監(jiān)控工具發(fā)送腳本 用戶還以使用管道的形式運(yùn)行命令
5.基于Web UI 1)master的web默認(rèn)端口是60010,region服務(wù)默認(rèn)端口是60030
六、與Mapreduce集成 1.類 InputFormat InputFormat負(fù)責(zé):拆分輸入數(shù)據(jù),同時(shí)返回一個(gè)RecordReader實(shí)例,定義了鍵值對(duì)象的類,并提供了next()遍歷數(shù)據(jù) 就HBase而言,它提供了一組專用的實(shí)現(xiàn),叫TableInputFormatBase,該實(shí)現(xiàn)的子類是TableInputFormat mapper HBase提供了一個(gè)TableMapper類,將鍵的類型強(qiáng)制轉(zhuǎn)換為ImmutableBytesWritable類,同時(shí)將改制的類型強(qiáng)制轉(zhuǎn)換為Result類型,TableMapper類沒(méi)有實(shí)現(xiàn)具體的功能,它只是添加了鍵值對(duì)的簽名 Reducer HBase提供了一個(gè)TableReducer類 OutputFormat Hbase提供了一個(gè)TableOutputFormat
2.支撐類 Mapreduce的支撐類與TableMapReduceUtil類一同協(xié)作在HBase上執(zhí)行Mapreduce任務(wù),它有一個(gè)靜態(tài)方法能配置作業(yè),病并使作業(yè)可以使用Hbase作為數(shù)據(jù)源或目標(biāo)
3.在HBase上的Mapreduce 當(dāng)運(yùn)行Mapreduce作業(yè)所需庫(kù)中的文件不是綁定在Hadoop或Mapreduce框架中時(shí),用戶就必須確保這些庫(kù)文在作業(yè)之前已經(jīng)可用,用戶一般兩個(gè)選擇:在所有的任務(wù)節(jié)點(diǎn)上準(zhǔn)備靜態(tài)的庫(kù)或直接提供作業(yè)所需的所有庫(kù) 1)靜態(tài)配置: 將jar文件復(fù)制到所有節(jié)點(diǎn)的常用路徑中 將這些jar文件的完整路徑寫入hadoop-env.sh配置文件中,按照如右方式編輯HADOOP-CLASSPATH變量:HADOOP-CLASSPATH="<extra-entries>":HADOOP-CLASSPATH 重啟所有的任務(wù)的NodeManager使變更生效 2)動(dòng)態(tài)配置:Hadoop有一個(gè)特殊的功能,它可以讀取操作目錄中/lib目錄下所包含的所有庫(kù)的jar文件,用戶可以使用此功能生成所謂的胖jar文件,胖jar文件使用maven的Maven Assembly插件
七、架構(gòu) 1.數(shù)據(jù)查找和傳輸 1)B+樹:它的葉節(jié)點(diǎn)項(xiàng)目鏈接并且有序,能夠通過(guò)主鍵對(duì)記錄進(jìn)行高效的插入、查找以及刪除,它表能為一個(gè)動(dòng)態(tài)、多層并由上下界的索引,同時(shí)要注意維護(hù)每一段所包含的鍵數(shù)目
2)LSM樹(log-structured merge-tree):輸入數(shù)據(jù)首先存儲(chǔ)在日志文件,這些文件內(nèi)的數(shù)據(jù)完全有序,當(dāng)有日志文件被修改時(shí),對(duì)應(yīng)的更新會(huì)被保存在內(nèi)存中加速查詢,修改數(shù)據(jù)文件的操作通過(guò)滾動(dòng)合并完成。
2.存儲(chǔ) 1)概覽 注:HBase主要處理兩種文件:一種是WAL文件,另一種是實(shí)際的數(shù)據(jù)文件,這兩種文件都是由HRegionServer管理
2)讀取數(shù)據(jù)流程
- 聯(lián)系ZooKeeper子集群(quorum),通過(guò)ZooKeeper獲取含有-ROOT-表的region服務(wù)器來(lái)查找行健
- 通過(guò)含有-ROOT-的region服務(wù)器可以查詢到含有.meta.表中對(duì)應(yīng)region服務(wù)器名,其中包內(nèi)含請(qǐng)求的行健信息
- 以上信息都會(huì)緩存下來(lái),只查找一次
- 通過(guò)查詢.META.服務(wù)器來(lái)獲取客戶端查詢的行健數(shù)據(jù)所在的region服務(wù)器,HBase會(huì)存儲(chǔ)這次查詢的信息
HRegionServer負(fù)責(zé)打開(kāi)region,并創(chuàng)建一個(gè)對(duì)應(yīng)的HRegion實(shí)例,它會(huì)為每個(gè)表的HColumnFamily創(chuàng)建一個(gè)Store實(shí)例,每個(gè)Store實(shí)例包含多個(gè)StoreFile(HFile的輕量級(jí)封裝)和一個(gè)MemStore,一個(gè)HRegionServer共享一個(gè)HLog實(shí)例
3)寫路徑
- 用戶發(fā)送HTable.put()請(qǐng)求到HRegion實(shí)例來(lái)大處理
- 決定數(shù)據(jù)是否需要寫到HLog類實(shí)現(xiàn)的預(yù)寫日志中,其中WAL是標(biāo)準(zhǔn)的Hadoop SequenceFile,并且存儲(chǔ)了HLogKey實(shí)例,這些鍵包含序列號(hào)和實(shí)際數(shù)據(jù)
- 一旦數(shù)據(jù)寫入到WAL中,數(shù)據(jù)就會(huì)放到MemStore中,同時(shí)檢查MemStore是否已經(jīng)滿了,如果滿了就刷寫到磁盤中去。書寫請(qǐng)求由另一個(gè)HRegionServer的線程處理,生成一個(gè)新的HFile
4)region拆分
- 當(dāng)region的存儲(chǔ)文件大于hbase.hregion.max.filesize大小或嫘祖層面的配置的大小時(shí),region會(huì)被一分為二
- 為新region創(chuàng)建兩個(gè)對(duì)應(yīng)的文件,每個(gè)region為原region的一半,通過(guò)在父region中創(chuàng)建split目錄來(lái)完成。
- 關(guān)閉該region,此后該region不再接受任何請(qǐng)求。
- region服務(wù)器通過(guò)split目錄中設(shè)立必需的文件接受來(lái)準(zhǔn)備新的子region,包括新region的目錄和參考文件。
- 把這兩個(gè)新region目錄移動(dòng)表目錄
- .META.表中父region的狀態(tài)會(huì)被更新,以表示其現(xiàn)在拆分的節(jié)點(diǎn)和子節(jié)點(diǎn)是什么
- 兩個(gè)子region準(zhǔn)備好后,將會(huì)被同一個(gè)服務(wù)器并行打開(kāi),打開(kāi)的過(guò)程包括更新.META.表,同時(shí)也會(huì)初始化為兩個(gè)region并對(duì)region中的內(nèi)容進(jìn)行合并,合并過(guò)程中替換引用文件之前會(huì)把父region的存儲(chǔ)文件異步重寫到兩個(gè)子region中,在region的.tmp目錄進(jìn)行
- 最終父region被清理,master被告知查分的情況,并且可以由于負(fù)載均衡而把新region移動(dòng)到其他的HRegionServer上
5)合并 minor合并:負(fù)責(zé)重寫最后生成的幾個(gè)文件到一個(gè)更大的文件中,文件數(shù)量有hbase.hstore.compaction.min決定,默認(rèn)值是3,minor合并處理的最大文件數(shù)默認(rèn)為10,用戶可以通過(guò)hbase.hstore.compaction.max來(lái)配置 major合并:把所有文件壓縮成一個(gè)單獨(dú)的文件,在memstore被刷寫到磁盤后出發(fā)檢查,或shell命令major-compact后觸發(fā),配置相關(guān)參數(shù) hbase.hregion.majorcompaction(默認(rèn)為24小時(shí))和hbase.hregion.majorcompaction.jitter(默認(rèn)為0.2)
6)HFile 注:文件長(zhǎng)度可變,唯一固定的塊是File Info和Trailer,Trailer是指向其他快遞的指針,塊大小是由HColumnDescriptor配置的,該配置可以在創(chuàng)建表的時(shí)候由用戶指定,默認(rèn)大小時(shí)64K,每一個(gè)塊都包含一個(gè)magic頭部和一定數(shù)量的序列化的KeyValue實(shí)例
7)WAL WAL存儲(chǔ)了對(duì)數(shù)據(jù)的所有更改,實(shí)現(xiàn)了WAL的類叫HLog類,HLog類的一個(gè)特性就是跟蹤修改,通過(guò)使用序列號(hào)來(lái)實(shí)現(xiàn)
3.ZooKeeper HBase使用ZooKeeper作為其協(xié)同服務(wù)組件,其主要功能包括跟蹤region服務(wù)器、保存root region的地址等 HBase建立的znode列表,默認(rèn)為/hbase,這個(gè)znode的名稱由zookeeper.znode.parent屬性決定, 以下是znode的列表以及他們的作用 /hbase/hbaseid:包括clusterID,與存儲(chǔ)在HDFS上的hbase.id文件內(nèi)容相同。 /hbase/master:包含服務(wù)器名稱 /hbase/replication:包含副本信息 /hbase/root-region-server:包含-ROOT-region所在的region服務(wù)器的機(jī)器名,這個(gè)經(jīng)常在region定位中使用 /hbase/rs:所偶region服務(wù)器的根節(jié)點(diǎn),集群使用它來(lái)跟蹤服務(wù)器異常 /hbase/shutdown:集群的啟動(dòng)事假和關(guān)閉時(shí)間 /hbase/table:當(dāng)表被禁用,信息會(huì)被添加到這個(gè)znode之下
4.復(fù)制 HBase復(fù)制可以作為一種災(zāi)難恢復(fù)的方法,并且可以提供HBase層的高可用性 HBase復(fù)制中最基本的機(jī)構(gòu)模式是"主推送",因?yàn)槊總€(gè)region服務(wù)器都有自己的WAL,所以很容易保存現(xiàn)在正在復(fù)制的位置 注:參與復(fù)制的集群可以不相等,主機(jī)群會(huì)通過(guò)隨機(jī)分配盡量均衡從集群的負(fù)載
1)常規(guī)處理 客戶端發(fā)送Put、Delete、或Increment到region服務(wù)器,這些請(qǐng)求包含的鍵值對(duì)會(huì)被region服務(wù)器轉(zhuǎn)化為WALEdit,同時(shí)WALEdit會(huì)被復(fù)制程序檢查,并以列族為單元復(fù)制數(shù)據(jù)。修改被添加到WAL中,并把實(shí)際數(shù)據(jù)添加到Memstore。 2)沒(méi)有反饋的從集群 如果從集群的region服務(wù)器沒(méi)有響應(yīng)rpc請(qǐng)求,主集群的region服務(wù)器將會(huì)睡眠并按照配置的次數(shù)重試。如果從集群的region服務(wù)器還是不可用,主機(jī)全會(huì)重新選擇一臺(tái)其他的機(jī)器來(lái)提交修改 3)挑選要復(fù)制的目標(biāo)集群 主集群的region服務(wù)器連接從集群的ZooKeeper群組,然后掃描/hbase/rs目錄來(lái)發(fā)現(xiàn)所有可用的并隨機(jī)選擇一部分服務(wù)器來(lái)復(fù)制數(shù)據(jù)(默認(rèn)是10%)
八、高級(jí)用法 1.rowkey設(shè)計(jì) 1)高表與寬表 HBase中的表可以設(shè)計(jì)為高表和寬表,前者指表中列少兒行多,后者則正好相反。用戶應(yīng)當(dāng)盡量將需要查詢的維度或信息存儲(chǔ)在行健中,應(yīng)為用它篩選的效率最高 此外,HBase只能按行分片,因此高表更有優(yōu)勢(shì)
2)時(shí)間序列:當(dāng)處理流式事件時(shí),最常用的就是按時(shí)間序列組織數(shù)據(jù),這些數(shù)據(jù)會(huì)被有序的存儲(chǔ)在一個(gè)特定的范圍內(nèi),到時(shí)系統(tǒng)產(chǎn)生讀寫熱點(diǎn),解決這個(gè)問(wèn)題的方法就是想辦法將數(shù)據(jù)分散到所有的region服務(wù)器上,有很多中方法,例如在行鍵前價(jià)格,通常情況下如下選擇
- salting方式:prefix=Long.hashCode(timestamp) % <number of regionservers>
- 字段變換/提升字段:如果用戶設(shè)計(jì)的行鍵包含多個(gè)字段則可以調(diào)整它們的位置
- 隨機(jī)化:rowkey=MD5(timestamp),隨機(jī)化很適合每次只讀取一行數(shù)據(jù)的應(yīng)用,如果用戶不需要連續(xù)掃描而只需要隨機(jī)讀取,可以考慮這種策略
時(shí)間順序關(guān)系 每個(gè)列族下的列可以作為輔助索引單獨(dú)進(jìn)行排序,主要內(nèi)容在主要的列族下,索引放在另外一個(gè)列族下,為了編碼創(chuàng)建太多的列族,可以把所有輔助索引存儲(chǔ)在有一個(gè)單獨(dú)的列族下,同時(shí)列鍵的最左端使用索引ID這個(gè)前綴來(lái)表示不同的順序
2.輔助索引 輔助索引存儲(chǔ)了新坐標(biāo)和現(xiàn)有坐標(biāo)之間的映射關(guān)系,一些為可行的解決方案 由客戶端管理索引: 把責(zé)任完全轉(zhuǎn)移到應(yīng)用層的典型做法是把一個(gè)數(shù)據(jù)表和一個(gè)查找/映射表結(jié)合起來(lái),每當(dāng)程序?qū)憯?shù)據(jù)表的時(shí)候,它也同時(shí)更新映射表(輔助索引表)。讀數(shù)據(jù)時(shí)可以直接在主表進(jìn)行查詢,從輔助索引表中先查找原表的行鍵,再在原表中讀取實(shí)際數(shù)據(jù)。優(yōu)點(diǎn):用戶可以按照需求設(shè)計(jì)映射表。缺點(diǎn):Hbase不能保證跨行操作的原子性 用戶可以自由設(shè)計(jì)主索引和輔助索引之間的映射關(guān)系時(shí),必須接受的缺點(diǎn)是用戶需要實(shí)現(xiàn)所有存儲(chǔ)和查找數(shù)據(jù)必需的方法
帶索引的事務(wù)型HBase 開(kāi)源的ITHBase,擴(kuò)展了HBase,最核心的擴(kuò)展是增加了保證所有輔助索引,提供了一個(gè)IndexedTableDescriptor,提供了數(shù)據(jù)表的輔助索引操作支持,大多數(shù)類被添加了索引支持功能的類替換了
帶索引的HBase IHBase是完全在內(nèi)存中維護(hù)索引,索引永遠(yuǎn)都是同步的,不需要額外的事務(wù)控制,索引的定義由IdxIndexDescriptor類完成
3.搜索集成 使用任意關(guān)鍵字來(lái)搜索數(shù)據(jù),滿足這種需要往往是集成一個(gè)完整的搜索引擎 Lucene:獨(dú)立于HBase使用的Lucene或其他派生類的解決方案可以通過(guò)Mapreduce建立索引。 HBasene:選擇的方法是直接在HBase內(nèi)部建立搜索索引,同時(shí)為用戶提供Lucene的API,它把每個(gè)文檔的字段、詞存儲(chǔ)在一個(gè)單獨(dú)的行,同時(shí)包含這個(gè)詞的文檔儲(chǔ)存在這一行的列中
九、監(jiān)控集群 1.監(jiān)控框架 每個(gè)HBase進(jìn)程都會(huì)提供一系列監(jiān)控指標(biāo),這些監(jiān)控指標(biāo)可以被各種監(jiān)控API和工具使用,包括JMX和Ganglia。每種服務(wù)器都有多組監(jiān)控指標(biāo),這些監(jiān)控指標(biāo)按子系統(tǒng)分組并隸屬于一種服務(wù)器 HBase使用Hadoop的監(jiān)控框架,并繼承了其所有類和特性,這個(gè)框架基于MetricsContext接口來(lái)處理監(jiān)控?cái)?shù)據(jù)點(diǎn)的生成,并使用這些數(shù)據(jù)點(diǎn)監(jiān)控和繪圖 1)可用的實(shí)現(xiàn)列表: GangliaContext:用來(lái)推送監(jiān)控指標(biāo)到Ganglia FileContext:將監(jiān)控指標(biāo)寫入磁盤上一個(gè)文件中 TimeStampingFileContext:將監(jiān)控指標(biāo)寫入磁盤上一個(gè)文件中,但是為每個(gè)監(jiān)控指標(biāo)添加一個(gè)時(shí)間戳前綴 CompositeContext:允許為監(jiān)控指標(biāo)生成不止一個(gè)上下文 NullContext:監(jiān)控指標(biāo)框架的關(guān)閉選項(xiàng),使用這個(gè)上下文時(shí),不生成也不聚合監(jiān)控指標(biāo) NullContextWithUpdateThread:不生成任何監(jiān)控指標(biāo),但是啟動(dòng)聚合統(tǒng)計(jì)線程。這種上下文在通過(guò)JMX檢索監(jiān)控指標(biāo)時(shí)使用
多重監(jiān)控指標(biāo)使用MetricsRecored分組,來(lái)描述一個(gè)具體的子系統(tǒng)。HBase使用這些組分別來(lái)保存master、region機(jī)器,以及其他服務(wù)器的統(tǒng)計(jì)信息,每個(gè)組都有唯一的名字:<context-name>.<record-name>.<metrics-name>。上下文有內(nèi)置的定時(shí)器來(lái)觸發(fā)并將監(jiān)控指標(biāo)推送至目標(biāo)
2)各種指標(biāo)類型: 整型值:(IV) 長(zhǎng)整型值:(LV) 速率(R):一個(gè)代表速率的浮點(diǎn)型值,可以是每秒操作或者消息數(shù) 字符串:存儲(chǔ)靜態(tài)的,基于文本的信息。并用來(lái)報(bào)告HBase版本信息和構(gòu)建時(shí)間 時(shí)間變化整型(TVI):上下文會(huì)維護(hù)一個(gè)單調(diào)遞增累加計(jì)數(shù)器??蚣苁褂眠@個(gè)方法對(duì)各種消息進(jìn)行技術(shù) 時(shí)間變化長(zhǎng)整型(TVL):用于增速較快的計(jì)數(shù)器 時(shí)間變化率(TVR):需要追蹤操作數(shù)或消息的數(shù)量,以及完成操作所用的時(shí)間,通常用來(lái)計(jì)算一次操作完成的平均時(shí)間 持續(xù)型時(shí)間變化率(PTVR):添加了對(duì)持續(xù)的周期性的監(jiān)控指標(biāo)的必要的支持。 3)master提供的監(jiān)控指標(biāo)
4)region服務(wù)器監(jiān)控指標(biāo): 塊緩存監(jiān)控指標(biāo) 塊緩存用來(lái)保存底層HFile從HDFS讀取的存儲(chǔ)塊。count(LV)監(jiān)控指標(biāo)反映了當(dāng)前緩存中保存的塊數(shù)目,size(LV)監(jiān)控指標(biāo)時(shí)占用java堆空間大小,free(LV)監(jiān)控指標(biāo)時(shí)堆空間為緩存保留的可用空間,evicted(LV)反映了命中緩存總數(shù)與請(qǐng)求緩存總數(shù)的關(guān)系 塊緩存追蹤追蹤緩存命中hit(LV)和緩存失效miss(LV)的數(shù)目,以及命中率hit radio(LV),其反映了命中緩存總數(shù)與請(qǐng)求緩存總數(shù)的關(guān)系。所有讀操作使用緩存,不管用戶是否制定過(guò)將使用的塊保留在緩存中。使用setCacheBlocks()僅僅影響塊的保留策略 合并監(jiān)控 compaction size(PTVR)和compaction time(PTVR)分別代表需要合并的存儲(chǔ)文件總大小和操作花費(fèi)時(shí)間 compaction queue size:用來(lái)監(jiān)測(cè)一個(gè)region服務(wù)器有多少文件當(dāng)前正在排隊(duì)等待合并
memstore監(jiān)控指標(biāo) memstore size MB(IV):服務(wù)器上所有memstore總共占用的堆大小 flush queue zie(IV):將要被刷寫的region的數(shù)目
存儲(chǔ)監(jiān)控指標(biāo): store files(IV):所有存儲(chǔ)文件的數(shù)目 store file index MB(IV):所有存儲(chǔ)文件的塊索引和元數(shù)據(jù)的總和大小
I/O監(jiān)控指標(biāo): fs read latency(TVR):文件系統(tǒng)的讀延遲 fs write latency:寫延遲 fs sync latency:統(tǒng)計(jì)了預(yù)寫日志記錄同步到文件系統(tǒng)的延遲
RPC監(jiān)控指標(biāo) Ganglia 組成: Ganglia監(jiān)控守護(hù)進(jìn)程(gmond):監(jiān)控守護(hù)進(jìn)程需要在每臺(tái)需要監(jiān)控的機(jī)器上運(yùn)行,它搜集本地?cái)?shù)據(jù),準(zhǔn)備統(tǒng)計(jì),然后被其他系統(tǒng)拉取。通過(guò)單一或組播方網(wǎng)絡(luò)消息傳播的主機(jī)變化情況,使用組播方式,每個(gè)監(jiān)控守護(hù)進(jìn)程可以獲取集群完整狀態(tài),所有的服務(wù)器擁有同樣的組播地址 Ganglia元數(shù)據(jù)守護(hù)進(jìn)程(gmetad):元數(shù)據(jù)守護(hù)進(jìn)程安裝在一個(gè)中心節(jié)點(diǎn)上,作為整個(gè)集群的管理節(jié)點(diǎn)。元數(shù)據(jù)守護(hù)進(jìn)程從一個(gè)或多個(gè)監(jiān)控守護(hù)進(jìn)程拉去數(shù)據(jù)來(lái)獲取整個(gè)集群的狀態(tài),然后使用RDTool將這些信息存放在一個(gè)用于輪詢的時(shí)間序列數(shù)據(jù)庫(kù)中。 GangliaPHP:展示統(tǒng)計(jì)信息
十、性能優(yōu)化 1.垃圾回收優(yōu)化 垃圾回收時(shí)master通常不會(huì)產(chǎn)生問(wèn)題,只需要添加到region服務(wù)器的啟動(dòng)參數(shù)中。 用戶可以通過(guò)向hbase-env.sh配置文件中添加HBASE_OPTS或者HBASE_REGIONSERVER_OPTS變量來(lái)設(shè)置垃圾回收的相關(guān)選項(xiàng)。后者僅影響region服務(wù)器進(jìn)程,也是推薦的修改方式 指定新生代的方式:-XX:MaxNewSize=128m -XX:NewSize=128m或-Xmn128m 注意:默認(rèn)值對(duì)于多數(shù)region服務(wù)器面對(duì)的負(fù)載還是太小,所以她必須增大
建議在JRE日志中輸入垃圾回收的詳細(xì)信息,通過(guò)添加以下JRE選項(xiàng): -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$HBASE-HOME/logs/gc-hbase.log 該日志不會(huì)按日期定時(shí)滾動(dòng),需要手動(dòng)處理(例如:使用基于crontab的每日滾動(dòng)轉(zhuǎn)存任務(wù))
通過(guò)不同的JRE參數(shù)來(lái)指定不同的垃圾回收實(shí)現(xiàn)策略,推薦的值是: -XX:+UseParNewGC and -XX:+UseConcMarkSweepGC UseParNewGC:停止運(yùn)行java進(jìn)程二期清空年輕代堆 ConcMarkSweepGC:不停止java進(jìn)程的情況下異步并行的完成工作
2.預(yù)拆分region 管理接口中createTable()方法或shell中的create命令可以接受列表形式提供的拆分行健作為參數(shù)
3.負(fù)載均衡: master有一個(gè)內(nèi)置的叫做均衡器的特性,在默認(rèn)的情況下,均衡器每五分鐘運(yùn)行一次,可以通過(guò)hbase.balancer.period屬性設(shè)置 均衡器有一個(gè)可以限制自身運(yùn)行時(shí)間的上限,用戶可以通過(guò)hbase.balance.max.balancing屬性來(lái)設(shè)置,默認(rèn)為均衡器間隔周期的一半
4.合并region HBase集成了一個(gè)工具能夠讓用戶在集群沒(méi)有工作時(shí)河北那個(gè)兩個(gè)相鄰的region,工具為org.apache.hadoop.hbase.util.Merge
5.客戶端API:最佳實(shí)踐 1)禁止自動(dòng)刷寫:當(dāng)有大量的寫入操作時(shí),使用setAutoFlush(false)方法,確認(rèn)HTable自動(dòng)刷寫的特性已經(jīng)關(guān)閉,如果禁用了自動(dòng)刷寫,add(Put)操作指導(dǎo)寫緩沖區(qū)被填滿時(shí)才會(huì)被送出,可以調(diào)用HTable的flushCommits()方法顯式刷寫數(shù)據(jù),調(diào)用HTable的close()也會(huì)隱式調(diào)用flushCommits() 2)使用掃面緩存:如果HBase被用作一個(gè)MapReduce作業(yè)的輸入源,請(qǐng)最好將作為MapReduce作業(yè)輸入掃描器實(shí)例的緩存用setCaching()方法設(shè)置為比默認(rèn)值1大得多的值,使用默認(rèn)值意味著map任務(wù)處理每條記錄都請(qǐng)求region服務(wù)器 3)限定掃描范圍 當(dāng)Scan用來(lái)處理大量行時(shí)注意哪些屬性被選中了,從而限制掃描范圍 4)關(guān)閉ResultScanner 如果用戶忘記關(guān)閉由HTable.getScanner()返回的ResultScanner實(shí)例,則可能對(duì)服務(wù)器端造成影響,一定要在try/catche的finally塊中關(guān)閉ResultScanner 5)塊緩存用法 Scan實(shí)例通過(guò)setCacheBlock()方法來(lái)設(shè)置使用region服務(wù)器中的塊緩存,如果MapReduce作業(yè)中使用掃描,這個(gè)方法應(yīng)當(dāng)被設(shè)為false,對(duì)于那些頻繁訪問(wèn)行的行,建議使用塊緩存 6)關(guān)閉Put上WAL 提高吞吐量方式,使用Put的writeToWAL(false)來(lái)關(guān)閉WAL,不過(guò)一旦region服務(wù)器故障就會(huì)丟失數(shù)據(jù)
6.配置 1)減少Zookeeper超時(shí) 默認(rèn)在region服務(wù)器和ZooKeeper集群之間的超時(shí)時(shí)間是3分鐘,通過(guò)zookeeper.session.timeout屬性設(shè)置,在改變值之前,確認(rèn)用戶服務(wù)器上JVM的垃圾回收機(jī)制是受控的 2)增加處理線程 hbase.regionserver.handler.count屬性定義了響應(yīng)外部用戶訪問(wèn)數(shù)據(jù)表請(qǐng)求的線程數(shù),默認(rèn)值10有些偏小,將這個(gè)值設(shè)置的高也有可能產(chǎn)生問(wèn)題,并發(fā)的寫請(qǐng)求造成壓力 3)增加堆大小 如果用戶使用更好的服務(wù)器,可以給HBase分配8G內(nèi)存或更大,用戶可以在hbase-env.sh文件中調(diào)整HBASE_HEAPSIZE的設(shè)置,master會(huì)默認(rèn)1GB的堆運(yùn)行,region服務(wù)器則會(huì)按照用戶單獨(dú)指定的堆空間運(yùn)行 4)啟動(dòng)數(shù)據(jù)壓縮 用戶應(yīng)當(dāng)為存儲(chǔ)文件啟動(dòng)壓縮,尤其推薦使用Snappy或LZO壓縮 5)增加region大小 默認(rèn)region大小為256M,用戶可以增加其大小,但是該參數(shù)的大小要仔細(xì)評(píng)估 6)調(diào)整塊緩存大小 控制堆中塊緩存大小的屬性是一個(gè)浮動(dòng)點(diǎn)數(shù)類型的百分比,默認(rèn)值是20%,可以通過(guò)perf.hfile.block.cache.size屬性改變這個(gè)值,看看是否存在許多塊被換出的情況,如果存在,則可以考慮增加塊緩存的大小。用戶負(fù)載大多數(shù)為讀請(qǐng)求是另一個(gè)增加緩存大小的原因。 7)調(diào)整memstore限制 內(nèi)存存儲(chǔ)占用的堆大小用hbase.regionserver.global.memstore.upperLimit屬性來(lái)配置,默認(rèn)值為40%,此外hbase.regionserver.global.memstore.lowerLimit屬性(默認(rèn)為35%)用戶控制當(dāng)服務(wù)器清空memstore之后剩余的大小,當(dāng)用戶主要在處理讀請(qǐng)求時(shí),可以考慮通知減少memstore的上線限來(lái)增加塊緩存的空間 8)增加阻塞時(shí)存儲(chǔ)文件數(shù)目 這個(gè)值通過(guò)hbase.hstore.blockingStoreFiles屬性來(lái)設(shè)置的,它決定了當(dāng)存儲(chǔ)文件的數(shù)據(jù)達(dá)到閾值時(shí),更新操作將會(huì)被阻塞,當(dāng)應(yīng)用經(jīng)常遇到大負(fù)載的突發(fā)寫請(qǐng)求時(shí),用戶可以稍微增加這個(gè)值來(lái)應(yīng)對(duì)這種情況,其默認(rèn)值是7 9)增加阻塞倍率 屬性hbase.hregion.memstore.block.multiplier的默認(rèn)值是2,當(dāng)memstore達(dá)到屬性multiplier乘以flush的大小限制時(shí)會(huì)阻止進(jìn)一步更新 10)減少最大日志文件的限制 設(shè)置hbase.regionserver.maxlogs屬性使得用戶能夠控制基于磁盤的WAL文件數(shù)目,進(jìn)而控制刷寫頻率,該參數(shù)的默認(rèn)值是32
負(fù)載測(cè)試 Hbase有自己的性能評(píng)價(jià)工具,名為PE,使用命令:hbase org.apache.hadoop.hbase.PerformanceEvaluation YCSB:Yahoo的云服務(wù)基準(zhǔn)測(cè)試系統(tǒng)也可用于對(duì)HBase集群進(jìn)行超負(fù)荷測(cè)試
十一、集群管理 1.運(yùn)維任務(wù) 1)減少節(jié)點(diǎn) 使用hbase-daemon.sh stop regionserver停止region服務(wù)器 如果關(guān)閉節(jié)點(diǎn)時(shí)負(fù)載均衡還在運(yùn)行,則在復(fù)雜均衡和master恢復(fù)下線的region服務(wù)器之間可能存在競(jìng)爭(zhēng),要避免這種情況,使用shell命令:balance_switch false禁用負(fù)載均衡 HBase0.90.2之后引入了一種可以讓region服務(wù)器逐漸減少其負(fù)載并停止服務(wù)的方法,使用graceful_stop.sh腳本來(lái)完成 用戶也可以用graceful_stop.sh腳本來(lái)重啟服務(wù)器,并將之前屬于它的region移回原味(用戶可能選擇后者以保持?jǐn)?shù)據(jù)的局部性),最簡(jiǎn)單的滾動(dòng)重啟可以使用如下命令(確認(rèn)之前已經(jīng)關(guān)閉負(fù)載均衡): for i in 'cat conf/regionservers|sort; do ./bin/graceful_stop.sh --restart --reload --debug $i; done $> /tmp/log.txt &
2.數(shù)據(jù)任務(wù) 1)導(dǎo)入/導(dǎo)出 HBase發(fā)布了一些有用的工具,其中兩個(gè)支持導(dǎo)入和導(dǎo)出MapReduce作業(yè)。這些工具包含在HBase的JAR文件中,用戶可以通過(guò)hadoop jar命令來(lái)獲得這些工具,使用格式:hadoop jar $HBASE_HOME/HBASE-0.91.0-SNAPSHOT.jar <command>
總結(jié)
以上是生活随笔為你收集整理的hbase权威指南学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。