HBase概述、安装、shell操作07

在这里插入图片描述

一、HBase概述

1.1 HBase的定义

HBase是一个分布式的、面向列的开源的非关系型数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable”。

1.2 HBase的特点

1)海量存储
HBase适合存储PB(1pb = 1024tb)级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与HBase的极易扩展性息息相关。正是因为HBase良好的扩展性,才为海量数据的存储提供了便利。
2)列式存储
这里的列式存储其实说的是列族存储,HBase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。
3)极易扩展
HBase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。
通过横向添加RegionSever的机器,进行水平扩展,提升HBase上层的处理能力,提升HBase服务更多Region的能力。
通过横向添加Datanode的机器,进行存储层扩容,提升HBase的数据存储能力和提升后端存储的读写能力。
4)高并发
由于目前大部分使用HBase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,是指:Hbase要把数据写到hdfs,再由hdfs写入磁盘,流程虽然繁琐,但其单个IO延迟下降的并不多,主要突出其架构的优越性。能获得高并发、低延迟的服务。
5)稀疏
稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。

1.3HBase表的逻辑结构

在这里插入图片描述

1.4HBase表的物理结构

在这里插入图片描述

1.5HBase数据模型

1 1 ) Name Space
命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。
2 2 ) Region
类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往 HBase 写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase 能够轻松应对字段变更的场景。
3 3 ) Row
HBase 表中的每行数据都由一个 y RowKey 和多个 Column(列)组成,数据是按照 RowKey的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重
要。
4 4 ) Column
HBase 中的每个列都由 Column Family(列族)和 Column Qualifier(列限定符)进行限定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。
5 5 ) Time Stamp
用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。
6 6 ) Cell
由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell 中的数
据是没有类型的,全部是字节码形式存贮。

二、HBase安装

2.1 部署Zookeeper

首先保证Zookeeper集群的正常部署并启动:
[root@hadoop003 zookeeper-3.4.10]$ bin/zkServer.sh start
[root@hadoop004 zookeeper-3.4.10]$ bin/zkServer.sh start
[root@hadoop005 zookeeper-3.4.10]$ bin/zkServer.sh start

2.2 部署Hadoop

Hadoop集群的正常部署并启动:
[root@hadoop003 hadoop-2.7.2]$ sbin/start-dfs.sh
[root@hadoop004 hadoop-2.7.2]$ sbin/start-yarn.sh

2.3 安装部署HBase

解压HBase到指定目录:
[root@hadoop003 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module
修改HBase配置文件
1)hbase-env.sh修改内容
export JAVA_HOME=/opt/module/jdk1.8.0_144
export HBASE_MANAGES_ZK=false
2)vim hbase-site.xml修改内容

<configuration>
	<property>     
		<name>hbase.rootdir</name>     
		<value>hdfs://hadoop003:9000/hbase</value>   
	</property>

	<property>   
		<name>hbase.cluster.distributed</name>
		<value>true</value>
	</property>

   <!-- 0.98后的新变动,之前版本没有port,默认端口为60000 -->
	<property>
		<name>hbase.master.port</name>
		<value>16000</value>
	</property>

	<property>   
		<name>hbase.zookeeper.quorum</name>
	     <value>hadoop003:2181,hadoop004:2181,hadoop005:2181</value>
	</property>

	<property>   
		<name>hbase.zookeeper.property.dataDir</name>
	     <value>/opt/module/zookeeper-3.4.10/zkData</value>
	</property>
</configuration>

3)regionservers:
hadoop003
hadoop004
hadoop005

4)软链接Hadoop配置文件到HBase
[root@hadoop003 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml /opt/module/hbase-1.3.1/conf/core-site.xml
[root@hadoop003 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml /opt/module/hbase-1.3.1/conf/hdfs-site.xml

5)HBase安装目录远程同步到集群其他服务器
scp -r /opt/module/hbase-1.3.1/ hadoop004:/opt/module/

6)启动HBase服务
[root@hadoop003 hbase]$ bin/start-hbase.sh
对应的停止服务:
[root@hadoop003 hbase]$ bin/stop-hbase.sh

7)查看HBase界面
启动成功后,可以通过“host:port”的方式来访问HBase管理页面,例如:
http://hadoop003:16010
在这里插入图片描述

