尚硅谷HBase

本文详细介绍了HBase的基本概念,包括其分布式、稀疏的数据模型,以及HBase的MemStore、WAL、RegionSplit等核心概念。还涵盖了HBase的Shell操作和API使用,包括创建、查询、删除表的操作,以及数据的写入与删除流程。此外,文章讨论了HBase的数据真正删除时间,强调了在flush和MajorCompaction时的数据清理过程。
摘要由CSDN通过智能技术生成

目录

一、HBase简介

1.1 HBase 定义

1.2 HBase 数据模型

1.2.1 HBase 逻辑结构

 1.2.2 HBase 物理存储结构

 1.2.3 数据模型

1.3 HBase 基本框架 

二、HBase 快速入门

2.1 HBase Shell操作

 2.1.1 基本操作

2.1.2  DDL

2.1.3 DML

三、HBase 进阶

3.1 架构原理

3.2 写流程

 3.3 MemStore Flush

 3.4 读流程

3.5 HBase的合并与拆分

3.5.1 StoreFile Compaction

3.5.2 Region Split  

3.6 数据真正删除时间

四、HBase API

4.1 DDL

4.1.1 判断表是否存在

 4.1.2 创建表

4.1.3 删除表

4.1.4 创建命名空间

4.2 DML

4.2.1 向表中插入数据

4.2.2 获取数据(get)

4.2.3 获取数据 (scan)

4.2.4 删除表中的数据

4.3.1 关闭资源

4.4.1 总的代码


一、HBase简介

1.1 HBase 定义

        HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。

1.2 HBase 数据模型

 

HBase 的设计理念依据 Google 的 BigTable 论文,论文中对于数据模型的首句介绍。

Bigtable 是一个稀疏的、分布式的、持久的多维排序 map。

对于映射的解释如下

该映射由行键、列键和时间戳索引;映射中的每个值都是一个未解释的字节数组。

最终 HBase 关于数据模型和 BigTable 的对应关系如下

HBase 使用与 Bigtable 非常相似的数据模型。用户将数据行存储在带标签的表中。数 据行具有可排序的键和任意数量的列。该表存储稀疏,因此如果用户喜欢,同一表中的行可 以具有疯狂变化的列。

最终理解 HBase 数据模型的关键在于稀疏、分布式、多维、排序的映射。其中映射 map 指代非关系型数据库的 key-Value 结构。


1.2.1 HBase 逻辑结构

 1.2.2 HBase 物理存储结构

 1.2.3 数据模型

1.3 HBase 基本框架 

Master

主要进程,具体实现类为HMaster,通常部署在namenode上。

功能:负责通过ZK监控RegionServer进程状态,同时是所有元数据变化 的接口。内部启动监控执行region的故障转移和拆分的线程。

RegionServer

主要进程,具体实现类为HRegionServer,部署在datanode上。 功能:主要负责数据cell的处理。同时在执行区域的拆分和合并的时候, 由RegionServer来实际执行。

二、HBase 快速入门

2.1 HBase Shell操作

 2.1.1 基本操作

 1)进入Hbase客户端命令行

 2)查看帮助命令

2.1.2  DDL

1)创建表

在 bigdata 命名空间中创建表格 student,两个列族。info 列族数据维护的版本数为 5 个, 如果不写默认版本数为 1。

hbase:005:0> create 'bigdata:student', {NAME => 'info', VERSIONS => 5}, {NAME => 'msg'}

如果创建表格只有一个列族,没有列族属性,可以简写。

如果不写命名空间,使用默认的命名空间 default。

hbase:006:0> create 'student1','info'


2)查看表

查看表有两个命令:list 和 describe

list:查看所有的表名

hbase:008:0> list


 


describe:查看一个表的详情

hbase:009:0> describe 'student1'


3)修改表

表名创建时写的所有和列族相关的信息,都可以后续通过 alter 修改,包括增加删除列 族。

(1)增加列族和修改信息都使用覆盖的方法

hbase:010:0> alter 'student1', {NAME => 'f1', VERSIONS => 3}


 


(2)删除信息使用特殊的语法

