有趣的地方

有趣的地方

Hadoop(05) HBase2.5.5安装和编程实践指南

HBase是一个基于Apache Hadoop的分布式、可扩展、面向列的NoSQL数据库系统。它被设计用于处理大规模数据集,并提供快速的读写访问性能。

以下是HBase的一些关键特点和概念:

  1. 列存储结构:HBase使用列存储结构,意味着数据被组织成行和列的形式。每个表可以有灵活的列族定义,而不需要预定义的模式。这使得HBase非常适合存储稀疏的、结构多变的数据。

  2. 分布式架构:HBase是一个分布式数据库系统,可以在多个服务器上水平扩展。数据被分割成多个区域(Regions),每个区域由一个RegionServer管理。这种分布式架构提供了高可用性和容错性,并允许处理大规模数据集。

  3. 强一致性:HBase提供强一致性的读写操作。一旦数据写入成功,它就会立即对所有客户端可见。这对于需要实时访问最新数据的应用程序非常重要。

  4. 高性能:HBase具有优化的读写性能。它使用内存中的块缓存(Block Cache)来加速读取操作,并支持批量写入和异步写入操作,以提高写入吞吐量。

  5. 自动分区和负载均衡:HBase自动管理数据的分区和负载平衡。当数据量增加或节点发生故障时,HBase会自动重新平衡数据,确保数据在集群中均匀分布。

  6. 弹性扩展:HBase可以根据需求进行水平扩展。通过添加更多的RegionServer和节点,可以扩展存储容量和处理能力,以适应不断增长的数据需求。

HBase适用于需要处理大量结构灵活、实时访问和高可扩展性的数据场景,如日志分析、实时数据处理、社交媒体应用、物联网等。它的紧密集成和兼容性与Apache Hadoop生态系统的其他组件(如Hadoop Distributed File System - HDFS和Apache Spark)使得它成为大数据处理和分析的重要工具之一。

一、HBase介绍

HBase是基于HDFS分布式文件系统去构建的。换句话说,HBase的数据其实也是存储在HDFS上的。

1.1 HDFS和HBase的区别

HDFS是文件系统,而HBase是数据库,其实也没啥可比性。「可以把HBase当做是MySQL,把HDFS当做是硬盘。HBase只是一个NoSQL数据库,把数据存储在HDFS上」。

数据库是一个以某种 有组织的方式存储的数据集合

扯了这么多,那我们为啥要用HBase呢?HBase在HDFS之上提供了高并发的随机写和支持实时查询,这是HDFS不具备的。HBase可以以低成本存储海量的数据并且支持高并发随机写和实时查询。

1.2 Hbase的表结构

如果以我们现有的数据库,比如MySQL举例。存储的结构我们很容易看懂,其实就是一行一行数据。

id 姓名 年龄 职业 年薪 婚姻 身高
1 张三 24 180
2 李四 瓦工 500¥

如果将MySQL数据库转换成列式的数据库来进行存储,它的表现形式为:

id:1 姓名:张三
id:1 年龄:24
id:1 身高:180
id:2 姓名:李四
id:2 职业:瓦工
id:2 年薪:500¥

通过以上的示例可以简单的发现,无非就是把每列抽出来,然后关联上Id。 很明显以前我们一行记录多个属性(列),有部分的列是空缺的,但是我们还是需要空间去存储。现在把这些列全部拆开,有什么我们就存什么,这样空间就能被我们充分利用。这种形式的数据更像是Key-Value,那我们该怎么理解HBase所谓的列式存储和Key-Value结构呢?

1.4 Hbase的数据模型

在看HBase数据模型的时候,其实最好还是不要用「关系型数据库」的知识去理解它。

HBase里边也有表、行和列的概念。

  • 表没什么好说的,就是一张表
  • 一行数据由一个行键一个或多个相关的列以及它的值所组成

在HBase里边,定位一行数据会有一个唯一的值,这个叫做行键(RowKey)。而在HBase的列不是我们在关系型数据库所想象中的列。

