HTable使用教程
對(duì)于建表,和RDBMS類似,HBase也有namespace的概念,可以指定表空間創(chuàng)建表,也可以直接創(chuàng)建表,進(jìn)入default表空間。
對(duì)于數(shù)據(jù)操作,HBase支持四類主要的數(shù)據(jù)操作,分別是:
· Put:增加一行,修改一行;
· Delete:刪除一行,刪除指定列族,刪除指定column的多個(gè)版本,刪除指定column的制定版本等;
· Get:獲取指定行的所有信息,獲取指定行和指定列族的所有colunm,獲取指定column,獲取指定column的幾個(gè)版本,獲取指定column的指定版本等;
· Scan:獲取所有行,獲取指定行鍵范圍的行,獲取從某行開(kāi)始的幾行,獲取滿足過(guò)濾條件的行等。
這四個(gè)類都是org.apache.hadoop.hbase.client的子類,可以到官網(wǎng)API去查看詳細(xì)信息,本文僅總結(jié)常用方法,力爭(zhēng)讓讀者用20%的時(shí)間掌握80%的常用功能。
1. 命名空間Namespace
在關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)中,命名空間namespace指的是一個(gè)表的邏輯分組,同一組中的表有類似的用途。命名空間的概念為即將到來(lái)的多租戶特性打下基礎(chǔ):
· 配額管理(Quota Management (HBASE-8410)):限制一個(gè)namespace可以使用的資源,資源包括region和table等;
· 命名空間安全管理(Namespace Security Administration (HBASE-9206)):提供了另一個(gè)層面的多租戶安全管理;
· Region服務(wù)器組(Region server groups (HBASE-6721)):一個(gè)命名空間或一張表,可以被固定到一組regionservers上,從而保證了數(shù)據(jù)隔離性。
1.1.命名空間管理
命名空間可以被創(chuàng)建、移除、修改。
表和命名空間的隸屬關(guān)系在在創(chuàng)建表時(shí)決定,通過(guò)以下格式指定:
《namespace》:《table》
Example:hbase shell中創(chuàng)建命名空間、創(chuàng)建命名空間中的表、移除命名空間、修改命名空間
?
1.2. 預(yù)定義的命名空間
有兩個(gè)系統(tǒng)內(nèi)置的預(yù)定義命名空間:
· hbase:系統(tǒng)命名空間,用于包含hbase的內(nèi)部表
· default:所有未指定命名空間的表都自動(dòng)進(jìn)入該命名空間
Example:指定命名空間和默認(rèn)命名空間
#namespace=foo and table qualifier=bar
create ‘foo:bar’, ‘fam’
#namespace=default and table qualifier=bar
create ‘bar’, ‘fam’
2. 創(chuàng)建表
廢話不多說(shuō),直接上樣板代碼,代碼后再說(shuō)明注意事項(xiàng)和知識(shí)點(diǎn):
關(guān)鍵知識(shí)點(diǎn):
必須將HBase集群的hbase-site.xml文件添加進(jìn)工程的classpath中,或者通過(guò)Configuration對(duì)象設(shè)置相關(guān)屬性,否則程序獲取不到集群相關(guān)信息,也就無(wú)法找到集群,運(yùn)行程序時(shí)會(huì)報(bào)錯(cuò);
HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(“my_ns:mytable”))代碼是描述表mytable,并將mytable放到了my_ns命名空間中,前提是該命名空間已存在,如果指定的是不存在命名空間,則會(huì)報(bào)錯(cuò)org.apache.hadoop.hbase.NamespaceNotFoundException;
命名空間一般在建模階段通過(guò)命令行創(chuàng)建,在java代碼中通過(guò)admin.createNamespace(NamespaceDescriptor.create(“my_ns”).build())創(chuàng)建的機(jī)會(huì)不多;
創(chuàng)建HBaseAdmin對(duì)象時(shí)就已經(jīng)建立了客戶端程序與HBase集群的connection,所以在程序執(zhí)行完成后,務(wù)必通過(guò)admin.close()關(guān)閉connection;
可以通過(guò)HTableDescriptor對(duì)象設(shè)置表的特性,比如:通過(guò)tableDesc.setMaxFileSize(512)設(shè)置一個(gè)region中的store文件的最大size,當(dāng)一個(gè)region中的最大store文件達(dá)到這個(gè)size時(shí),region就開(kāi)始分裂;通過(guò)tableDesc.setMemStoreFlushSize(512)設(shè)置region內(nèi)存中的memstore的最大值,當(dāng)memstore達(dá)到這個(gè)值時(shí),開(kāi)始往磁盤中刷數(shù)據(jù)。更多特性請(qǐng)自行查閱官網(wǎng)API;
可以通過(guò)HColumnDescriptor對(duì)象設(shè)置列族的特性,比如:通過(guò)hcd.setTimeToLive(5184000)設(shè)置數(shù)據(jù)保存的最長(zhǎng)時(shí)間;通過(guò)hcd.setInMemory(true)設(shè)置數(shù)據(jù)保存在內(nèi)存中以提高響應(yīng)速度;通過(guò) hcd.setMaxVersions(10)設(shè)置數(shù)據(jù)保存的最大版本數(shù);通過(guò)hcd.setMinVersions(5)設(shè)置數(shù)據(jù)保存的最小版本數(shù)(配合TimeToLive使用)。更多特性請(qǐng)自行查閱官網(wǎng)API;
數(shù)據(jù)的版本數(shù)只能通過(guò)HColumnDescriptor對(duì)象設(shè)置,不能通過(guò)HTableDescriptor對(duì)象設(shè)置;
由于HBase的數(shù)據(jù)是先寫入內(nèi)存,數(shù)據(jù)累計(jì)達(dá)到內(nèi)存閥值時(shí)才往磁盤中flush數(shù)據(jù),所以,如果在數(shù)據(jù)還沒(méi)有flush進(jìn)硬盤時(shí),regionserver down掉了,內(nèi)存中的數(shù)據(jù)將丟失。要想解決這個(gè)場(chǎng)景的問(wèn)題就需要用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability.SYNC_WAL)就是設(shè)置寫WAL日志的級(jí)別,示例中設(shè)置的是同步寫WAL,該方式安全性較高,但無(wú)疑會(huì)一定程度影響性能,請(qǐng)根據(jù)具體場(chǎng)景選擇使用;
setDurability(Durability d)方法可以在相關(guān)的三個(gè)對(duì)象中使用,分別是:HTableDescriptor,Delete,Put(其中Delete和Put的該方法都是繼承自父類org.apache.hadoop.hbase.client.Mutation)。分別針對(duì)表、插入操作、刪除操作設(shè)定WAL日志寫入級(jí)別。需要注意的是,Delete和Put并不會(huì)繼承Table的Durability級(jí)別(已實(shí)測(cè)驗(yàn)證)。Durability是一個(gè)枚舉變量,可選值參見(jiàn)4.2節(jié)。如果不通過(guò)該方法指定WAL日志級(jí)別,則為默認(rèn)USE_DEFAULT級(jí)別。
3.刪除表
刪除表沒(méi)創(chuàng)建表那么多學(xué)問(wèn),直接上代碼:
?
4、修改表
4.1.實(shí)例代碼
(1)刪除列族、新增列族
修改之前,四個(gè)列族:
hbase(main):014:0》 describe ‘rd_ns:itable’
DESCRIPTION ENABLED
‘rd_ns:itable’, {NAME =》 ‘info’, DATA_BLOCK_ENCODING =》 ‘NONE’, BLOOMFILTER =》 ‘ROW’, REPLICATION_SCOPE =》 ‘0’, V true
ERSIONS =》 ‘10’, COMPRESSION =》 ‘NONE’, MIN_VERSIONS =》 ‘0’, TTL =》 ‘2147483647’, KEEP_DELETED_CELLS =》 ‘false’,
BLOCKSIZE =》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》 ‘true’}, {NAME =》 ‘newcf’, DATA_BLOCK_ENCODING =》 ‘NONE
’, BLOOMFILTER =》 ‘ROW’, REPLICATION_SCOPE =》 ‘0’, COMPRESSION =》 ‘NONE’, VERSIONS =》 ‘10’, TTL =》 ‘2147483647’,
MIN_VERSIONS =》 ‘0’, KEEP_DELETED_CELLS =》 ‘false’, BLOCKSIZE =》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》 ‘tr
ue’}, {NAME =》 ‘note’, DATA_BLOCK_ENCODING =》 ‘NONE’, BLOOMFILTER =》 ‘ROW’, REPLICATION_SCOPE =》 ‘0’, VERSIONS =》
‘10’, COMPRESSION =》 ‘NONE’, MIN_VERSIONS =》 ‘0’, TTL =》 ‘2147483647’, KEEP_DELETED_CELLS =》 ‘false’, BLOCKSIZE
=》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》 ‘true’}, {NAME =》 ‘sysinfo’, DATA_BLOCK_ENCODING =》 ‘NONE’, BLOOM
FILTER =》 ‘ROW’, REPLICATION_SCOPE =》 ‘0’, COMPRESSION =》 ‘NONE’, VERSIONS =》 ‘10’, TTL =》 ‘2147483647’, MIN_VERS
IONS =》 ‘0’, KEEP_DELETED_CELLS =》 ‘true’, BLOCKSIZE =》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》 ‘true’}
1 row(s) in 0.0450 seconds
修改表,刪除三個(gè)列族,新增一個(gè)列族,代碼如下:
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
String tablename = “rd_ns:itable”;
if(admin.tableExists(tablename)) {
try {
admin.disableTable(tablename);
//get the TableDescriptor of target table
HTableDescriptor newtd = admin.getTableDescriptor(Bytes.toBytes(“rd_ns:itable”));
//remove 3 useless column families
newtd.removeFamily(Bytes.toBytes(“note”));
newtd.removeFamily(Bytes.toBytes(“newcf”));
newtd.removeFamily(Bytes.toBytes(“sysinfo”));
//create HColumnDescriptor for new column family
HColumnDescriptor newhcd = new HColumnDescriptor(“action_log”);
newhcd.setMaxVersions(10);
newhcd.setKeepDeletedCells(true);
//add the new column family(HColumnDescriptor) to HTableDescriptor
newtd.addFamily(newhcd);
//modify target table struture
admin.modifyTable(Bytes.toBytes(“rd_ns:itable”),newtd);
admin.enableTable(tablename);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
admin.close();
修改之后:
hbase(main):015:0》 describe ‘rd_ns:itable’
DESCRIPTION ENABLED
‘rd_ns:itable’, {NAME =》 ‘a(chǎn)ction_log’, DATA_BLOCK_ENCODING =》 ‘NONE’, BLOOMFILTER =》 ‘ROW’, REPLICATION_SCOPE =》 true
‘0’, COMPRESSION =》 ‘NONE’, VERSIONS =》 ‘10’, TTL =》 ‘2147483647’, MIN_VERSIONS =》 ‘0’, KEEP_DELETED_CELLS =》 ‘tr
ue’, BLOCKSIZE =》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》 ‘true’}, {NAME =》 ‘info’, DATA_BLOCK_ENCODING =》 ‘
NONE’, BLOOMFILTER =》 ‘ROW’, REPLICATION_SCOPE =》 ‘0’, VERSIONS =》 ‘10’, COMPRESSION =》 ‘NONE’, MIN_VERSIONS =》 ‘
0’, TTL =》 ‘2147483647’, KEEP_DELETED_CELLS =》 ‘false’, BLOCKSIZE =》 ‘65536’, IN_MEMORY =》 ‘false’, BLOCKCACHE =》
‘true’}
1 row(s) in 0.0400 seconds
邏輯很簡(jiǎn)單:
通過(guò)admin.getTableDescriptor(Bytes.toBytes(“rd_ns:itable”))取得目標(biāo)表的描述對(duì)象,應(yīng)該就是取得指向該對(duì)象的指針了;
修改目標(biāo)表描述對(duì)象;
通過(guò)admin.modifyTable(Bytes.toBytes(“rd_ns:itable”),newtd)將修改后的描述對(duì)象應(yīng)用到目標(biāo)表。
(2)修改現(xiàn)有列族的屬性(setMaxVersions)
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
String tablename = “rd_ns:itable”;
if(admin.tableExists(tablename)) {
try {
admin.disableTable(tablename);
//get the TableDescriptor of target table
HTableDescriptor htd = admin.getTableDescriptor(Bytes.toBytes(“rd_ns:itable”));
HColumnDescriptor infocf = htd.getFamily(Bytes.toBytes(“info”));
infocf.setMaxVersions(100);
//modify target table struture
admin.modifyTable(Bytes.toBytes(“rd_ns:itable”),htd);
admin.enableTable(tablename);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
admin.close();
評(píng)論
查看更多