三、HBase Shell操作

3.1 进入HBase客户端命令行(任意节点均可)

[root@hadoop003 hbase]$ bin/hbase shell

3.2 库namespace

增:
create_namespace ‘offcn’
删:
drop_namespace ‘offcn’
改:
–修改NameSpace的属性
alter_namespace ‘ns1’, {METHOD => ‘set’, ‘PROPERTY_NAME’ => ‘PROPERTY_VALUE’}
查:
list_namespace

3.2 表

增:
create ‘t1’, ‘f1’, ‘f2’, ‘f3’
create ‘offcn:student’,‘basic’,‘extends’
创建表 必须指定列族
删:
drop ‘offcn:student’(不写namespace则是默认namespace下的表)
ERROR: Table offcn:student is enabled. Disable it first.先禁用表,再删除表
disable ‘offcn:student’
drop ‘offcn:student’
改:
alter ‘student’, {NAME => ‘info’, VERSIONS => 5} 开启多版本
get ‘student’,‘1001’,{COLUMN=>‘info:age’,VERSIONS=>‘3’}查看最新的几个版本值
查:
list
describe ‘student’==desc 'student 查看表结构

3.3 数据

增:
hbase(main):004:0> put ‘student’,‘1001’,‘info:age’,‘18’
hbase(main):005:0> put ‘student’,‘1002’,‘info:name’,‘Janna’
hbase(main):006:0> put ‘student’,‘1002’,‘info:sex’,‘female’
hbase(main):007:0> put ‘student’,‘1002’,‘info:age’,‘20’
删:
delete ‘ns1:t1’, ‘r1’, ‘c1’, ts1 删除某条数据
delete ‘student’, ‘002’, ‘basic:sex’
deleteall ‘student’,‘001’
truncate 'student’清空表数据
提示:清空表的操作顺序为先 disable,然后再 truncate。
改:
put ‘student’,‘1001’,‘info:age’,‘100’
查:
get查看具体值
get ‘student’,‘1001’
get ‘student’,‘1001’,‘info:name’
get ‘student’,‘1001’,{COLUMN=>‘info:age’,VERSIONS=>‘3’}查看最新的几个版本值
scan ‘student’–全表扫描
–根据rowkey的范围查询
scan ‘student’,{STARTROW => ‘1001’}
scan ‘student’, {COLUMNS => ‘basic:name’, LIMIT => 2, STARTROW => ‘001’}
scan ‘student’, {COLUMNS => ‘basic:name’, STARTROW => ‘001’,ENDROW => ‘003’}

3.4 其他

count  统计行数
status 
version 查看habse版本
whoami 

四、Java API操作HBase

环境准备

新建项目后在pom.xml中添加依赖:

junit junit RELEASE org.apache.hbase hbase-client 1.3.1

HBase API

1.获取Configuration对象

Configuration conf = null;
@Before
public void test()throws Exception {
    conf = HBaseConfiguration.create();
    conf.set("hbase.zookeeper.quorum","hadoop003,hadoop004,hadoop005");
    conf.set("hbase.zookeeper.property.clientPort","2181");
}

2.判断表是否存在

@Test//  判断表是否存在
public void testTableExist()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象
    Admin admin = conn.getAdmin();
    // 3 利用admin对象进行操作hbase
    boolean stu = admin.tableExists(TableName.valueOf("student"));
    System.out.println("表是否存在:"+stu);
    // 4 关闭连接
    admin.close();
    conn.close();
}

3.创建表

@Test//  创建表
public void testTableCreate()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象
    Admin admin = conn.getAdmin();
    // 3 利用admin对象进行操作hbase
    HTableDescriptor table = new HTableDescriptor(TableName.valueOf("stu"));
    HColumnDescriptor family = new HColumnDescriptor("info");
    table.addFamily(family);
    admin.createTable(table);
    System.out.println("表创建成功");
    // 4 关闭连接
    admin.close();
    conn.close();
}

4.删除表

@Test//  删除表
public void testTableDrop()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象
    Admin admin = conn.getAdmin();
    // 3 利用admin对象进行操作hbase 先禁用掉表,再删除表
    admin.disableTable(TableName.valueOf("stu"));
    admin.deleteTable(TableName.valueOf("stu"));
    System.out.println("表删除成功");
    // 4 关闭连接
    admin.close();
    conn.close();
}