hbase:011:0>  alter 'student1', NAME => 'f1', METHOD => 'delete'
hbase:012:0> alter 'student1', 'delete' => 'f1'


 

 
4)删除表

shell 中删除表格,需要先将表格状态设置为不可用

hbase:013:0> disable 'student1'
hbase:014:0> drop 'student1'


2.1.3 DML

1)写入数据 

在 HBase 中如果想要写入数据,只能添加结构中最底层的 cell。可以手动写入时间戳指 定 cell 的版本,推荐不写默认使用当前的系统时间。

hbase:015:0> put 'bigdata:student','1001','info:name','zhangsan'
hbase:016:0> put 'bigdata:student','1001','info:name','lisi'
hbase:017:0> put 'bigdata:student','1001','info:age','18'

2)读取数据 

读取数据的方法有两个:get 和 scan。

get 最大范围是一行数据,也可以进行列的过滤,读取数据的结果为多行 cell。


也可以修改读取 cell 的版本数,默认读取一个。最多能够读取当前列族设置的维护版本 数。


scan 是扫描数据,能够读取多行数据,不建议扫描过多的数据,推荐使用 startRow 和 stopRow 来控制读取的数据,默认范围左闭右开。


实际开发中使用 shell 的机会不多,所有丰富的使用方法到 API 中介绍

3)删除数据

删除数据的方法有两个:delete 和 deleteall。

delete 表示删除一个版本的数据,即为 1 个 cell,不填写版本默认删除最新的一个版本

hbase:023:0> delete 'bigdata:student','1001','info:name'


deleteall 表示删除所有版本的数据,即为当前行当前列的多个 cell。(执行命令会标记 数据为要删除,不会直接将数据彻底删除,删除数据只在特定时期清理磁盘时进行)

hbase:024:0> deleteall 'bigdata:student','1001','info:name'


 

三、HBase 进阶

3.1 架构原理

1)StoreFile

保存实际数据的物理文件,StoreFile以HFile的形式存储在HDFS上。每个Store会有一个或多个StoreFile,数据在每个StoreFile中都是有序的。

2)MemStore
写缓存,由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中,排好
序后,等到达刷写时机才会刷写到 HFile ,每次刷写都会形成一个新的 HFile ,写入到对应的
文件夹 store 中。
3)WAL
由于数据要经 MemStore 排序后才能刷写到 HFile ,但把数据保存在内存中会有很高的
概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件
中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重
建。
4)BlockCache
读缓存,每次查询出的数据会缓存在 BlockCache 中,方便下次查询。

3.2 写流程

2)写流程:
写流程顺序正如 API 编写顺序,首先创建 HBase 的重量级连接
1 )首先访问 zookeeper ,获取 hbase:meta 表位于哪个 Region Server
(2)访问对应的 Region Server ,获取 hbase:meta 表,将其缓存到连接中,作为连接属
MetaCache ,由于 Meta 表格具有一定的数据量,导致了创建连接比较慢;
之后使用创建的连接获取 Table ,这是一个轻量级的连接,只有在第一次创建的时候会
检查表格是否存在访问 RegionServer ,之后在 获取 Table 不会访问 RegionServer
(3)调用 Table put 方法写入数据,此时还需要解析 RowKey ,对照缓存的 MetaCache
查看具体写入的位置有哪个 RegionServer
(4)将数据顺序写入(追加)到 WAL ,此处写入是直接落盘的,并设置专门的线程控
WAL 预写日志的滚动(类似 Flume );
(5)根据写入命令的 RowKey ColumnFamily 查看具体写入到哪个 MemStory ,并且
MemStory 中排序;
(6)向客户端发送 ack
(7)等达到 MemStore 的刷写时机后,将数据刷写到对应的 story 中。

 3.3 MemStore Flush

MemStore 刷写(flush)时机:

  

 

 3.4 读流程

 

3.5 HBase的合并与拆分

3.5.1 StoreFile Compaction

        由于 memstore 每次刷写都会生成一个新的 HFile ,文件过多读取不方便,所以会进行文