HBase的列(Column)都得归属到列族(Column Family)中。在HBase中用列修饰符(Column Qualifier)来标识每个列。

在HBase里边,先有列族,后有列

什么是列族?可以简单理解为:列的属性类别

什么是列修饰符?先有列族后有列,在列族下用列修饰符来标识一列

可以通过在里面放入更加具体的值来观察:

 

数据写到HBase的时候都会被记录一个时间戳,这个时间戳被我们当做一个版本。比如说,我们修改或者删除某一条的时候,本质上是往里边新增一条数据,记录的版本加一了而已。 在读的时候按照时间戳读最新的记录。在外界「看起来」就是把这条记录改了。

1.3 Hbase的运行模式

HBase是一个分布式的、面向列的开源数据库,源于Google的一篇论文《BigTable:一个结构化数据的分布式存储系统》。HBase以表的形式存储数据,表有行和列组成,列划分为若干个列族/列簇(column family)。欲了解HBase的官方资讯,请访问[HBase官方网站](http://hbase.apache.org/)。
HBase的运行有三种模式:单机模式、伪分布式模式、分布式模式。
单机模式:在一台计算机上安装和使用HBase,不涉及数据的分布式存储;

伪分布式模式:在一台计算机上模拟一个小的集群;

分布式模式:使用多台计算机实现物理意义上的分布式存储。

这里出于学习目的,我们只重点讨论单机模式和伪分布式模式。

本教程运行环境是在Debain-64位系统下(此教程为Debian11-7),HBase版本为Hbase-2.5.5,这是目前已经发行的已经编译好的稳定的版本,带有src的文件是未编译的版本,这里我们只要下载bin版本Hbase-2.5.5-bin.tar.gz就好了。

点击此处下载 Hbase2.5.5 稳定版本

 

文件区别:

  1. hbase-2.5.5-bin.tar.gz: 这是 HBase 的二进制发行版。它包含了编译好的二进制文件,可以直接使用,而无需进行编译。这个发行版适用于大多数用户,尤其是那些只需要运行 HBase 而不需要进行源代码级别的修改的用户。

  2. hbase-2.5.5-client-bin.tar.gz: 这是 HBase 的客户端二进制发行版。它包含了仅限客户端使用的二进制文件,没有包含 HBase 的服务端组件。这个发行版适用于那些只需要在客户端进行 HBase 操作的用户,而不需要在本地运行 HBase 服务。

  3. hbase-2.5.5-hadoop3-bin.tar.gz: 这是 HBase 针对 Hadoop 3.x 版本的二进制发行版。它适用于与 Hadoop 3.x 版本集成使用的用户。这个发行版包含了与 Hadoop 3.x 版本兼容的二进制文件。

  4. hbase-2.5.5-hadoop3-client-bin.tar.gz: 这是 HBase 针对 Hadoop 3.x 版本的客户端二进制发行版。它适用于只需要在客户端与 Hadoop 3.x 版本集成使用的用户,不需要在本地运行 HBase 服务。

  5. hbase-2.5.5-src.tar.gz: 这是 HBase 的源代码发行版。它包含了 HBase 的完整源代码,可以用于进行修改、编译和调试。这个发行版适用于那些需要在源代码级别进行扩展或修改 HBase 的用户。

在下载此文件之后,可以使用xftp工具将该文件上传到虚拟机系统中即可。 

二、安装并配置HBase2.5.5 

在安装HBase之前,请确保你的电脑已经安装了Hadoop3.3.5,由于HBase对Hadoop具有版本依赖性,所以,在安装HBase2.5.4时,一定要首先安装Hadoop3.3.6。(点击此处 查看Hadoop3.3.6的安装方法)因为根据之前的学习路线,我已经安装 Hadoop集群 ,此处是在master节点上进行安装(即前面学习中提到的 hadoop01 主机)。

在将HBase2.5.5 通过xftp上传到虚拟机的hadoop01 的/software文件夹之后。

2.1 解压安装包HBase-2.5.5-bin.tar.gz至路径 /usr/local

命令如下:

cd /software/
ls -l
sudo tar -zvxf hbase-2.5.5-bin.tar.gz -C /usr/local   # 如果此时是非特权用户的身份,需要在命令前面加上sudo

2.2 切换目录命令,把hbase-2.5.5目录权限赋予给hadoop用户

命令如下: 

cd /usr/local/
sudo chown -R hadoop ./hbase-2.5.5/

2.3 配置环境变量
将hbase-2.5.5下的bin目录添加到path中,这样,启动hbase就无需到/usr/local/hbase目录下,大大的方便了hbase的使用。教程下面的部分还是切换到了/usr/local/hbase-2.5.5目录操作,有助于初学者理解运行过程,熟练之后可以不必切换。
编辑~/.bashrc文件

cd ~
vim ~/.bashrc

如果没有引入过PATH请在~/.bashrc文件尾行添加如下内容:

export HBASE_HOME=/usr/local/hbase-2.5.5
export PATH=$PATH:$HBASE_HOME/bin

由于在之前的教程中安装过Java和Hadoop,并且配置过PATH,因此只需要在原本的export PATH的基础上添加 $HBASE_HOME/bin:,这里的“:”是分隔符。如下图:

 添加之后的如下图所示:

保存并退出 

2.3 执行source命令使上述配置在当前终端立即生效

命令如下:

source ~/.bashrc

2.4 查看Hbase 的版本

命令如下:

hbase version

此处出现一条警告信息(SLF4J: Class path contains multiple SLF4J bindings.),可以点击此处查看解决办法

看到输出版本消息表示HBase已经安装成功,接下来将分别进行HBase单机模式和伪分布式模式的配置。

三、HBase配置

HBase作为一个分布式的开源NoSQL数据库,它有三种运行模式,分别是单机模式(Standalone Mode)、伪分布式模式(Pseudo-Distributed Mode)和完全分布式模式(Fully-Distributed Mode)。

  1. 单机模式(Standalone Mode):
    在单机模式下,HBase运行在单个节点上,所有的HBase组件(包括HMaster和HRegionServer)都在同一个JVM进程中运行。这种模式适用于在开发和测试环境中快速搭建和运行HBase,但不具备分布式的优势和可扩展性。

  2. 伪分布式模式(Pseudo-Distributed Mode):
    在伪分布式模式下,HBase模拟了分布式环境,但实际上仍然在单个节点上运行。每个HBase组件都在独立的JVM进程中运行,包括一个HMaster和一个或多个HRegionServer。这种模式适用于在本地机器上模拟和测试分布式的HBase环境,通常用于开发和学习目的。

  3. 完全分布式模式(Fully-Distributed Mode):
    在完全分布式模式下,HBase运行在一个真正的分布式环境中,通过多台物理或虚拟机器组成。HBase集群包括一个HMaster节点和多个HRegionServer节点,数据被分布存储在不同的RegionServer上。这种模式适用于生产环境,可以提供高可用性、容错性和水平扩展性,并支持大规模数据存储和处理。

选择适当的模式取决于你的使用场景和需求。在开发和测试阶段,可以使用单机模式或伪分布式模式进行快速验证和开发。在实际生产环境中,通常会使用完全分布式模式来构建可靠的、高性能的HBase集群。

作为学习,我们将重点讨论单机模式和伪分布式模式。
以下先决条件很重要,比如没有配置JAVA_HOME环境变量,就会报错。
- jdk
- Hadoop( 单机模式不需要,伪分布式模式和分布式模式需要)
- SSH

以上三者如果没有安装,请回到 Hadoop(01) Hadoop3.3.6安装教程,单机/伪分布式配置 参考如何安装。

3.1 单机模式

3.1.1 配置/usr/local/hbase-2.5.5/conf/hbase-env.sh

配置JAVA环境变量,并添加配置HBASE_MANAGES_ZK为true。如果此前配置过JAVA_HOME可以输入下列命令显示其路径。

echo $JAVA_HOME

配置HBASE_MANAGES_ZK为true,表示由hbase自己管理zookeeper,不需要单独的zookeeper。hbase-env.sh中本来就存在该变量的配置,只需要删除前面的#并修改配置内容即可(#代表注释),用vi命令打开并编辑hbase-env.sh,命令如下:

保存后退出。

3.1.2 配置/usr/local/hbase-2.5.5/conf/hbase-site.xml

打开并编辑hbase-site.xml,命令如下:

vim /usr/local/hbase-2.5.5/conf/hbase-site.xml

在启动HBase前需要设置属性hbase.rootdir,用于指定HBase数据的存储位置,因为如果不设置的话,hbase.rootdir默认为/tmp/hbase-${user.name},这意味着每次重启系统都会丢失数据。此处设置为HBase安装目录下的hbase-tmp文件夹即(/usr/local/hbase-2.5.5/hbase-tmp),添加配置如下: 

<configuration>
        <property>
                <name>hbase.rootdir</name>
                <value>file:///usr/local/hbase-2.5.5/hbase-tmp</value>
        </property>
</configuration>

 修改前:

 修改后:

3.1.3 测试运行

首先切换目录至HBase安装目录/usr/local/hbase;再启动HBase。命令如下:

cd /usr/local/hbase-2.5.5/bin/
./start-hbase.sh  # 启动HBase
./hbase shell   # 打开shell命令行模式,用户可以通过输入shell命令操作HBase数据库

使用exit可以退出shell命令行模式。

停止HBase运行,命令如下:

注意:如果在操作HBase的过程中发生错误,可以通过{HBASE_HOME}目录(/usr/local/hbase-2.5.5)下的logs子目录中的日志文件查看错误原因。 

3.2 伪分布式模式

3.2.1 配置/usr/local/hbase-2.5.5/conf/hbase-env.sh

配置JAVA_HOME,HBASE_CLASSPATH,HBASE_MANAGES_ZK。HBASE_CLASSPATH设置为本机HBase安装目录下的conf目录(即/usr/local/hbase-2.5.5/conf)命令如下:

cd /usr/local/hbase-2.5.5/conf/
vim hbase-env.sh 

在hbase-env.sh中添加下列命令:

 export HBASE_MANAGES_ZK=true
 export JAVA_HOME=/usr/local/java/jdk-11.0.20.1+1
 export HBASE_CLASSPATH=/usr/local/hbase-2.5.5/conf

3.2.2 配置/usr/local/hbase-2.5.5/conf/hbase-site.xml

用命令vi打开并编辑hbase-site.xml,命令如下:

/usr/local/hbase-2.5.5/conf/hbase-site.xml

修改hbase.rootdir,指定HBase数据在HDFS上的存储路径;将属性hbase.cluter.distributed设置为true。假设当前Hadoop集群运行在伪分布式模式下,在本机上运行,且NameNode运行在9000端口。

<configuration>
        <property>
                <name>hbase.rootdir</name>
                <!-- value 的 URL 地址请与hadoop配置文件core-site.xml
                 中的 fs.default.name 保持一致,然后再加上 /hbase。
                 此处建议用主机名(不建议直接填写 IP 地址,否则可能出错)-->
                <value>hdfs://hadoop01:9000/hbase</value>
        </property>
        <property>
                <name>hbase.cluster.distributed</name>
                <value>true</value>
        </property>
        <property>
        <name>hbase.unsafe.stream.capability.enforce</name>
        <value>false</value>
    </property>
</configuration>

修改前:

修改后:

hbase.rootdir指定HBase的存储目录;

hbase.cluster.distributed设置集群处于分布式模式.
另外,上面配置文件中,hbase.unsafe.stream.capability.enforce这个属性的设置,是为了避免出现启动错误。也就是说,如果没有设置hbase.unsafe.stream.capability.enforce为false,那么,在启动HBase以后,会出现无法找到HMaster进程的错误,启动后查看系统启动日志(/usr/local/hbase-2.5.5/logs/hbase-hadoop-master-ubuntu.log),会发现如下错误:

 2023-10-23 11:05:53,916 ERROR [master/localhost:16000:becomeActiveMaster] master.HMaster: Failed to become active master
java.lang.IllegalStateException: The procedure WAL relies on the ability to hsync for proper operation during component failures, but the underlying filesystem does not support doing so. Please check the config value of 'hbase.procedure.store.wal.use.hsync' to set the desired level of robustness and ensure the config value of 'hbase.wal.dir' points to a FileSystem mount that can provide it.

3.3.3 测试运行HBase

① 登陆ssh,由于之前设置了无密码登陆,因此这里不需要密码;再切换目录至/usr/local/hadoop-3.3.6 ;再启动hadoop,如果已经启动hadoop请跳过此步骤。命令如下:

一般来说,输入命令jps,如果能看到NameNode,DataNode和SecondaryNameNode都已经成功启动,表示Hadoop启动成功。但是由于我们在此前的 Hadoop(01) Hadoop3.3.6安装教程,单机/伪分布式配置 教程中的 伪分布式配置的小节中 仅将hadoop01作为namenode来进行的配置,所以在hadoop01主机上运行 jps 命令并不会显示datanode,因为datanode是配置在hadoop02 主机上。如果想要查看datanode是否正常启动,可以hadoop02主机上输入 jps,如下所示:

② 切换目录至/usr/local/hbase-2.5.5 ;再启动HBase.命令如下: 

cd /usr/local/hbase-2.5.5/bin/
./start-hbase.sh 
jps

输入jps后,看到一下界面表示启动hbase成功。 

以上的提示信息表示:

  1. 首先,看到一个关于主机身份验证的提示,要求确认连接。这是SSH连接到本地主机(127.0.0.1)时的一般行为。可以输入yes以继续连接。

  2. 接下来,输出显示成功连接到主机(127.0.0.1),并开始了一系列操作。

    running zookeeper 启动了ZooKeeper服务,它是HBase的依赖组件之一。ZooKeeper用于协调和管理HBase集群中的各个节点。
    running master 启动了HBase的Master节点,Master节点负责管理和协调整个HBase集群的操作。
    running regionserver 启动了HBase的RegionServer节点,RegionServer节点负责存储和处理HBase表中的数据。
  3. 启动过程中的日志输出被重定向到了相应的日志文件中,例如hbase-hadoop-zookeeper-hadoop01.outhbase-hadoop-master-hadoop01.outhbase-hadoop-regionserver-hadoop01.out。你可以查看这些日志文件以获取更多关于启动过程的详细信息。

进入hbase的shell界面,命令如下:

3.3.4 停止HBase运行

启动关闭Hadoop和HBase的顺序一定是:
启动Hadoop—>启动HBase—>关闭HBase—>关闭Hadoop

./stop-hbase.sh 
cd /usr/local/hadoop-3.3.6/sbin/
./stop-dfs.sh 

注意:如果在操作HBase的过程中发生错误,可以通过{HBASE_HOME}目录(/usr/local/hbase)下的logs子目录中的日志文件查看错误原因。

四、编程实践

4.1 Hbase 的shell命令

在使用hbase shell命令之前,要先启动hadoop和hbase,启动命令如上述。

4.1.1 创建表

hbase中用create命令创建表,具体如下:

create 'student','Sname','Ssex','Sage','Sdept','course'

 参数说明:创建一个名为student的表,以及定义一些列族(SnameSsexSageSdeptcourse

因为HBase的表中会有一个系统默认的属性作为行键,无需自行创建,默认为put命令操作中表名后第一个数据。创建完“student”表后,可通过describe命令查看“student”表的基本信息。命令执行截图如下:

describe 'student'

4.1.2 hbase数据库的基本操作

本小节主要介绍HBase的增、删、改、查操作。在添加数据时,HBase会自动为添加的数据添加一个时间戳,故在需要修改数据时,只需直接添加数据,HBase即会生成一个新的版本,从而完成“改”操作,旧的版本依旧保留,系统会定时回收垃圾数据,只留下最新的几个版本,保存的版本数可以在创建表的时候指定。

① 添加数据

hbase中用put命令添加数据,注意:一次只能为一个表的一行数据的一个列,也就是一个单元格添加一个数据,所以直接用shell命令插入数据效率很低,在实际应用中,一般都是利用编程操作数据。
当运行命令:put ‘student’,’95001’,’Sname’,’LiYing’时,即为student表添加了学号为95001,名字为LiYing的一行数据,其行键为95001。

put 'student','95001','Sname','LiYing'

参数说明: 在student表的行键为95001的行中,插入一个名为Sname的列,并设置其值为LiYing。此处的行键可以代指学生的学号,也可表示为student表添加了学号为95001,名字为LiYing的一行数据,其行键为95001。

补充:在HBase中,行键是用于唯一标识表中每一行数据的标识符。行键是一个字节数组,可以是任意长度的二进制数据。在HBase表中,行键是按照字典顺序进行排序的。

put 'student','95001','course:math','80'

 参数说明:在student表的行键为95001的行中,在 course 列族下存储一个名为math的列,并设置其属性值为80

put 'student','95001','course:English','98'

参数说明:在 student 表的行键为95001的行中,在 course 列族下存储一个名为 English 的列,并将其属性值设置为 98

put 'student','95001','Ssex','Male'

 参数说明:在student表的行键为95001的行中,插入一个名为Ssex的列,并设置其值为Male

② 查看数据

HBase中有两个用于查看数据的命令:1. get命令,用于查看表的某一行数据;2. scan命令用于查看某个表的全部数据

get命令:

get 'student','95001'

 scan命令:

scan 'student'

③ 删除数据

在HBase中用delete以及deleteall命令进行删除数据操作,它们的区别是:1. delete用于删除一个数据,是put的反向操作;2. deleteall操作用于删除一行数据。

delete命令:

delete 'student','95001','course:English'

删除之前:

删除之后:

deleteall命令:

deleteall 'student','95001'

删除之前:

删除之后:

④ 删除表

删除表有两步,第一步先让该表不可用,第二步删除表。

disable 'student'  
drop 'student'

⑤ 查询表的历史数据 

在 Hbase 中,表的历史数据通常是通过版本控制来实现的。每次对表执行写操作时,HBase 会为每个单元格(cell)维护多个版本的数据。可以通过设置适当的版本数来控制保存的历史数据量。

注意:保存的历史数据数量可能会影响存储空间的使用和查询性能。因此,应根据实际需求和系统资源进行适当的配置。 

step1

在创建表的时候,指定保存的版本数(假设指定为5)

create 'teacher',{NAME=>'username',VERSIONS=>5}

step2

插入数据然后更新数据,使其产生历史版本数据,注意:这里插入数据和更新数据都是用put命令

put 'teacher','91001','username','Mary'
put 'teacher','91001','username','Mary1'
put 'teacher','91001','username','Mary2'
put 'teacher','91001','username','Mary3'
put 'teacher','91001','username','Mary4'  
put 'teacher','91001','username','Mary5'
 step3

查询时,指定查询的历史版本数。默认会查询出最新的数据。(有效取值为1到5) 

要查询表的历史数据,可以使用 get 命令并指定列族和列限定符,并在命令中添加 VERSIONS 关键字,后接要返回的版本数。例如:(有效取值为1到5) 

get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}

参数说明:返回 teacher 表中 91001 行的 username 列的最近 5 个版本的数据。 

也可以使用 scan 命令来扫描整个表或特定的行范围,并通过设置 VERSIONS 选项来获取多个版本的数据。例如:

scan 'student', {VERSIONS => 3}

参数说明: 扫描整个 student 表,并返回每个单元格的最近 3 个版本的数据。

⑥ 退出Hbase数据库表操作

最后退出数据库操作,输入exit命令即可退出,注意:这里退出HBase数据库是退出对数据库表的操作,而不是停止启动HBase数据库后台运行。

exit

4.2 Hbase Java API编程实践

4.2.1 在Linux中安装IDEA开发工具

本实例采用IDEA开发工具,虚拟机中如何安装IDEA 开发工具,参考教程 Linux(04) Debian11中安装IDEA教程(无GNOME)

通过将IDEA安装到 /opt/idea-IC-23.2/bin 路径之后,可以通过以下命令启动IDEA

cd /opt/idea-IC-23.2/bin
./idea.sh

 启动之后,新建一个名为HBase_Example的java工程。

4.2.2 为项目添加需要用到的JAR包  

为了编写一个能够与HBase交互的Java应用程序,需要在这个界面中加载该Java工程所需要用到的JAR包,这些JAR包中包含了可以访问HBase的Java API。这些JAR包都位于Linux系统的HBase安装目录的lib目录下,也就是位于“/usr/local/hbase-2.5.5/lib”目录下。

在 HBase 安装目录下的 /usr/local/hbase-2.5.5/lib 文件夹通常包含 HBase 的相关库文件和依赖项。这些文件是 HBase 运行所需的核心组件和第三方库。除了上述提到的主要内容外,还有另外六个目录:

  1. client-facing-thirdparty:这个目录通常包含 HBase 与客户端交互时所需的第三方库文件。这些库文件用于支持与 HBase 进行交互的客户端应用程序,例如 Java 应用程序或其他编程语言的客户端。

  2. jdk11:这个目录可能包含适用于 JDK 11 的特定版本的 HBase 库文件。由于不同的 JDK 版本可能存在兼容性差异,HBase 可能提供特定于某个 JDK 版本的库文件。

  3. ruby:这个目录可能包含与 Ruby 编程语言相关的库文件。HBase 提供了一些用于与 Ruby 客户端进行交互的接口和工具。

  4. shaded-clients:这个目录通常包含 HBase 为不同的客户端环境提供的 shaded(阴影)客户端库文件。这些库文件将 HBase 的依赖项打包在一起,以便客户端应用程序可以更轻松地使用 HBase。

  5. trace:这个目录可能包含与 HBase 分布式跟踪功能相关的库文件。HBase 的分布式跟踪功能用于跟踪和分析请求在集群中的执行情况。

  6. zkcli:这个目录可能包含与 HBase ZooKeeper 客户端相关的库文件和工具。ZooKeeper 用于 HBase 的协调和配置管理,zkcli 目录可能包含与 ZooKeeper 客户端交互的命令行工具和库文件。

本次的编程实践中我们仅引入 核心库 和 client-facing-thirdparty ,其余几个包均不涉及,如有需要可以按照下面的方法建立依赖。

① 创建libs文件夹

在该java工程中创建libs文件,如果已经存在libs文件夹,则可以直接进行下一步。

② 复制JAR文件

将需要导入的jar(在 hbase的安装目录下lib文件中,包括核心库的jar包和 client-facing-thirdparty 复制粘贴到libs文件夹中。

复制到HBase_Example项目中的libs文件夹中

查看一下刚复制到libs文件夹中的状态,暂时不要点开

③ 建立该java工程对libs文件夹的依赖

在IDEA中右键单击项目,选择'Open Module Settings”(或者"Project Structure"”),在弹出的窗口中选择'Modules”,然后选择“Dependencies”选项卡。
点击“+"按钮,选择"JARs or directories”,然后在弹出的窗口中选择刚才放置jar包的libs文件夹,然后点击OK(我在此处直接选择的是文件夹)。

如果是这个状态表示依赖建立成功:  

这样,导入jar包的操作就完成了。现在你可以直接编写或运行代码了。如果需要进一步优化导包设置,可以根据IDEA的环境配置和插件进行相应的调整(如Maven)。 

4.2.3 新建java代码程序 

ExampleForHBase.java代码内容具体如下:

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 java.io.IOException;
public class ExampleForHBase {
    public static Configuration configuration;
    public static Connection connection;
    public static Admin admin;
    public static void main(String[] args)throws IOException{
        init();
        createTable("student",new String[]{"score"});
        insertData("student","zhangsan","score","English","69");
        insertData("student","zhangsan","score","Math","86");
        insertData("student","zhangsan","score","Computer","77");
        getData("student", "zhangsan", "score","English");
        close();
    }
 
    public static void init(){
        configuration  = HBaseConfiguration.create();
        configuration.set("hbase.rootdir","hdfs://localhost:9000/hbase");
        try{
            connection = ConnectionFactory.createConnection(configuration);
            admin = connection.getAdmin();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
 
    public static void close(){
        try{
            if(admin != null){
                admin.close();
            }
            if(null != connection){
                connection.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
 
    public static void createTable(String myTableName,String[] colFamily) throws IOException {
        TableName tableName = TableName.valueOf(myTableName);
        if(admin.tableExists(tableName)){
            System.out.println("talbe is exists!");
        }else {
            TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(tableName);
            for(String str:colFamily){
                ColumnFamilyDescriptor family = 
ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(str)).build();
                tableDescriptor.setColumnFamily(family);
            }
            admin.createTable(tableDescriptor.build());
        } 
    }
 
    public static void insertData(String tableName,String rowKey,String colFamily,String col,String val) throws IOException { 
        Table table = connection.getTable(TableName.valueOf(tableName));
        Put put = new Put(rowKey.getBytes());
        put.addColumn(colFamily.getBytes(),col.getBytes(), val.getBytes());
        table.put(put);
        table.close(); 
    }
 
    public static void getData(String tableName,String rowKey,String colFamily, String col)throws  IOException{ 
        Table table = connection.getTable(TableName.valueOf(tableName));
        Get get = new Get(rowKey.getBytes());
        get.addColumn(colFamily.getBytes(),col.getBytes());
        Result result = table.get(get);
        System.out.println(new String(result.getValue(colFamily.getBytes(),col==null?null:col.getBytes())));
        table.close(); 
    }
}

注意:在开始运行程序之前,需要启动HDFS和HBase。 

然后开始编译运行

程序运行成功以后,如上图所示,会在运行结果中出现“69”。

在上面的console控制台中的警告信息为:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.hadoop.security.authentication.util.KerberosUtil (file:/home/hadoop/workspace/HBase_Example/libs/hadoop-auth-2.10.2.jar) to method sun.security.krb5.Config.getInstance()
WARNING: Please consider reporting this to the maintainers of org.apache.hadoop.security.authentication.util.KerberosUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

这些警告信息是关于非法反射访问操作的提示。在 Java 9 及更高版本中,Java 引入了模块化系统,限制了对内部 API 的访问。当使用反射访问内部 API 时,可能会触发这些警告。 解决方案可以参考 启动hadoop报出一串警告 ,因为对程序没有太大的影响,此处并未测试该方案是否可行。

4.2.4 查看运行的结果

在HBase Shell交互式环境中,使用如下命令查看student表是否创建成功:

hbase> list

在HBase Shell交互式环境中,使用如下命令查看student表中的数据: 

hbase> scan ‘student’

参考资料

HBase(Hadoop3.1.2 HBase2.2.4) 伪分布式安装与配置-CSDN博客

我终于看懂了HBase,太不容易了... - 知乎 (zhihu.com)

Hbase 常用 shell 操作:增删改查(create、put、delete、scan)_hbase shell put-CSDN博客

启动hadoop报出一串警告_please consider reporting this to the maintainers -CSDN博客 

发表评论:

Powered By Z-BlogPHP 1.7.3

© 2018-2020 有趣的地方 粤ICP备18140861号-1 网站地图