HBase
- 1.hbase 介紹
Apache HBase?是Hadoop數(shù)據(jù)庫,是一個(gè)分布式,可擴(kuò)展的大數(shù)據(jù)存儲(chǔ)。
當(dāng)您需要對(duì)大數(shù)據(jù)進(jìn)行隨機(jī),實(shí)時(shí)讀/寫訪問時(shí),請(qǐng)使用Apache HBase?。該項(xiàng)目的目標(biāo)是托
管非常大的表 - 數(shù)十億行X百萬列 - 在商品硬件集群上。Apache HBase是一個(gè)開源的,分布式
的,版本化的非關(guān)系數(shù)據(jù)庫,模仿Google的Bigtable: Chang等人的結(jié)構(gòu)化數(shù)據(jù)分布式存儲(chǔ)系
統(tǒng)。正如Bigtable利用Google文件系統(tǒng)提供的分布式數(shù)據(jù)存儲(chǔ)一樣,Apache HBase在Hadoop和
HDFS之上提供類似Bigtable的功能。
2006年-google發(fā)表了bigtable的白皮書
2006年-開始開發(fā)hbase
2008年-hbase正式成為apache的子項(xiàng)目
2010年-正式成為apache的頂級(jí)項(xiàng)目
1.HBase是在HDFS上面向列的分布式的數(shù)據(jù)庫;
HBase首先是數(shù)據(jù)庫,分布式的,面向列的,稀疏,<首選在HDFS基礎(chǔ)上>;
Google發(fā)布三篇論文:GFS、MapReduce、BigTable開啟分布式存儲(chǔ)和計(jì)算的紀(jì)元;
hdfs+MapRedece(Hadoop)解決離線分析;HBase解決實(shí)時(shí)處理業(yè)務(wù)需求;
2.HBase不是關(guān)系型數(shù)據(jù)庫,它不支持SQL;
3.列簇(Column family):
物理上,列簇存儲(chǔ)在文件系統(tǒng)中,面向列簇的存儲(chǔ)器;
創(chuàng)建table時(shí),必須制定列簇,列簇的中列可隨時(shí)增加;
針對(duì)調(diào)優(yōu)和存儲(chǔ)考慮,需將列簇成員設(shè)置成相同的訪問權(quán)限和大小特征;

- 2.hbase 特點(diǎn)
大:一個(gè)表可以有數(shù)十億行,上百萬列;
無模式:每行都有一個(gè)可排序的主鍵和任意多的列,列可以根據(jù)需要?jiǎng)討B(tài)的增加,同一張表中不同的行可以有截然不同的列;
面向列:面向列(族)的存儲(chǔ)和權(quán)限控制,列(族)獨(dú)立檢索;
稀疏:對(duì)于空(null)的列,并不占用存儲(chǔ)空間,表可以設(shè)計(jì)的非常稀疏;
數(shù)據(jù)多版本:每個(gè)單元中的數(shù)據(jù)可以有多個(gè)版本,默認(rèn)情況下版本號(hào)自動(dòng)分配,是單元格插入時(shí)的時(shí)間戳;
數(shù)據(jù)類型單一:Hbase中的數(shù)據(jù)都是字符串,沒有類型。
- 3.hbase 搭建(完全分布式+HA)
1) 解壓
tar -zxvf hbase-1.3.1-bin.tar.gz -C /root/soft/
mv ~/soft/hbase-1.3.1 ~/soft/hbase
2) 添加環(huán)境變量
echo "#hbase install" >> /etc/profile
echo "export HBASE_HOME=/root/soft/hbase" >> /etc/profile
echo "export PATH=$HBASE_HOME/bin:$PATH" >> /etc/profile
source /etc/profile
3) 修改配置文件
(1) hbase-env.sh
export JAVA_HOME=/root/soft/java
export HBASE_CLASSPATH=/root/soft/hadoop/etc/hadoop
# 去掉后邊的 -XX:PermSize=128m -XX:MaxPermSize=128m
# java1.8 后會(huì)自動(dòng)調(diào)整內(nèi)存 添加參數(shù)會(huì)有警告
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS "
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS "
# 關(guān)閉hbase自帶Zookeeper
export HBASE_MANAGES_ZK=false
(2) hbase-site.xml
<property>
<name>hbase.rootdir</name>
<value>hdfs://mycluster/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>mstr,slv1,slv2,slv3,slv4</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/root/zookeeper/zkdata</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/root/tmp/hbase</value>
</property>
(3) regionservers
slv1
slv2
slv3
(4) backup-masters (自己在conf下創(chuàng)建 )
slv4
(5) 軟連接hadoop的配置文件(core, hdfs)
#軟連接hadoop配置
ln -s ~/soft/hadoop/core-site.xml ~/soft/hbase/conf
ln -s ~/root/hadoop/hdfs-site.xml ~/soft/hbase/conf
(6) 分發(fā)軟件, 配置文件和環(huán)境變量
- 4 hbase 操作
1) 啟動(dòng)集群
zkServer.sh start //在Zk集群節(jié)點(diǎn)上執(zhí)行
start-dfs.sh
start-hbase.sh

