HTable使用教程
對于建表,和RDBMS類似,HBase也有namespace的概念,可以指定表空間創建表,也可以直接創建表,進入default表空間。
對于數據操作,HBase支持四類主要的數據操作,分別是:
· Put:增加一行,修改一行;
· Delete:刪除一行,刪除指定列族,刪除指定column的多個版本,刪除指定column的制定版本等;
· Get:獲取指定行的所有信息,獲取指定行和指定列族的所有colunm,獲取指定column,獲取指定column的幾個版本,獲取指定column的指定版本等;
· Scan:獲取所有行,獲取指定行鍵范圍的行,獲取從某行開始的幾行,獲取滿足過濾條件的行等。
這四個類都是org.apache.hadoop.hbase.client的子類,可以到官網API去查看詳細信息,本文僅總結常用方法,力爭讓讀者用20%的時間掌握80%的常用功能。
1. 命名空間Namespace
在關系數據庫系統中,命名空間namespace指的是一個表的邏輯分組,同一組中的表有類似的用途。命名空間的概念為即將到來的多租戶特性打下基礎:
· 配額管理(Quota Management (HBASE-8410)):限制一個namespace可以使用的資源,資源包括region和table等;
· 命名空間安全管理(Namespace Security Administration (HBASE-9206)):提供了另一個層面的多租戶安全管理;
· Region服務器組(Region server groups (HBASE-6721)):一個命名空間或一張表,可以被固定到一組regionservers上,從而保證了數據隔離性。
1.1.命名空間管理
命名空間可以被創建、移除、修改。
表和命名空間的隸屬關系在在創建表時決定,通過以下格式指定:
《namespace》:《table》
Example:hbase shell中創建命名空間、創建命名空間中的表、移除命名空間、修改命名空間
?
1.2. 預定義的命名空間
有兩個系統內置的預定義命名空間:
· hbase:系統命名空間,用于包含hbase的內部表
· default:所有未指定命名空間的表都自動進入該命名空間
Example:指定命名空間和默認命名空間
#namespace=foo and table qualifier=bar
create ‘foo:bar’, ‘fam’
#namespace=default and table qualifier=bar
create ‘bar’, ‘fam’
2. 創建表
廢話不多說,直接上樣板代碼,代碼后再說明注意事項和知識點:
關鍵知識點:
必須將HBase集群的hbase-site.xml文件添加進工程的classpath中,或者通過Configuration對象設置相關屬性,否則程序獲取不到集群相關信息,也就無法找到集群,運行程序時會報錯;
HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(“my_ns:mytable”))代碼是描述表mytable,并將mytable放到了my_ns命名空間中,前提是該命名空間已存在,如果指定的是不存在命名空間,則會報錯org.apache.hadoop.hbase.NamespaceNotFoundException;
命名空間一般在建模階段通過命令行創建,在java代碼中通過admin.createNamespace(NamespaceDescriptor.create(“my_ns”).build())創建的機會不多;
創建HBaseAdmin對象時就已經建立了客戶端程序與HBase集群的connection,所以在程序執行完成后,務必通過admin.close()關閉connection;
可以通過HTableDescriptor對象設置表的特性,比如:通過tableDesc.setMaxFileSize(512)設置一個region中的store文件的最大size,當一個region中的最大store文件達到這個size時,region就開始分裂;通過tableDesc.setMemStoreFlushSize(512)設置region內存中的memstore的最大值,當memstore達到這個值時,開始往磁盤中刷數據。更多特性請自行查閱官網API;
可以通過HColumnDescriptor對象設置列族的特性,比如:通過hcd.setTimeToLive(5184000)設置數據保存的最長時間;通過hcd.setInMemory(true)設置數據保存在內存中以提高響應速度;通過 hcd.setMaxVersions(10)設置數據保存的最大版本數;通過hcd.setMinVersions(5)設置數據保存的最小版本數(配合TimeToLive使用)。更多特性請自行查閱官網API;
數據的版本數只能通過HColumnDescriptor對象設置,不能通過HTableDescriptor對象設置;
由于HBase的數據是先寫入內存,數據累計達到內存閥值時才往磁盤中flush數據,所以,如果在數據還沒有flush進硬盤時,regionserver down掉了,內存中的數據將丟失。要想解決這個場景的問題就需要用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability.SYNC_WAL)就是設置寫WAL日志的級別,示例中設置的是同步寫WAL,該方式安全性較高,但無疑會一定程度影響性能,請根據具體場景選擇使用;
setDurability(Durability d)方法可以在相關的三個對象中使用,分別是:HTableDescriptor,Delete,Put(其中Delete和Put的該方法都是繼承自父類org.apache.hadoop.hbase.client.Mutation)。分別針對表、插入操作、刪除操作設定WAL日志寫入級別。需要注意的是,Delete和Put并不會繼承Table的Durability級別(已實測驗證)。Durability是一個枚舉變量,可選值參見4.2節。如果不通過該方法指定WAL日志級別,則為默認USE_DEFAULT級別。
3.刪除表
刪除表沒創建表那么多學問,直接上代碼:
?
4、修改表
4.1.實例代碼
(1)刪除列族、新增列族
修改之前,四個列族:
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
修改表,刪除三個列族,新增一個列族,代碼如下:
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 =》 ‘action_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
邏輯很簡單:
通過admin.getTableDescriptor(Bytes.toBytes(“rd_ns:itable”))取得目標表的描述對象,應該就是取得指向該對象的指針了;
修改目標表描述對象;
通過admin.modifyTable(Bytes.toBytes(“rd_ns:itable”),newtd)將修改后的描述對象應用到目標表。
(2)修改現有列族的屬性(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();
評論
查看更多