【大数据技术基础 | 实验八】HBase实验:新建HBase表

文章目录

  • 一、实验目的
  • 二、实验要求
  • 三、实验原理
  • 四、实验环境
  • 五、实验内容和步骤
  • (一)启动HBase集群
  • (二)编写项目java代码
  • (三)将代码导出jar包
  • 六、实验结果
  • 七、实验心得

  • 一、实验目的

    1. 掌握HBase数据模型(逻辑模型及物理模型);
    2. 掌握如何使用Java代码获得HBase连接,并熟练Java对HBase数据库的基本操作,进一步加深对HBase表概念的理解。

    二、实验要求

    通过Java代码实现与HBase数据库连接,然后用Java API创建HBase表,向创建的表中写数据,最后将表中数据读取出来并展示。

    三、实验原理

    逻辑模型:HBase以表的形式存储数据,每个表由行和列组成,每个列属于一个特定的列族(Column Family)。表中的行和列确定的存储单元称为一个元素(Cell),每个元素保存了同一份数据的多个版本,由时间戳(Time Stamp)来标识。行健是数据行在表中的唯一标识,并作为检索记录的主键。在HBase中访问表中的行只有三种方式:通过单个行健访问、给定行键的范围扫描、全表扫描。行健可以是任意字符串,默认按字段顺序存储。表中的列定义为( <列族>: <限定符>),通过列族和限定符两部分可以唯一指定一个数据的存储列。元素由行健、列( <列族>: <限定符>)和时间戳唯一确定,元素中的数据以字节码的形式存储,没有类型之分。

    物理模型:HBase是按照列存储的稀疏行/列矩阵,其物理模型实际上就是把概念模型中的一个行进行分割,并按照列族存储。

    四、实验环境

  • 云创大数据实验平台:
  • Java 版本:jdk1.7.0_79
  • Hadoop 版本:hadoop-2.7.1
  • ZooKeeper 版本:zookeeper-3.4.6
  • HBase 版本:hbase-1.1.2
  • 五、实验内容和步骤

    本实验主要演示HBase Java API的一些基本操作,包括取得链接,创建表,写数据,查询等几个步骤,具体内容如下:

    (一)启动HBase集群

    首先,使用一键搭建启动Hbase集群。详细步骤参考:【大数据技术基础 | 实验七】HBase实验:部署HBase。

    cd /usr/cstor/hbase/bin
    ./start-hbase.sh
    

    使用jps命令查看Java进程:

    可以看到HBase集群启动成功。

    (二)编写项目java代码

    首先,在Eclipse中新建一个名为HbaseTest的Java Project。

    其次,从HBase安装包的lib目录导入如下jar包到开发工具(jar包的版本号以实际的安装中的版本号为主):

    commons-codec-1.4.jar
    commons-collections-3.2.2.jar
    commons-configuration-1.6.jar
    commons-lang-2.6.jar
    commons-logging-1.2.jar
    guava-12.0.1.jar
    hadoop-auth-2.7.2.jar
    hadoop-common-2.7.2.jar
    hadoop-hdfs-2.7.2.jar
    hbase-client-1.1.2.jar
    hbase-common-1.1.2.jar
    hbase-protocol-1.1.2.jar
    htrace-core-3.1.0-incubating.jar
    httpclient-4.4.jar
    httpcore-4.4.jar
    libfb303-0.9.2.jar
    log4j-1.2.17.jar
    metrics-core-2.2.0.jar
    netty-all-4.0.23.Final.jar
    protobuf-java-2.5.0.jar
    slf4j-api-1.7.7.jar
    slf4j-log4j12-1.6.4.jar
    zookeeper-3.4.6.jar

    找到虚拟机内的HBase安装包的lib目录/usr/cstor/hbase/lib,然后将lib下的这些jar包导入到我们本地的项目lib目录内:


    然后我们需要将这些jar包导入到我们的项目中,我们右键每一个jar包 -> Build Path -> Add to Build Path 即可导入成功:


    导入成功后显示如下:


    然后,获得HBase连接,代码实现:

    Configuration configuration = HBaseConfiguration.create();
    Connection connection;
    configuration.set("hbase.zookeeper.quorum", "slave1:2181,slave2:2181,master:2181");
    configuration.set("zookeeper.znode.parent", "/hbase");
    connection = ConnectionFactory.createConnection(configuration);
    

    然后,通过连接实现对HBase数据库的一些基本操作,如下:

    新建HBase表,代码实现:

    //获得HBaseAdmin对象
    Admin admin = connection.getAdmin();
    //表名称
    String tn = "mytable";
    TableName tableName = TableName.valueOf(tn);
    //表不存在时创建表
    if(!admin.tableExists(tableName))
    {
       //创建表描述对象
       HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
       //列簇1
       HColumnDescriptor columnDescriptor1 = new HColumnDescriptor("c1".getBytes());
       tableDescriptor.addFamily(columnDescriptor1);
       //列簇2
       HColumnDescriptor columnDescriptor2 = new HColumnDescriptor("c2".getBytes());
       tableDescriptor.addFamily(columnDescriptor2);
       //用HBaseAdmin对象创建表
       admin.createTable(tableDescriptor);
    }
    //关闭HBaseAdmin对象
    admin.close();
    

    向表put数据,代码实现:

    //获得table接口
    Table table = connection.getTable(TableName.valueOf("mytable"));
    //添加的数据对象集合
    List<Put> putList = new ArrayList<Put>();
    //添加10行数据
    for(int i=0; i<10; i++)
    {
       //put对象(rowkey)
       String rowkey = "mykey" + i;
       Put put = new Put(rowkey.getBytes());
       //列簇 , 列名, 值
       put.addColumn("c1".getBytes(), "c1tofamily1".getBytes(), ("aaa"+i).getBytes());
       put.addColumn("c1".getBytes(), "c2tofamily1".getBytes(), ("bbb"+i).getBytes());
       put.addColumn("c2".getBytes(), "c1tofamily2".getBytes(), ("ccc"+i).getBytes());
       putList.add(put);
    }
    table.put(putList);
    table.close();
    

    查询数据,代码实现:

    //获得table接口(这行代码注意取舍,如果查询的代码和插入代码在同一个类中,则可以不要下面的这行)
    Table table = connection.getTable(TableName.valueOf("mytable"));
    //Scan 对象
    Scan scan = new Scan();
    //限定rowkey查询范围
    scan.setStartRow("mykey0".getBytes());
    scan.setStopRow("mykey9".getBytes());
    //只查询c1:c1tofamily1列
    scan.addColumn("c1".getBytes(), "c1tofamily1".getBytes());
    //过滤器集合
    FilterList filterList = new FilterList();
    //查询符合条件c1:c1tofamily1==aaa7的记录
    Filter filter1 = new SingleColumnValueFilter("c1".getBytes(), "c1tofamily1".getBytes(), 
    CompareFilter.CompareOp.EQUAL, "aaa7".getBytes());
    filterList.addFilter(filter1);
    scan.setFilter(filterList);
    ResultScanner results = table.getScanner(scan);
    for (Result result : results) {  
        System.out.println("获得到rowkey:" + new String(result.getRow()));
        for (Cell cell : result.rawCells()) {
            System.out.println("列簇:" + 
                Bytes.toString(cell.getFamilyArray(),cell.getFamilyOffset(),cell.getFamilyLength()) + "列:" + 
                Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength()) + "值:" +
                Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
        }
    }
    results.close();
    table.close();
    

    :完整代码如下:

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.*;
    import org.apache.hadoop.hbase.client.*;
    import org.apache.hadoop.hbase.filter.CompareFilter;
    import org.apache.hadoop.hbase.filter.Filter;
    import org.apache.hadoop.hbase.filter.FilterList;
    import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
    import org.apache.hadoop.hbase.util.Bytes;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) {
            Configuration configuration = HBaseConfiguration.create();
            Connection connection;
            configuration.set("hbase.zookeeper.quorum", "slave1:2181,slave2:2181,master:2181");
            configuration.set("zookeeper.znode.parent", "/hbase");
            try {
                connection = ConnectionFactory.createConnection(configuration);
                //获得HBaseAdmin对象
                Admin admin = connection.getAdmin();
                //表名称
                String tn = "mytable";
                TableName tableName = TableName.valueOf(tn);
                //表不存在时创建表
                if (!admin.tableExists(tableName)) {
                    //创建表描述对象
                    HTableDescriptor tableDescriptor = new HTableDescriptor(tableName);
                    //列簇1
                    HColumnDescriptor columnDescriptor1 = new HColumnDescriptor("c1".getBytes());
                    tableDescriptor.addFamily(columnDescriptor1);
                    //列簇2
                    HColumnDescriptor columnDescriptor2 = new HColumnDescriptor("c2".getBytes());
                    tableDescriptor.addFamily(columnDescriptor2);
                    //用HBaseAdmin对象创建表
                    admin.createTable(tableDescriptor);
                }
                //关闭HBaseAdmin对象
                admin.close();
                //向表put数据,代码实现:
                //获得table接口
                Table table = connection.getTable(TableName.valueOf("mytable"));
                //添加的数据对象集合
                List<Put> putList = new ArrayList<Put>();
                //添加10行数据
                for (int i = 0; i < 10; i++) {
                    //put对象(rowkey)
                    String rowkey = "mykey" + i;
                    Put put = new Put(rowkey.getBytes());
                    //列簇 , 列名, 值
                    put.addColumn("c1".getBytes(), "c1tofamily1".getBytes(), ("aaa" + i).getBytes());
                    put.addColumn("c1".getBytes(), "c2tofamily1".getBytes(), ("bbb" + i).getBytes());
                    put.addColumn("c2".getBytes(), "c1tofamily2".getBytes(), ("ccc" + i).getBytes());
                    putList.add(put);
                }
                table.put(putList);
                table.close();
                //查询数据,代码实现:
                //获得table接口
                //Scan 对象
                Scan scan = new Scan();
                //限定rowkey查询范围
                scan.setStartRow("mykey0".getBytes());
                scan.setStopRow("mykey9".getBytes());
                //只查询c1:c1tofamily1列
                scan.addColumn("c1".getBytes(), "c1tofamily1".getBytes());
                //过滤器集合
                FilterList filterList = new FilterList();
                //查询符合条件c1:c1tofamily1==aaa7的记录
                Filter filter1 = new SingleColumnValueFilter("c1".getBytes(), "c1tofamily1".getBytes(), CompareFilter.CompareOp.EQUAL, "aaa7".getBytes());
                filterList.addFilter(filter1);
                scan.setFilter(filterList);
                ResultScanner results = table.getScanner(scan);
                for (Result result : results) {
                    System.out.println("获得到rowkey:" + new String(result.getRow()));
                    for (Cell cell : result.rawCells()) {                    
                        System.out.println("列簇:" +
                            Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()) + "列:" +
                            Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()) + "值:" +
                            Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
                    }
                }
                results.close();
                table.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    最后,要点击菜单栏中的Run,选择Run As -> Java Application。这将自动创建一个默认的运行配置。

    (三)将代码导出jar包

    将上述代码打成jar包,注意要选择Runnable JAR file:


    Launch configuration选择Main – HbaseTest:(注意:若上一步中,没有选择Run As -> Java Application创建运行配置,这里则没有Main – HbaseTest的选项)


    用WinSCP工具上传到客户端节点:


    最后,将Java代码打成jar包,并上传到客户端执行。

    java -jar HbaseTest.jar
    

    六、实验结果

    表创建完,然后添加数据后,可以通过shell查看mytable表数据,共插入10条数据,数据内容如图所示。

    cd /usr/cstor/hbase/bin
    ./hbase shell
    

    scan 'mytable'
    

    七、实验心得

      在本次实验中,我通过Java代码实现了与HBase数据库的连接,并进行了创建表、插入数据和查询数据的操作。这一过程中,我对HBase的逻辑模型和物理模型有了更深刻的理解。

      首先,HBase作为一个列式存储的数据库,以表的形式存储数据,每个表由行和列组成。通过实验,我了解到HBase中的行键是数据行的唯一标识,可以用于检索记录。在列的定义中,由列族和限定符组合唯一确定一个数据的存储位置。通过这些基础知识,我能够更好地理解HBase的数据组织方式,尤其是其多版本数据管理的独特优势。

      其次,实验中我学习了如何通过Java代码创建HBase表。通过连接HBase服务器,利用Java API获取HBase的管理对象,并在表不存在时创建表,定义列族。接下来,我使用了Put对象将数据插入表中。通过这种方式插入多行数据,验证了HBase在海量数据处理和存储上的效率与优势。

      最后,我完成了对数据的查询操作。在查询时,我使用了扫描和过滤器来限定查询条件。这种灵活的查询方式让我体验到了HBase对于复杂数据分析和处理的支持。

      此次实验强化了我对HBase数据库操作的掌握,使我认识到HBase在分布式环境下的应用潜力。通过Java代码与HBase的交互,我加深了对HBase表和列族概念的理解,掌握了其增删查改的基本操作。

    作者:Francek Chen

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【大数据技术基础 | 实验八】HBase实验:新建HBase表

    发表回复