5.向表中插入数据

@Test//  向表中插入数据
public void testInsertData()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象 表的操作用Admin对象来完成,
    // 而数据的操作,要用Table对象来实现
    Table stuTable = conn.getTable(TableName.valueOf("stu"));
    // 3 利用Table对象进行操作 把行键的字节数组传递进put对象,而且要注意,不要用
    // jdk自带的转变字节数组的方法
    //Put put = new Put(Bytes.toBytes("1001"));
    //参数1:列族名称
    //参数2:列名称
    //参数3:列值
    //put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("zhangsan"));
    //put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("18"));

    Put put = new Put(Bytes.toBytes("1002"));
    put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("lisi"));
    put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("19"));

    Put put2 = new Put(Bytes.toBytes("1003"));
    put2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("wangwu"));
    put2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("20"));
	//批量插入
    List<Put> putList = new ArrayList<Put>();
    putList.add(put);
    putList.add(put2);

    stuTable.put(putList);
    System.out.println("数据插入成功");
    // 4 关闭连接
    stuTable.close();
    conn.close();
}

6.删除一行&多行数据

@Test//  从表中删除数据
public void testDeleteData()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象 表的操作用Admin对象来完成,
    // 而数据的操作,要用Table对象来实现
    Table stuTable = conn.getTable(TableName.valueOf("stu"));
    // 3 利用Table对象进行操作 把行键的字节数组传递进put对象
    //Delete delete = new Delete(Bytes.toBytes("1003"));
    //delete.addFamily(Bytes.toBytes("info"));
    //delete.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"));

    Delete delete = new Delete(Bytes.toBytes("1002"));
    Delete delete2 = new Delete(Bytes.toBytes("1003"));
    delete2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"));

    List<Delete> deleteList = new ArrayList<Delete>();
    deleteList.add(delete);
    deleteList.add(delete2);

    stuTable.delete(deleteList);
    // 4 关闭连接
    stuTable.close();
    conn.close();
}

7.获取所有数据

@Test//  获取所有数据
public void testGetAllData()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象 表的操作用Admin对象来完成,
    // 而数据的操作,要用Table对象来实现
    Table stuTable = conn.getTable(TableName.valueOf("stu"));
    // 3 利用Table对象进行操作 把行键的字节数组传递进put对象
    Scan scan = new Scan();
    ResultScanner scanner = stuTable.getScanner(scan);
    for (Result result : scanner) {
        //这是封装的某个rowkey的所有数据
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
            String family = Bytes.toString(CellUtil.cloneFamily(cell));
            String column = Bytes.toString(CellUtil.cloneQualifier(cell));
            String value = Bytes.toString(CellUtil.cloneValue(cell));
            System.out.println(rowkey+"-"+family+"-"+column+"-"+value);
        }
        System.out.println("=========================");
    }

    // 4 关闭连接
    stuTable.close();
    conn.close();
}

8.获取某一行数据,指定列族,列

@Test//  获取某个rowkey的数据
public void testGetOneData()throws Exception {
    // 1 通过配置对象获取连接
    Connection conn = ConnectionFactory.createConnection(conf);
    // 2 通过连接,拿到admin对象 表的操作用Admin对象来完成,
    // 而数据的操作,要用Table对象来实现
    Table stuTable = conn.getTable(TableName.valueOf("stu"));
    // 3 利用Table对象进行操作 把行键的字节数组传递进put对象
    //Get get = new Get(Bytes.toBytes("1002"));
    //get.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"));
    Get get = new Get(Bytes.toBytes("1002"));
    Get get2 = new Get(Bytes.toBytes("1003"));
    List<Get> getList = new ArrayList<Get>();
    getList.add(get);
    getList.add(get2);
    Result[] results = stuTable.get(getList);
    for (Result result : results) {
        //这是封装的某个rowkey的所有数据
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
            String family = Bytes.toString(CellUtil.cloneFamily(cell));
            String column = Bytes.toString(CellUtil.cloneQualifier(cell));
            String value = Bytes.toString(CellUtil.cloneValue(cell));
            System.out.println(rowkey+"-"+family+"-"+column+"-"+value);
        }
        System.out.println("========");
    }
    // 4 关闭连接
    stuTable.close();
    conn.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值