件的合并,清理掉过期和删除的数据,会进行 StoreFile Compaction
Compaction 分为两种,分别是 Minor Compaction Major Compaction Minor Compaction
会将临近的若干个较小的 HFile 合并成一个较大的 HFile ,并 清理掉部分过期和删除的数据
有系统使用一组参数自动控制, Major Compaction 会将一个 Store 下的所有的 HFile 合并成
一个大 HFile ,并且 清理掉所有过期和删除的数据 ,由参数 hbase.hregion.majorcompaction
控制,默认 7 天。   

Minor Compaction 控制机制:
参与到小合并的文件需要通过参数计算得到,有效的参数有 5
(1) hbase.hstore.compaction.ratio (默认 1.2F 合并文件选择算法中使用的比率。
(2) hbase.hstore.compaction.min (默认 3 Minor Compaction 的最少文件个数。
(3) hbase.hstore.compaction.max (默认 10 Minor Compaction 最大文件个数。
(4) hbase.hstore.compaction.min.size (默认 128M 为单个 Hfile 文件大小最小值,小于这
个数会被合并。
(5) hbase.hstore.compaction.max.size (默认 Long.MAX_VALUE 为单个 Hfile 文件大小最大
值,高于这个数不会被合并。
小合并机制为拉取整个 store 中的所有文件,做成一个集合。之后按照从旧到新的顺序遍历。
判断条件为:
过小合并,过大不合并
文件大小 / hbase.hstore.compaction.ratio < ( 剩余文件大小和 ) 则参与压缩。所有把比值设
置过大,如 10 会最终合并为 1 个特别大的文件,相反设置为 0.4 ,会最终产生 4 storeFile
不建议修改默认值
满足压缩条件的文件个数达不到个数要求(3 <= count <= 10)则不压缩。

3.5.2 Region Split  

        Region 切分分为两种,创建表格时候的预分区即自定义分区,同时系统默认还会启动一
个切分规则,避免单个 Region 中的数据量太大。   
 
预分区(自定义分区)
每一个 region 维护着 startRow endRowKey ,如果加入的数据符合某个 region 维护的
rowKey 范围,则该数据交给这个 region 维护。那么依照这个原则,我们可以将数据所要投
放的分区提前大致的规划好,以提高 HBase 性能。
系统拆分
Region 的拆分是由 HRegionServer 完成的,在操作之前需要通过 ZK 汇报 master ,修改
对应的 Meta 表信息添加两列 info splitA info splitB 信息。之后需要操作 HDFS 上面对
应的文件,按照拆分后的 Region 范围进行标记区分, 实际操作为创建文件引用,不会挪动
数据 。刚完成拆分的时候, 两个 Region 都由原先的 RegionServer 管理 。之后汇报给 Master
Master 将修改后的信息写入到 Meta 表中。等待下一次触发负载均衡机制,才会修改 Region
的管理服务者,而 数据要等到下一次压缩时,才会实际进行移动
不管是否使用预分区,系统都会默认启动一套 Region 拆分规则。不同版本的拆分规则
有差别。系统拆分策略的父类为 RegionSplitPolicy

3.6 数据真正删除时间

1.Flash时也会删除数据put进两条数据,scan只显示一个时间戳大的,显示多版本才会出现两个这时flash表一下,显示多版本也只会显示一个时间戳大的。再put一条数据,刷写一下,显示多版本的时候会包括之前的那个Flash刷写时把同一个内存中的删除,刷写时只管内存空间,也就是刷写成功的写入磁盘的是不会删除的。
2.合并时会删除数据这时会把之前的旧版本都删除掉Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期和删除的数据。

总结:在Flash或者Major Compaction时会删除数据,Flash删除的时同一个内存的旧数据,不能删除跨越的多文件,Flash待删除的数据只能在同一个内存中。Major Compaction,将多个文件合并,在内存中都做过比较了。再put一条数据,把他删除掉,然后flash,显示多版本不会出现这个数据内容(在同一个内存flash会把他删除),但是会有这条数据的状态 type=deletecolumn。在合并的时候会删除掉这个状态。再合并时删除不在flash里删除是因为flash删除的只是在内存的数据。

例子:put 1 flash生成新文件put 2 flash生成新文件put 3 在内存时把他删掉,flash生成新文件,这里只要delete状态,如果这个时候删除掉delete状态flash新文件就会把put2的内容刷下来。所以在合并时在删除。其他数据会和删除标记就是那个状态比较不然会出现刷写到之前的文件数据。
 

四、HBase API

4.1 DDL

通用编写为静态代码块

 private static  Connection connection=null;
    private static Admin admin=null;

    static {
        try {
            //1.获取配置信息
            //新的
            Configuration configuration = HBaseConfiguration.create();
            configuration.set("hbase.zookeeper.quorum","192.168.189.144,192.168.189.145,192.168.189.146");

            //2.创建连接对象
            connection=ConnectionFactory.createConnection(configuration);

            //3.创建Admin对象
            admin=connection.getAdmin();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

4.1.1 判断表是否存在

 //1.判断表是否存在
    public static boolean isTableExist(String tableName) throws IOException {
        //1.获取配置文件信息
        //过时的
        //HBaseConfiguration configuration = new HBaseConfiguration();

        //新的
//        Configuration configuration = HBaseConfiguration.create();
//        configuration.set("hbase.zookeeper.quorum","192.168.189.144,192.168.189.145,192.168.189.146");
//
//        //2.获取管理员对象
//        //过时的
//        //HBaseAdmin hBaseAdmin = new HBaseAdmin(configuration);
//
//        //新的
//        Connection connection = ConnectionFactory.createConnection(configuration);
//        Admin admin = connection.getAdmin();


        //3.判断表是否存在
        //boolean exists = admin.tableExists(tableName);
        boolean exists = admin.tableExists(TableName.valueOf(tableName));

        //4.关闭连接
        //admin.close();

        //5.返回结果
        return exists;
    }

 4.1.2 创建表

 //2.创建表
    public static void createTable(String tableName,String...cfs) throws IOException {
        //1.判断是否存在列族信息
        if(cfs.length<=0){
            System.out.println("请设置列族信息!");
            return;
        }

        //2.判断表是否存在
        if(isTableExist(tableName)){
            System.out.println(tableName+"表已经存在");
            return;
        }

        //3.创建表描述器
        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));

        //4.循环添加列族信息
        for(String cf:cfs){
            //5.创建列族描述器
            HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);

            //6.添加具体的列族信息
            hTableDescriptor.addFamily(hColumnDescriptor);
        }


        //7.创建表
        admin.createTable(hTableDescriptor);
    }

4.1.3 删除表

//3.删除表
    public static void dropTable(String tableName) throws IOException {
        //1.判断表是否存在
        if(!isTableExist(tableName)){
            System.out.println(tableName+"表不存在");
            return;
        }

        //2.使表下线
        admin.disableTable(TableName.valueOf(tableName));

        //3.删除表
        admin.deleteTable(TableName.valueOf(tableName));
    }

4.1.4 创建命名空间

 public static void createNameSpace(String ns){
        //1.创建命名空间描述器
        NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(ns).build();

        //2.创建命名空间
        try {
            admin.createNamespace(namespaceDescriptor);
        } catch (NamespaceExistException e) {
            System.out.println(ns+"命名空间已存在");
        }catch(IOException e){
            e.printStackTrace();
        }

        System.out.println("我来了");
    }

4.2 DML

4.2.1 向表中插入数据

 public static void putData(String tableName,String rowKey,String cf,String cn,String value) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.创建Put对象
        Put put = new Put(Bytes.toBytes(rowKey));

        //3.给Put对象赋值
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));

        //4.插入数据
        table.put(put);

        //5.关闭表连接
        table.close();
    }

4.2.2 获取数据(get)

 public static void getData(String tableName,String rowKey,String cf,String cn) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.创建Get对象
        Get get = new Get(Bytes.toBytes(rowKey));

        //2.1 指定获取的列族
        get.addFamily(Bytes.toBytes(cf));

        //2.2 指定获取的列族和列
        get.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn));

        //2.3 设置获取数据的版本数
        get.setMaxVersions(5);

        //3.获取数据
        Result result = table.get(get);

        //4.解析result并打印
        for(Cell cell:result.rawCells()){
         //5.打印数据
            System.out.println("CF:"+Bytes.toString(CellUtil.cloneFamily(cell))+",CN:"+Bytes.toString(CellUtil.cloneQualifier(cell))+
            ",Value:"+Bytes.toString(CellUtil.cloneValue(cell)));
        }

        //6.关闭表连接
        table.close();
    }

