阅读 138

海量列式非关系数据库HBase 架构,shell与API

HBase的特点:

  • 海量存储: 底层基于HDFS存储海量数据

  • 列式存储:HBase表的数据是基于列族进行存储的,一个列族包含若干列

  • 极易扩展:底层依赖HDFS,当磁盘空间不足的时候,只需要动态增加DataNode服务节点就可以

  • 高并发:支持高并发的读写请求

  • 稀疏:稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情 况下,是不会占用存储空间的。

  • 数据的多版本:HBase表中的数据可以有多个版本值,默认情况下是根据版本号去区分,版本号就 是插入数据的时间戳

  • 数据类型单一:所有的数据在HBase中是以字节数组进行存储

HBase的应用场景:

  HBase适合海量明细数据的存储,并且后期需要有很好的查询性能(单表超千万、上亿, 且并发要求高)

HBase数据模型:

 

HBase整体架构:

 

 

 Zookeeper

  • 实现了HMaster的高可用

  • 保存了HBase的元数据信息,是所有HBase表的寻址入口

  • 对HMaster和HRegionServer实现了监控

HMaster(Master)

  • 为HRegionServer分配Region 维护整个集群的负载均衡

  • 维护集群的元数据信息

  • 发现失效的Region,并将失效的Region分配到正常的HRegionServer上

HRegionServer(RegionServer)

  • 负责管理Region 接受客户端的读写数据请求

  • 切分在运行过程中变大的Region

Region

  • 每个HRegion由多个Store构成, 每个Store保存一个列族(Columns Family),表有几个列族,则有几个Store,

  • 每个Store由一个MemStore和多个StoreFile组成,MemStore是Store在内存中的内容,写到文件 后就是StoreFile。

  • StoreFile底层是以HFile的格式保存

HBase shell 基本操作:

入口:hbase shell

hbase(main):001:0> create 'lagou', 'base_info', 'extra_info'或者(Hbase建表必须指定列族信息)create 'lagou', {NAME => 'base_info', VERSIONS => '3'},{NAME =>'extra_info',VERSIONS => '3'}
VERSIONS 是指此单元格内的数据可以保留最近的 3 个版本

添加数据操作:

复制代码

, , , , , , , , ,

复制代码

查询,更新,删除:

复制代码

获取表中row key为rk1的所有信息
get 'lagou', 'rk1'获取lagou表中row key为rk1,base_info列族的所有信息
get 'lagou', 'rk1', 'base_info'获取表中row key为rk1,base_info列族的name、age列标示符的信息
get 'lagou', 'rk1', 'base_info:name', 'base_info:age'获取lagou表中row key为rk1,base_info、extra_info列族的信息
hbase(main):010:0> get 'lagou', 'rk1', 'base_info', 'extra_info'或者
hbase(main):011:0> get 'lagou', 'rk1', {COLUMN => ['base_info', 'extra_info']}
或者
hbase(main):012:0> get 'lagou', 'rk1', {COLUMN => ['base_info:name',
'extra_info:address']}

获取表中row key为rk1,cell的值为wang的信息
get 'lagou', 'rk1', {FILTER => "ValueFilter(=,'binary:wang')"}

获取表中row key为rk1,列标示符中含有a的信息
get 'lagou', 'rk1', {FILTER => "
(QualifierFilter(=,'substring:a'))"}

查询lagou表中的所有信息:
 scan 'lagou'查询表中列族为 base_info 的信息:
hbase(main):001:0> scan 'lagou', {COLUMNS => 'base_info'}
hbase(main):002:0> scan 'lagou', {COLUMNS => 'base_info', RAW => true, VERSIONS=> 3}
## Scan时可以设置是否开启Raw模式,开启Raw模式会返回包括已添加删除标记但是未实际删除的数据
## VERSIONS指定查询的最大版本数

指定多个列族与按照数据值模糊查询:
查询lagou表中列族为 base_info 和 extra_info且列标示符中含有a字符的信息

hbase(main):001:0> scan 'lagou', {COLUMNS => ['base_info', 'extra_info'], FILTER=> "(QualifierFilter(=,'substring:a'))"}

rowkey的范围值查询(非常重要)
查询lagou表中列族为base_info,rk范围是[rk1, rk3)的数据(rowkey底层存储是字典序)
按rowkey顺序存储。
scan 'lagou', {COLUMNS => 'base_info', STARTROW => 'rk1',
ENDROW => 'rk3'}

查询lagou表中row key以rk字符开头的
hbase(main):001:0> scan 'lagou',{FILTER=>"PrefixFilter('rk')"}

 更新数据值:
把lagou表中rowkey为rk1的base_info列族下的列name修改为liang
put 'lagou', 'rk1', 'base_info:name', 'liang'


删除数据和表:
删除lagou表row key为rk1,列标示符为 base_info:name 的数据
> delete 'lagou', 'rk1', 'base_info:name'

指定rowkey,列名以及时间戳信息进行删除
删除lagou表row key为rk1,列标示符为base_info:name的数据
delete 'lagou', 'rk1', 'base_info:name',1600660619655

删除 base_info 列族
 alter 'lagou', 'delete' => 'base_info'

删除lagou表数据
truncate 'lagou'

删除lagou表
#先disable 再drop
hbase(main):036:0> disable 'lagou'
hbase(main):037:0> drop 'lagou'
#如果不进行disable,直接drop会报错
ERROR: Table user is enabled. Disable it first.

复制代码

HBase JAVA  API:

复制代码

<dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>1.3.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.14.3</version><scope>test</scope></dependency></dependencies>

复制代码

创建连接:

复制代码

package com.lagou.hbase.client;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.*;import org.apache.hadoop.hbase.client.*;import org.apache.hadoop.hbase.util.Bytes;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.io.IOException;public class HbaseClientDemo {
    Configuration conf = null;
    Connection conn = null;

    @Before    public void init() throws IOException {        //获取一个配置文件对象
        conf = HBaseConfiguration.create();

        conf.set("hbase.zookeeper.quorum", "linux121,linux122");
        conf.set("hbase.zookeeper.property.clientPort", "2181");        //通过conf获取到hbase集群的连接
        conn = ConnectionFactory.createConnection(conf);
    }    //释放连接    @After    public void realse() {        if (conn != null) {            try {
                conn.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

复制代码

 

 

创建表:

复制代码

 //创建一张hbase表    @Test    public void createTable() throws IOException {        //获取HbaseAdmin对象用来创建表
        HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();        //创建Htabledesc描述器,表描述器
        final HTableDescriptor worker = new HTableDescriptor(TableName.valueOf("worker"));        //指定列族
        worker.addFamily(new HColumnDescriptor("info"));
        admin.createTable(worker);
        System.out.println("worker表创建成功!!");
    }

复制代码

 

插入数据:

复制代码

  //插入一条数据    @Test    public void putData() throws IOException {        //需要获取一个table对象
        final Table worker = conn.getTable(TableName.valueOf("worker"));        //准备put对象
        final Put put = new Put(Bytes.toBytes("110"));//指定rowkey
        put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("addr"), Bytes.toBytes("beijing"));        //插入数据,参数类型是put        worker.put(put);        //准备list<puts>,可以执行批量插入        //关闭table对象        worker.close();
        System.out.println("插入数据到worker表成功!!");
    }

