启动和停止
先启动Zookeeper和Hadoop
启动Hbase
代码语言:javascript复制$HBASE_HOME/bin/start-hbase.sh
停止Hbase
代码语言:javascript复制$HBASE_HOME/bin/stop-hbase.sh
HMaster 的 Web 接口
http://192.168.7.101:16010
http://192.168.7.102:16010
HRegionServer 的 Web 接口
http://192.168.7.101:16030
http://192.168.7.102:16030
http://192.168.7.103:16030
HBase的操作
下面的操作主要是在hbase的shell中操作的,进入hbase shell
代码语言:javascript复制hbase shell
命名空间
查看所有namespace
代码语言:javascript复制list_namespace
创建namespace
代码语言:javascript复制create_namespace 'zns'
删除namespace
代码语言:javascript复制drop_namespace 'zns'
注意
删除命名空间前要删除命名空间下的所有表
删除命名空间下的表
代码语言:javascript复制disable 'zns:ztable'
drop 'zns:ztable'
查看namespace
代码语言:javascript复制describe_namespace 'zns'
在namespace下创建表
代码语言:javascript复制create 'zns:ztable','s_name','s_sex'
查看namespace下的表
代码语言:javascript复制list_namespace_tables 'zns'
表操作
创建表
代码语言:javascript复制create 'student','s_name','s_sex','s_age','s_dept','s_course'
# 创建表示指定保存的版本数
create 'teacher',{NAME=>'username',VERSIONS=>5}
查看表详情
代码语言:javascript复制describe 'student'
显示所有的表
代码语言:javascript复制list
插入数据
代码语言:javascript复制put 'student','95001','s_name','LiYing'
put 'student','95001','s_sex','Male'
put 'student','95001','s_course:math','80'
put 'student','95001','s_course:english','90'
put 'student','95002','s_name','XiaoHong'
put 'student','95002','s_sex','Femal'
put 'student','95002','s_course:math','90'
put 'student','95002','s_course:english','70'
注意:一次只能为一个表的一行数据的一个列,也就是一个单元格添加一个数据,所以直接用shell命令插入数据效率很低,在实际应用中,一般都是利用编程操作数据。
当运行命令:
put ‘student’,’95001’,’s_name’,’LiYing’
时,即为student表添加了学号为95001,名字为LiYing的一行数据,其行键为95001。
查询数据 HBase中有两个用于查看数据的命令:
- get命令,用于查看表的某一行数据;
- scan命令用于查看某个表的全部数据
示例
代码语言:javascript复制get 'student','95001'
get 'student','95001','s_course'
get 'student','95001','s_course:math'
scan 'student'
scan 'student', {FORMATTER => 'toString'}
删除数据 在HBase中用delete以及deleteall命令进行删除数据操作,它们的区别是: ① delete用于删除一个数据,是put的反向操作; ② deleteall操作用于删除一行数据。
代码语言:javascript复制delete 'student','95001','s_sex'
deleteall 'student','95001'
修改数据 在添加数据时,HBase会自动为添加的数据添加一个时间戳,故在需要修改数据时,只需直接添加数据,HBase即会生成一个新的版本,从而完成“改”操作,旧的版本依旧保留,系统会定时回收垃圾数据,只留下最新的几个版本,保存的版本数可以在创建表的时候指定。下面是一个操作的例子:
代码语言:javascript复制hbase(main):034:0> get 'student','95001'
COLUMN CELL
s_name: timestamp=1537497681798, value=LiYing
s_sex: timestamp=1537497682400, value=Male
s_course:english timestamp=1537497872225, value=90
s_course:math timestamp=1537497681859, value=80
4 row(s) in 0.0310 seconds
hbase(main):035:0> put 'student','95001','s_course:english','100'
0 row(s) in 0.0130 seconds
hbase(main):036:0> get 'student','95001'
COLUMN CELL
s_name: timestamp=1537497681798, value=LiYing
s_sex: timestamp=1537497682400, value=Male
s_course:english timestamp=1537498062541, value=100
s_course:math timestamp=1537497681859, value=80
4 row(s) in 0.0130 seconds
删除表 删除表有两步,第一步先让该表不可用,第二步删除表。直接drop未disable的表会失败。
代码语言:javascript复制disable 'student'
drop 'student'
查询历史的表
代码语言:javascript复制create 'teacher',{NAME=>'username',VERSIONS=>5}
put 'teacher','91001','username','Mary'
put 'teacher','91001','username','Mary1'
put 'teacher','91001','username','Mary2'
put 'teacher','91001','username','Mary3'
put 'teacher','91001','username','Mary4'
put 'teacher','91001','username','Mary5'
get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}
hbase(main):064:0> get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}
COLUMN CELL
username: timestamp=1537498459746, value=Mary5
username: timestamp=1537498455244, value=Mary4
username: timestamp=1537498455193, value=Mary3
username: timestamp=1537498455174, value=Mary2
username: timestamp=1537498455149, value=Mary1
5 row(s) in 0.0110 seconds
退出hbase
代码语言:javascript复制exit
授权
具备Create权限的namespace Admin可以对表创建和删除、生成和恢复快照
具备Admin权限的namespace Admin可以对表splits或major compactions
授权命名空间
授权zuser01用户对zns下的写权限
代码语言:javascript复制grant 'zuser01' 'W' '@zns'
回收zuser01用户对zns的所有权限
代码语言:javascript复制revoke 'zuser01''@zns'
当前用户:hbase
代码语言:javascript复制namespace_create 'ns_hbase'
grant 'zuser02', 'W', '@ns_hbase'
授权表
当前用户:zuser02
代码语言:javascript复制create 'ns_hbase.ztable01', 'name'
create 'ns_hbase.ztable02', 'name'
zuser02创建了两张表ztable01和ztable02,同时成为这两张表的owner,意味着有RWXCA
权限
此时,zuser02团队的另一名成员zuser03也需要获得ns_hbase下的权限,hbase管理员操作如下
如果希望zuser03可以访问已经存在的表,则hbase管理员操作如下
当前用户:hbase
代码语言:javascript复制grant 'zuser03', 'RW', 'ns_hbase.ztable01'
grant 'zuser03', 'RW', 'ns_hbase.ztable02'
不要只设置写权限
当前用户:hbase
代码语言:javascript复制grant 'zuser03', 'W', '@ns_hbase'
此时zuser03可以在ns_hbase下创建表,但是无法读、写、修改和删除ns_hbase下已存在的表
当前用户:zuser03
代码语言:javascript复制scan 'ns_hbase:ztable01'
报错AccessDeniedException
在HBase中启用授权机制
hbase-site.xml
代码语言:javascript复制<property>
<name>hbase.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hbase.coprocessor.master.classes</name>
<value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<property>
<name>hbase.coprocessor.region.classes</name>
<value>org.apache.hadoop.hbase.security.token.TokenProvider,org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
配置完成后需要重启HBase集群
Java操作
添加依赖
代码语言:javascript复制<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.10</version>
</dependency>
Java代码
代码语言:javascript复制package cn.psvmc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.net.URISyntaxException;
public class HbaseTest {
public static Connection getConn() throws IOException, URISyntaxException {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
/*
conf.addResource(new Path(ClassLoader.getSystemResource("hbase-site.xml").toURI()));
conf.addResource(new Path(ClassLoader.getSystemResource("core-site.xml").toURI()));
*/
return ConnectionFactory.createConnection(conf);
}
public static void close(Connection conn) throws IOException {
if (null != conn)
conn.close();
}
public static Table getTable(Connection conn, String tablename, String namespace) throws IOException {
TableName tableName1 = TableName.valueOf(namespace, tablename);
return conn.getTable(tableName1);
}
/**
* 添加值
* @param conn 连接
* @param tablename 表名
* @param namespace 命名空间
* @param rowkey 行键
* @param cf 列簇
* @param lie 列标识
* @param value 值
* @throws IOException
*/
public static void put(Connection conn, String tablename, String namespace, String rowkey, String cf, String lie, String value) throws IOException {
Table table = getTable(conn, tablename, namespace);
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(lie), Bytes.toBytes(value));
table.put(put);
table.close();
}
/**
* 获取数据
* @param conn 连接
* @param tablename 表名
* @param namespace 命名空间
* @param rowkey 行键
* @throws IOException
*/
public static void get(Connection conn, String tablename, String namespace, String rowkey) throws IOException {
Table table = getTable(conn, tablename, namespace);
Get get = new Get(Bytes.toBytes(rowkey));
Result result = table.get(get);
if (result != null) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
String row = Bytes.toString(CellUtil.cloneRow(cell));
String family = Bytes.toString(CellUtil.cloneFamily(cell));
String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
String value = Bytes.toString(CellUtil.cloneValue(cell));
System.out.printf("行:%s 列族: %s 列名: %s 值: %s%n", row, family, qualifier, value);
}
}
table.close();
}
/**
* 获取数据
* @param conn 连接
* @param tablename 表名
* @param rowkey 行键
* @throws IOException
*/
public static void get(Connection conn, String tablename, String rowkey) throws IOException {
get(conn,tablename,null,rowkey);
}
public static void main(String[] args) throws IOException, URISyntaxException {
Connection conn = HbaseTest.getConn();
HbaseTest.put(conn,"student","default","95001","s_course","yw","100");
HbaseTest.put(conn,"student","default","95001","s_name","zw","小明");
HbaseTest.get(conn,"student","95001");
}
}