【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)

一、HBase数据模型

HBase分布式数据库的数据存储在行列式的表格中,它是一个多维度的映射模型,其数据模型如下所示。表的索引是行键,列族,列限定符和时间戳,表在水平方向由一个或者多个列族组成,一个列族中可以包含任意多个列,列族支持动态扩展,可以很轻松的添加一个列族或者列,无须预先定义列的数量及数据类型,所有列均以字符串形式存储

RowKey表示行键,每个HBase表中只能有一个行键,它在HBase中以字典序的方式存储。由于RowKey是HBase表的唯一标识,因此Row Key的设计非常重要。

HBase表的列是由列族名、限定符以及列名组成的,其中“:”为限定符。创建HBase表不需要指定列,因为列是可变的,非常灵活。

在HBase中,列族由很多列组成。在同一个表里,不同列族有完全不同的属性,但是同一个列族内的所有列都会有相同的属性,而属性都是定义在列族上的。

表示时间戳,记录每次操作数据的时间,通常记作数据的版本号。

二、HBase的Shell操作

HBase Shell提供大量操作HBase的命令,通过Shell命令很方便地操作HBase数据库,如创建、删除及修改表、向表中添加数据、列出表中的相关信息等操作。当使用Shell命令行操作HBase时,需要进入HBase Shell交互界面,执行“bin/hbase shell”命令进入到目录/hbase的界面。

在HBase Shell交互界面中,可通过一系列Shell命令操作HBase,下面通过一张表列举操作HBase表常见的Shell命令。

1)显示hbase中的表l ist

2)创建表user,包含info、data两个列族

3)向user表中插入数据

4)获取user表中row key为rk0001的所有信息

5)获取user表中row key为rk0001,列族为info,版本号最新3个的信息 HBase2.0默认VERSIONS为1,也就是说,默认情况只会存取一个版本的列数据。需要使用alter命令修改表的版本号。

清空表数据

添加列族

三、HBase的Java API操作

HBase是由Java语言开发的,它对外提供了Java API的接口。下面,通过一个表来列举HBase常见的Java API。

下面代码主要利用HBase常用的Java API进行表的创建,插入,删除等操作