复制代码

 

查询数据:

复制代码

//查询数据    @Test    public void getData() throws IOException {        //准备table对象
        final Table worker = conn.getTable(TableName.valueOf("worker"));        //准备get对象
        final Get get = new Get(Bytes.toBytes("110"));        //指定查询某个列族或者列
        get.addFamily(Bytes.toBytes("info"));        //执行查询
        final Result result = worker.get(get);        //获取到result中所有cell对象
        final Cell[] cells = result.rawCells();        //遍历打印
        for (Cell cell : cells) {            final String rowkey = Bytes.toString(CellUtil.cloneRow(cell));            final String f = Bytes.toString(CellUtil.cloneFamily(cell));            final String column = Bytes.toString(CellUtil.cloneQualifier(cell));            final String value = Bytes.toString(CellUtil.cloneValue(cell));

            System.out.println("rowkey-->" + rowkey + "--;cf-->" + f + "---;column--->" + column + "--;value-->" + value);
        }
        worker.close();
    }

复制代码

删除数据:

复制代码

   //删除一条数据    @Test    public void deleteData() throws IOException {        //需要获取一个table对象
        final Table worker = conn.getTable(TableName.valueOf("worker"));        //准备delete对象
        final Delete delete = new Delete(Bytes.toBytes("110"));//执行删除        worker.delete(delete);        //关闭table对象        worker.close();
        System.out.println("删除数据成功!!");
    }

复制代码

 

 

通过Scan全表扫描:

复制代码

/*** 全表扫描*/@Testpublic void scanAllData() throws IOException {
HTable teacher = (HTable) conn.getTable(TableName.valueOf("teacher"));
Scan scan = new Scan();
ResultScanner resultScanner = teacher.getScanner(scan);for (Result result : resultScanner) {
Cell[] cells = result.rawCells();//获取改行的所有cell对象for (Cell cell : cells) {//通过cell获取rowkey,cf,column,valueString cf = Bytes.toString(CellUtil.cloneFamily(cell));
String column = Bytes.toString(CellUtil.cloneQualifier(cell));
String value = Bytes.toString(CellUtil.cloneValue(cell));
String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
System.out.println(rowkey + "----" + cf + "--" + column + "---"
+ value);
}
}
teacher.close();

}

复制代码

通过startRowKey和endRowKey进行扫描:

复制代码

//指定scan 开始rowkey和结束rowkey,这种查询方式建议使用,指定开始和结束rowkey区间避免全表扫描@Testpublic void scanStartEndData() throws IOException {    //准备table对象
    final Table worker = conn.getTable(TableName.valueOf("worker"));    //准备scan对象
    final Scan scan = new Scan();    //指定查询的rowkey区间,rowkey在hbase中是以字典序排序
    scan.setStartRow(Bytes.toBytes("001"));
    scan.setStopRow(Bytes.toBytes("004"));    //执行扫描
    final ResultScanner resultScanner = worker.getScanner(scan);    for (Result result : resultScanner) {        //获取到result中所有cell对象
        final Cell[] cells = result.rawCells();        //遍历打印
        for (Cell cell : cells) {            final String rowkey = Bytes.toString(CellUtil.cloneRow(cell));            final String f = Bytes.toString(CellUtil.cloneFamily(cell));            final String column = Bytes.toString(CellUtil.cloneQualifier(cell));            final String value = Bytes.toString(CellUtil.cloneValue(cell));
            System.out.println("rowkey-->" + rowkey + "--;cf-->" + f + ";column--->" + column + "--;value-->" + value);
        }
    }

    worker.close();
}

复制代码

来源 https://www.cnblogs.com/wanghzh/p/15270164.html


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