2) Web-UI
(mstr:16010)

(slv4:16010)
[圖片上傳失敗...(image-b9822d-1565087262349)]
3) hbase shell
[root@mstr ~]# hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 1.3.1, r930b9a55528fe45d8edce7af42fef2d35e77677a, Thu Apr 6 19:36:54 PDT 2017
1."查看服務(wù)器狀態(tài)"
> status
1 active master, 1 backup masters, 3 servers, 0 dead, 2.0000 average load
2."查看表"
> list
TABLE
mfrain:student
mfrain:tt
testtable
wordcount
3."掃描"
# 全表掃描
> scan 'mfrain:tt'
ROW COLUMN+CELL
1001 column=info1:a, timestamp=1557909052757, value=aaa
1001 column=info1:b, timestamp=1557909063664, value=bbb
# 篩選掃描
> scan 'user',{STARTROW =>'101',STOPROW => '101'}
# 獲取一行數(shù)據(jù)
> get 'mfrain:tt','1001'
COLUMN CELL
info1:a timestamp=1557909052757, value=aaa
info1:b timestamp=1557909063664, value=bbb
# 查看某單元格值
> get 'mfrain:tt','1001','info1:a'
COLUMN CELL
info1:a timestamp=1557909052757, value=aaa
4."創(chuàng)建表"
> create '表名','列族名'
5."插入數(shù)據(jù)"
> put '表名','行鍵','列族名:列名','值'
#在hbase中沒有修改,但是可以覆蓋只要保持rowkey,列族,列相同即可進(jìn)行覆蓋操作
6."查看表結(jié)構(gòu)"
> describe 'testtable'
Table testtable is ENABLED
testtable
COLUMN FAMILIES DESCRIPTION
{NAME => 'colfaml',
BLOOMFILTER => 'ROW',
VERSIONS => '1',
IN_MEMORY => 'false',
KEEP_DELETED_CELLS => 'FALSE',
DATA_BLOCK_ENCODING => 'NONE',
TTL => 'FOREVER',
COMPRESSION => 'NONE',
MIN_VERSIONS => '0',
BLOCKCACHE => 'true',
BLOCKSIZE => '65536',
REPLICATION_SCOPE => '0'}
7."更改表信息"
# 更改列族的版本號(hào)
> alter '表名',{NAME => 'info',VERSIONS => '3'}
# 添加列族
> disable '表名'
> alter '表名',NAME=>'新增列族名'
> enable '表名'
8."刪除表信息"
# 刪除具體單元格值
> delete '表名','行鍵','列族:列'
# 刪除一行值
> deleteall '表名','行鍵'
# 清空表信息
> truncate '表名'
# 刪除列族
> alter "表名",'delete' => '列族名'
9."刪除表"
# 第一步 將表設(shè)置為disable
> disable '表名'
# 第二部 刪除表
> drop '表名'
10."多版本控制"
# 默認(rèn)version為1,只能存1個(gè)版本
# 更改表的列族的最多版本
> alter 'mfrain:student',{NAME=>'info1',VERSIONS=>3}
# 掃描表最近三個(gè)版本信息
> scan 'mfrain:student' ,{VERSIONS=>3}
ROW COLUMN+CELL
1001 column=info1:nage, timestamp=1557901465180, value=18
1001 column=info1:name, timestamp=1557905467926, value=mfre4
1001 column=info1:name, timestamp=1557905336099, value=mfr3
1001 column=info1:name, timestamp=1557902966333, value=mfr2
1001 column=info2:addr, timestamp=1557901498209, value=JiLin
# 執(zhí)行delete刪除命令時(shí),如需按照ts(timestamp)時(shí)間戳進(jìn)行刪除操作時(shí),之前版本一并刪除掉;
> delete 'mfrain:student','1001','info1:name',1557905336099
> scan 'mfrain:student' ,{VERSIONS=>3}
ROW COLUMN+CELL
1001 column=info1:nage, timestamp=1559645182639, value=20
1001 column=info1:nage, timestamp=1557901465180, value=18
1001 column=info1:name, timestamp=1557905467926, value=mfre4
1001 column=info2:addr, timestamp=1557901498209, value=JiLin
11."get_table指令"
# 將table映射成相對(duì)應(yīng)的變量值(table實(shí)例),通過table實(shí)例對(duì)表進(jìn)行相關(guān)操作
> t1 = get_table '表名'
> t1.scan
> t1.put 'row-2','info1:name','zhangsan'
> t1.get 'row-2'
12."namespace操作"
# namespace名字空間,相當(dāng)于傳統(tǒng)數(shù)據(jù)庫的表空間:
# 列出名字空間
> list_namespace
# 列出名字空間下有哪些表
> list_namespace_tables 'default'
# 創(chuàng)建namespace
> create_namespace 'ns1',{'author'=>'zhangsan','data'=>'2018-07-31'}
# 查看namespace 信息
> describe_namespace 'mfrain'
DESCRIPTION
{NAME => 'mfrain', author => 'mfr', data => '20190515'}
# 刪除namespace (先清空表)
> drop_namespace 'ns1'
4) Flush刷新表(1.3.1版本默認(rèn)128M進(jìn)行刷新)
(1) 插入數(shù)據(jù)
(2) 查看hbase/data/列族生成0 bytes
> hadoop fs -lsr /hbase
image(3) 刷盤/關(guān)閉Hbase
(Hbase)> flush 'mfrain:stu'
或者 > stop-hbase.sh
(4) 查看hbase/data/列族生成4918bytes
> hadoop fs -lsr /hbase
image(5) 設(shè)置刷盤閾值
<property> <name>hbase.regionserver.optionalcacheflushinterval</name> <value>3600000</value> <description> 在自動(dòng)刷新之前,編輯在內(nèi)存中的最長(zhǎng)時(shí)間。 默認(rèn)的1小時(shí)。將其設(shè)置為0以禁用自動(dòng)刷新。 </description> </property> <property> <name>hbase.hregion.memstore.flush.size</name> <value>134217728</value> <description> 如果memstore的大小超過128M,進(jìn)行刷盤操作 </description> </property>
5) 負(fù)載均衡
balance負(fù)載均衡指令,需使用開關(guān)模式,原因負(fù)載均衡比較耗費(fèi)資源:
> balance_switch true //開啟負(fù)載均衡
> balancer //執(zhí)行負(fù)載均衡
> balance_switch false //關(guān)閉負(fù)載均衡
> balancer "force" //強(qiáng)制負(fù)載均衡
調(diào)節(jié)均衡器運(yùn)行間隔(默認(rèn)30000)
<property> <name>hbase.balancer.period</name> <value>3000</value> </property>
6) meta表
查看meta表(只有mfrain:stu表)
兩條記錄
[圖片上傳失敗...(image-655311-1565087262350)]
查看WEB-UI
三個(gè)region 包括 hbase:namespace, mfrain:stu, hbase:meta
imageimageimageregionname格式:
<table_name>+","+<startKey>+","+<timestamp>+"."+<ENCODED>MD5生成碼(生成規(guī)則由“{<table_name>+","+<startKey>+","+<timestamp>+"."}”
7) split切分
(1) 添加測(cè)試數(shù)據(jù),使用Ruby語法添加數(shù)據(jù)
hbase(main):003:0> create_namespace 'mfrain' hbase(main):003:0> create 'mfrain:stu','info' hbase(main):003:0> for i in 'a'..'z' do for j in 'a'..'z' do \ hbase(main):009:2* put 'mfrain:stu',"row-#{i}#{j}","info:#{j}","#{j}" end end hbase(main):008:0> count 'mfrain:stu' 676 row(s) in 0.2560 seconds hbase(main):010:0> flush 'mfrain:stu' 0 row(s) in 0.9240 seconds(2) 查看/hbase路徑和meta表
① $> hadoop fs -lsr /hbase
[圖片上傳失敗...(image-92e46c-1565087262350)]
② hbase> scan 'hbase:meta'
image③ 切分
# 切分 hbase(main):012:0> split 'mfrain:stu','row-mm' 0 row(s) in 0.2460 seconds④ 查看切分后的meta表
切分時(shí)切分時(shí)
切分完成切分完成⑤ 查看切分后的HDFS
hdfs⑥ 總結(jié)
1.rowkey區(qū)間,前包后不包 2.切分時(shí)原region不會(huì)立刻刪除,等待切分完成后再刪除!切分時(shí)原region有如下標(biāo)記: STARTKEY => '', ENDKEY => '', OFFLINE => true, SPLIT => true
8) merge合并
(1) 合并指令
hbase(main):019:0> merge_region '53c1b5981f6c7eab63b0f260eddff79a','7c0fda1423359fd3152466935b56d8bd'(2) 合并過程
合并時(shí)[圖片上傳失敗...(image-5486e5-1565087262350)]
合并完成合并完成(3) Web-UI merge
webUIwancheng(4) Region移動(dòng)
隨機(jī)移動(dòng)# move 'encoded' move '2530e3effe529c9f8d51141525d478f2'
指定移動(dòng)# move 'encoded','regionserver_hostname,16020,regionservertimestamp' move '2530e3effe529c9f8d51141525d478f2','slv1,16020,1560150516386'
9) 預(yù)分區(qū) (事先指定分區(qū)(rowkey設(shè)計(jì)至關(guān)重要))
# 說明:在ns1命名空間下,創(chuàng)建t1表,列簇為f1;預(yù)分區(qū)為5個(gè)(字符串):['',10);[10,20);[20,30);[30,40);[40,''] hbase> create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40']
- 5. HBase API
1) 開發(fā)環(huán)境準(zhǔn)備
hbase 對(duì)應(yīng)版本相關(guān)Jar hdfs-site.xml core-site.xml hbase-site.xml
//編寫HBaseTool工具類
//1.定義conn對(duì)象
private static Configuration conf;
private static Connection conn;
static{
conf = HBaseConfiguration.create();
try {
conn = ConnectionFactory.createConnection(conf);
} catch (IOException e) {
e.printStackTrace();
}
}
2) namespace 操作
/**
* 創(chuàng)建名字空間
* create_namespace 'ns1'
*/
public static void createNS(String namespace){
Admin admin = null;
try {
admin = conn.getAdmin();
NamespaceDescriptor nsdesc = NamespaceDescriptor.create(namespace).build();
admin.createNamespace(nsdesc);
System.out.println("---創(chuàng)建成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---創(chuàng)建失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 查詢名字空間
* list_namespace
*/
public static void listNS(){
Admin admin = null;
try {
admin = conn.getAdmin();
NamespaceDescriptor[] nss = admin.listNamespaceDescriptors();
for (NamespaceDescriptor ns : nss) {
System.out.println(ns);
}
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 刪除名字空間
* drop_namespace 'ns1'
*/
public static void deleteNS(String namespace){
Admin admin = null;
try {
admin = conn.getAdmin();
admin.deleteNamespace(namespace);
System.out.println("---刪除成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---刪除失敗!---");
} finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3) Table 操作
/**
* 創(chuàng)建Table
* create 'ns1:student','f1'
*/
public static void createTable(String tablename,String colunmfamily){
Admin admin = null;
try {
admin = conn.getAdmin();
TableName tname = TableName.valueOf(tablename);
HTableDescriptor htdesc = new HTableDescriptor(tname);
HColumnDescriptor hcdesc = new HColumnDescriptor(colunmfamily);
htdesc.addFamily(hcdesc);
admin.createTable(htdesc);
System.out.println("---表創(chuàng)建成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---表創(chuàng)建失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 查看表
* list
*/
public static void getTable() {
try {
HTableDescriptor[] listtable = admin.listTables();
for(HTableDescriptor tables :listtable) {
System.out.println(tables);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 刪除Table
* drop 'ns1:student'
*/
public static void dropTable(String tablename){
Admin admin = null;
try {
admin = conn.getAdmin();
TableName tname = TableName.valueOf(tablename);
admin.disableTable(tname);
admin.deleteTable(tname);
System.out.println("---表刪除成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---表刪除失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4) Put 操作
/**
* 單行put
* put 'ns1:student','row-1','f1:name','zhangsan'
*/
public static void putTable(String tablename){
TableName tableName =TableName.valueOf(tablename);
try {
HTable table = new HTable(conf,tableName);
for(int i = 20; i<=23 ; i++) {
byte[] row = Bytes.toBytes("row"+i);
Put put = new Put(row);
byte[] columFamily = Bytes.toBytes("fA");
byte[] qualifier = Bytes.toBytes(String.valueOf(i));
byte[] value = Bytes.toBytes("value"+i);
put.addColumn(columFamily,qualifier,value);
table.put(put);
System.out.println("put 成功!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 多行put
*
*/
public static void puts(String tablename,List<Put> puts){
try {
Table _table = conn.getTable(TableName.valueOf(tablename));
for (int i = 0; i < puts.size(); i++) {
_table.put(puts.get(i));
}
System.out.println("---插入成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---插入失敗!---");
}
}
//測(cè)試多行插入
public static void main(String[] args) throws IOException {
List<Put> _puts = new ArrayList<Put>();
for (int i = 3; i < 10000; i++) {
Put _put = new Put(Bytes.toBytes("row-"+i));
_put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("asa"+i));
_put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("age"), Bytes.toBytes("23"));
_put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("sex"), Bytes.toBytes("男"+i));
_put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("class"), Bytes.toBytes("BD1709"+i));
_puts.add(_put);
}
HBaseTool.puts("ns1:t1", _puts);
}
5) Get 操作
HBase以表的方式存儲(chǔ)數(shù)據(jù)。表是由行和列構(gòu)成的,列從屬于某一個(gè)列族(column family)。
行和列的交叉點(diǎn)稱之為cell,cell是版本化的,cell的內(nèi)容就是數(shù)據(jù),cell中的數(shù)據(jù)是沒有類型的,
全部是字節(jié)碼形式存貯,是不可分割的字節(jié)數(shù)組。
/**
* 查詢單條記錄通過rowkey查詢 get 'tableName','rowKey'
* @param tablename
* @param rowkey
*/
public static void getone(String tablename,String rowkey){
try {
Table _table = conn.getTable(TableName.valueOf(tablename));
//get 對(duì)象首先指定rowkey
Get _get = new Get(Bytes.toBytes(rowkey));
Result rs = _table.get(_get);
List<Cell> cells = rs.listCells();
for (Cell cell : cells) {
System.out.println("列簇為:"+Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("限定符為:"+Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("rowkey為:"+Bytes.toString(CellUtil.cloneRow(cell)));
System.out.println("value為:"+Bytes.toString(CellUtil.cloneValue(cell)));
}
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}
}
/**
* 查詢單條記錄,并返回指定Version數(shù)
* @param tablename
* @param rowkey
*/
public static void getone(String tablename,String rowkey,int version){
try {
Table _table = conn.getTable(TableName.valueOf(tablename));
Get _get = new Get(Bytes.toBytes(rowkey));
_get.setMaxVersions(version);
Result rs = _table.get(_get);
List<Cell> cells = rs.listCells();
for (Cell cell : cells) {
System.out.println("列簇為:"+Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("限定符為:"+Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("rowkey為:"+Bytes.toString(CellUtil.cloneRow(cell)));
System.out.println("value為:"+Bytes.toString(CellUtil.cloneValue(cell)));
System.out.println("timestamp為:"+cell.getTimestamp());
}
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}
}
/**
* 按照hbase shell 格式輸出
*
*/
private static void printOut(Result rs){
List<Cell> cells = rs.listCells();
for (Cell cell : cells) {
String family = Bytes.toString(CellUtil.cloneFamily(cell));
String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
String value = Bytes.toString(CellUtil.cloneValue(cell));
long timestamp = cell.getTimestamp();
System.out.println(rowkey+" column="+family+":"+qualifier+", timestamp="+timestamp+", value="+value);
}
}
/**
* 查詢所有
* @param tablename
* @param rowkey
*/
public static void findAll(String tablename){
try {
Table _table = conn.getTable(TableName.valueOf(tablename));
Scan scan = new Scan();
ResultScanner rsscan = _table.getScanner(scan);
Iterator<Result> its = rsscan.iterator();
while (its.hasNext()) {
printOut(its.next());
}
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}
}
/**
* 查詢startkey至endkey之間的數(shù)據(jù)
* @param tablename
* @param rowkey
*/
public static void findByRowkey(String tablename,String startkey,String endkey){
try {
Table _table = conn.getTable(TableName.valueOf(tablename));
Scan scan = new Scan(Bytes.toBytes(startkey),Bytes.toBytes(endkey));
ResultScanner rsscan = _table.getScanner(scan);
Iterator<Result> its = rsscan.iterator();
while (its.hasNext()) {
printOut(its.next());
}
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}
}
按rowKey刪除 $> deleteall 'ts1','33'
public static void deleteRowKey(String tableName,String rowkey) throws IOException {
Table _table = conn.getTable(TableName.valueOf(tablename));
Delete delete = new Delete(Bytes.toBytes(rowkey));
table.delete(delete);
}
6) split 操作
/**
* 切分Table
* 查看HDFS hadoop fs -lsr /hbase
*/
public static void splittable(String tablename){
Admin admin = null;
try {
admin = conn.getAdmin();
admin.split(TableName.valueOf(tablename),Bytes.toBytes("5"));
System.out.println("---切分成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---切分失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 切分region和table 相同
*
*/
public static void splitregion(String regionname){
Admin admin = null;
try {
admin = conn.getAdmin();
admin.splitRegion(Bytes.toBytes(regionname),"row-nu".getBytes());
System.out.println("---切分成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---切分失敗!---");
}finally{
try {
admin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
7) merge 操作 / move 操作
//合并region
admin = conn.getAdmin();
admin.mergeRegions("ffd7e19bf6dabc990aa9da07cea32afc".getBytes(), "27e639cc8d5d43d4ff25d38c59a3bc1e".getBytes(), true);
//移動(dòng)region到指定節(jié)點(diǎn)
admin = conn.getAdmin();
admin.move("ffd7e19bf6dabc990aa9da07cea32afc".getBytes(), "slave1,16020,1558184978689".getBytes());
8) Scan緩存/bacth批量查詢
一、設(shè)置Scan緩存
通過Scan掃描,每一次調(diào)用next()方法都會(huì)生成一個(gè)單獨(dú)的PRC請(qǐng)求,并且返回一條記錄
緩存可以讓next()一次獲取多條記錄
設(shè)置緩存方式有兩種 :
1)表Htable層面 setScannerCaching(int)
2)Scan類 setCaching(int)
也可以通過設(shè)置配置文件hbase-site.xml
<property>
<name>hbase.client.scanner.caching</name>
<value>10</value>
</property>
優(yōu)先級(jí)順序?yàn)? scan類 -->Htable類-->配置文件
二、設(shè)置bacth批量查詢
批量可以讓用戶選擇每一次ResultScanner實(shí)例的next()操作要取回多少列
例如,setBatch(5),則一次next()返回的Resulut實(shí)例包括5列
緩存是面向行一級(jí)的操作,而批量則是面向列一級(jí)的操作
public static void findAll(String tablename){
try {
Table table = conn.getTable(TableName.valueOf(tablename));
//EQUAL 匹配等于設(shè)定值的值
Scan scan = new Scan();
//設(shè)置掃描批次,一次next()返回 Result實(shí)例會(huì)包括5列
// scan.setBatch(5);
// //hbase設(shè)置緩存
// scan.setCaching(100);
long starttime = System.currentTimeMillis();
ResultScanner scanner = table.getScanner(scan);
Iterator<Result> its = scanner.iterator();
while (its.hasNext()) {
printOut(its.next());
}
scanner.close();
System.out.println(System.currentTimeMillis()-starttime);
System.out.println("---查詢成功!---");
} catch (IOException e) {
e.printStackTrace();
System.out.println("---查詢失敗!---");
}
}