package com.hadoop.hbase;
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.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class HbaseApiDemo {
    //初始化Configuration对象
    private Configuration conf = null;
    //初始化连接
    private Connection conn = null;
    @Before
    public void init() throws Exception {
        //获取Configuration对象
        conf = HBaseConfiguration.create();
        //对于hbase的客户端来说,只需要知道hbase所经过的Zookeeper集群地址即可
          conf.set("hbase.zookeeper.quorum", "bigdata01:2181,bigdata02:2181,bigdata03:2181");
        //获取连接
        conn = ConnectionFactory.createConnection(conf);
    }
     @Test
    public void CreateTable() throws Exception {
        try {
            //获取操作对象
            Admin admin = conn.getAdmin();
            //构建一个user表
            TableDescriptorBuilder t_user = TableDescriptorBuilder.newBuilder(TableName.valueOf("t_user"));
             //创建列族  1
            ColumnFamilyDescriptor of = ColumnFamilyDescriptorBuilder.of("info");
            t_user.setColumnFamily(of);
            //创建列族  2
            ColumnFamilyDescriptor of1 = ColumnFamilyDescriptorBuilder.of("data");
            t_user.setColumnFamily(of1);
            //构建
            TableDescriptor build = t_user.build();
            //创建表
            admin.createTable(build);
            // 关闭连接
            admin.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testPut() throws Exception {
        //创建table对象,通过table对象来添加数据
        Table table = conn.getTable(TableName.valueOf("t_user"));
        //创建一个集合,用于存放Put对象
        ArrayList<Put> puts = new ArrayList<Put>();
        //构建put对象(kv形式),并指定其行键
        Put put01 = new Put(Bytes.toBytes("rk002"));
        put01.addColumn(Bytes.toBytes("info"),
                Bytes.toBytes("username"), Bytes.toBytes("zhangsan"));
        put01.addColumn(Bytes.toBytes("info"),
                Bytes.toBytes("password"), Bytes.toBytes("345678"));
        Put put02 = new Put("rk003".getBytes());
        put02.addColumn(Bytes.toBytes("info"),
                Bytes.toBytes("username"), Bytes.toBytes("lisi"));
         //把所有的put对象添加到一个集合中
        puts.add(put01);
        puts.add(put02);
        //提交所有的插入数据的记录
        table.put(puts);
        //关闭
        table.close();
        conn.close();
    }
    @Test
    public void testGet() throws IOException {
        Table table = conn.getTable(TableName.valueOf("t_user"));
        //得到用于扫描region的对象
//        Scan scan = new Scan();
        Get get = new Get("rk002".getBytes());
        //使用HTable得到resultcanner实现类的对象
        Result result1 = table.get(get);
        List<Cell> cells = result1.listCells();
        for (Cell cell : cells) {
            //得到rowkey
            System.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));
            //得到列族
            System.out.println("列族:" + Bytes.toString(CellUtil.cloneFamily(cell)));
            System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
            System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
        }
    }
    @Test
    public void testScan() throws Exception {
        //获取table对象
        Table table = conn.getTable(TableName.valueOf("t_user"));
        //获取scan对象
        Scan scan = new Scan();
        //获取查询的数据
        ResultScanner scanner = table.getScanner(scan);
        //获取ResultScanner所有数据,返回迭代器
        Iterator<Result> iter = scanner.iterator();
        //遍历迭代器
        while (iter.hasNext()) {
            //获取当前每一行结果数据
            Result result = iter.next();
            //获取当前每一行中所有的cell对象
            List<Cell> cells = result.listCells();
            //迭代所有的cell
            for(Cell c:cells){
                //获取行键
                byte[] rowArray = c.getRowArray();
                //获取列族
                byte[] familyArray = c.getFamilyArray();
                //获取列族下的列名称
                byte[] qualifierArray = c.getQualifierArray();
                //列字段的值
                byte[] valueArray = c.getValueArray();
                //打印rowArray、familyArray、qualifierArray、valueArray
                System.out.println("行键:"+new String(rowArray, c.getRowOffset(),
                        c.getRowLength()));
                System.out.print("列族:"+new String(familyArray,c.getFamilyOffset(),
                        c.getFamilyLength()));
                System.out.print(" "+"列:"+ new String(qualifierArray,
                        c.getQualifierOffset(), c.getQualifierLength()));
                System.out.println(" "+"值:"+ new String(valueArray,
                        c.getValueOffset(), c.getValueLength()));
            }
            System.out.println("-----------------------");
        }
        //关闭
        table.close();
        conn.close();
    }
    @Test
    public void testDel() throws Exception {
        //获取table对象
        Table table = conn.getTable(TableName.valueOf("t_user"));
        //获取delete对象,需要一个rowkey
        Delete delete = new Delete("rk002".getBytes());
        //在delete对象中指定要删除的列族-列名称
        delete.addColumn("info".getBytes(), "password".getBytes());
        //执行删除操作
        table.delete(delete);
        //关闭
        table.close();
        conn.close();
    }
    @Test
    public void testDrop() throws Exception {
        //获取一个表的管理器
        Admin admin = conn.getAdmin();
        //删除表时先需要禁用表
        admin.disableTable(TableName.valueOf("t_user"));
        admin.deleteTable(TableName.valueOf("t_user"));
        //关闭
        admin.close();
        conn.close();
    }
}

创作不易 觉得有帮助请点赞关注收藏~~~

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
|
20天前
|
使用Java和Spring Data构建数据访问层
本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
62 21
【潜意识Java】深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
71 1
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
50 7
|
1月前
|
java怎么统计每个项目下的每个类别的数据
通过本文,我们详细介绍了如何在Java中统计每个项目下的每个类别的数据,包括数据模型设计、数据存储和统计方法。通过定义 `Category`和 `Project`类,并使用 `ProjectManager`类进行管理,可以轻松实现项目和类别的数据统计。希望本文能够帮助您理解和实现类似的统计需求。
107 17
java常用数据判空、比较和类型转换
本文介绍了Java开发中常见的数据处理技巧,包括数据判空、数据比较和类型转换。详细讲解了字符串、Integer、对象、List、Map、Set及数组的判空方法,推荐使用工具类如StringUtils、Objects等。同时,讨论了基本数据类型与引用数据类型的比较方法,以及自动类型转换和强制类型转换的规则。最后,提供了数值类型与字符串互相转换的具体示例。
129 3
|
3月前
|
Java|如何用一个统一结构接收成员名称不固定的数据
本文介绍了一种 Java 中如何用一个统一结构接收成员名称不固定的数据的方法。
53 3
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
307 2
|
3月前
|
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
64 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等