4.2.3 获取数据 (scan)

 //7.获取数据 (scan)
    public static void scanTable(String tableName) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.构建Scan对象
        Scan scan = new Scan();



        //3.扫描表
        ResultScanner resultScanner = table.getScanner(scan);

        //4.解析resultScanner
        for(Result result:resultScanner){
            //5.解析result并打印
            for(Cell cell:result.rawCells()){
                //6.打印数据
                System.out.println("CF:"+Bytes.toString(CellUtil.cloneFamily(cell))+",CN:"+Bytes.toString(CellUtil.cloneQualifier(cell))+
                        ",Value:"+Bytes.toString(CellUtil.cloneValue(cell)));
            }
        }

        //7.关闭表连接
        table.close();
    }

4.2.4 删除表中的数据

//8.删除数据
    public static void deleteData(String tableName,String rowKey,String cf,String cn) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.构建删除对象
        Delete delete = new Delete(Bytes.toBytes(rowKey));

        //2.1设置删除的列
        delete.addColumns(Bytes.toBytes(cf),Bytes.toBytes(cn));


        //3.执行删除操作
        table.delete(delete);

        //4.关闭表连接
        table.close();
    }

4.3.1 关闭资源

 //关闭资源
    public static void close(){
        if(admin!=null){
            try {
                admin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(connection!=null){
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

4.4.1 总的代码

package com.git.test;


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 sun.net.spi.nameservice.NameServiceDescriptor;

import java.io.IOException;

/*
* DDL
* 1.判断表是否存在
* 2.创建表
* 3.创建命名空间
* 4.删除表
*
*
*
* DML
* 5.插入数据
* 6.查数据(get)
* 7.查数据(scan)
* 8.删除数据
* */
public class TestAPI {
    public static void main(String[] args) throws IOException {
        //1.测试表是否存在
        //System.out.println(isTableExist("stu1"));//true


        //2.创建表测试
        //createTable("0408:stu1","info1","info2");


        //3.删除表测试
        //dropTable("stu1");


        //4.创建命名空间测试
        //createNameSpace("0408");


        //5.插入数据测试
        //putData("stu","1001","info2","name","rqz");


        //6.获取单行数据测试
        //getData("stu","1002","info1","name");


        //7.获取获取扫描数据测试
        //scanTable("stu");


        //8.删除表中的数据测试
        deleteData("stu","1006","info1","name");

        //3.
        //System.out.println(isTableExist("stu1"));





        //统一关闭资源
        close();

    }

    private static  Connection connection=null;
    private static Admin admin=null;

    static {
        try {
            //1.获取配置信息
            //新的
            Configuration configuration = HBaseConfiguration.create();
            configuration.set("hbase.zookeeper.quorum","192.168.189.144,192.168.189.145,192.168.189.146");

            //2.创建连接对象
            connection=ConnectionFactory.createConnection(configuration);

            //3.创建Admin对象
            admin=connection.getAdmin();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }



    //1.判断表是否存在
    public static boolean isTableExist(String tableName) throws IOException {
        //1.获取配置文件信息
        //过时的
        //HBaseConfiguration configuration = new HBaseConfiguration();

        //新的
//        Configuration configuration = HBaseConfiguration.create();
//        configuration.set("hbase.zookeeper.quorum","192.168.189.144,192.168.189.145,192.168.189.146");
//
//        //2.获取管理员对象
//        //过时的
//        //HBaseAdmin hBaseAdmin = new HBaseAdmin(configuration);
//
//        //新的
//        Connection connection = ConnectionFactory.createConnection(configuration);
//        Admin admin = connection.getAdmin();


        //3.判断表是否存在
        //boolean exists = admin.tableExists(tableName);
        boolean exists = admin.tableExists(TableName.valueOf(tableName));

        //4.关闭连接
        //admin.close();

        //5.返回结果
        return exists;
    }


    //2.创建表
    public static void createTable(String tableName,String...cfs) throws IOException {
        //1.判断是否存在列族信息
        if(cfs.length<=0){
            System.out.println("请设置列族信息!");
            return;
        }

        //2.判断表是否存在
        if(isTableExist(tableName)){
            System.out.println(tableName+"表已经存在");
            return;
        }

        //3.创建表描述器
        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));

        //4.循环添加列族信息
        for(String cf:cfs){
            //5.创建列族描述器
            HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);

            //6.添加具体的列族信息
            hTableDescriptor.addFamily(hColumnDescriptor);
        }


        //7.创建表
        admin.createTable(hTableDescriptor);
    }



    //3.删除表
    public static void dropTable(String tableName) throws IOException {
        //1.判断表是否存在
        if(!isTableExist(tableName)){
            System.out.println(tableName+"表不存在");
            return;
        }

        //2.使表下线
        admin.disableTable(TableName.valueOf(tableName));

        //3.删除表
        admin.deleteTable(TableName.valueOf(tableName));
    }



    //4.创建命名空间
    public static void createNameSpace(String ns){
        //1.创建命名空间描述器
        NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(ns).build();

        //2.创建命名空间
        try {
            admin.createNamespace(namespaceDescriptor);
        } catch (NamespaceExistException e) {
            System.out.println(ns+"命名空间已存在");
        }catch(IOException e){
            e.printStackTrace();
        }

        System.out.println("我来了");
    }




    //5.向表中插入数据
    public static void putData(String tableName,String rowKey,String cf,String cn,String value) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.创建Put对象
        Put put = new Put(Bytes.toBytes(rowKey));

        //3.给Put对象赋值
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
        put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));

        //4.插入数据
        table.put(put);

        //5.关闭表连接
        table.close();
    }



    //6.获取数据(get)
    public static void getData(String tableName,String rowKey,String cf,String cn) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.创建Get对象
        Get get = new Get(Bytes.toBytes(rowKey));

        //2.1 指定获取的列族
        get.addFamily(Bytes.toBytes(cf));

        //2.2 指定获取的列族和列
        get.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn));

        //2.3 设置获取数据的版本数
        get.setMaxVersions(5);

        //3.获取数据
        Result result = table.get(get);

        //4.解析result并打印
        for(Cell cell:result.rawCells()){
         //5.打印数据
            System.out.println("CF:"+Bytes.toString(CellUtil.cloneFamily(cell))+",CN:"+Bytes.toString(CellUtil.cloneQualifier(cell))+
            ",Value:"+Bytes.toString(CellUtil.cloneValue(cell)));
        }

        //6.关闭表连接
        table.close();
    }


    //7.获取数据 (scan)
    public static void scanTable(String tableName) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.构建Scan对象
        Scan scan = new Scan();



        //3.扫描表
        ResultScanner resultScanner = table.getScanner(scan);

        //4.解析resultScanner
        for(Result result:resultScanner){
            //5.解析result并打印
            for(Cell cell:result.rawCells()){
                //6.打印数据
                System.out.println("CF:"+Bytes.toString(CellUtil.cloneFamily(cell))+",CN:"+Bytes.toString(CellUtil.cloneQualifier(cell))+
                        ",Value:"+Bytes.toString(CellUtil.cloneValue(cell)));
            }
        }

        //7.关闭表连接
        table.close();
    }



    //8.删除数据
    public static void deleteData(String tableName,String rowKey,String cf,String cn) throws IOException {
        //1.获取表对象
        Table table = connection.getTable(TableName.valueOf(tableName));

        //2.构建删除对象
        Delete delete = new Delete(Bytes.toBytes(rowKey));

        //2.1设置删除的列
        delete.addColumns(Bytes.toBytes(cf),Bytes.toBytes(cn));


        //3.执行删除操作
        table.delete(delete);

        //4.关闭表连接
        table.close();
    }





    //关闭资源
    public static void close(){
        if(admin!=null){
            try {
                admin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(connection!=null){
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值