HBase2.6.7安装和编程实践指南

大数据学习路线图

【版权声明】版权所有,请勿转载!
作者:厦门大学计算机系林子雨副教授
E-mail: ziyulin@xmu.edu.cn
本博客内容与林子雨编著《大数据技术原理与应用(第5版)》(访问教材官网)教材配套。
本指南介绍了HBase2.6.7的安装和使用方法。

注意,必须先在Ubuntu24.04中安装Hadoop3.5.0
如果你还没有安装Hadoop3.5.0,请先参考这篇博客完成Hadoop3.5.0的安装。

一、安装HBase

1.下载HBase2.6.7安装文件

HBase2.6.7安装文件hbase-2.6.7-hadoop3-bin.tar.gz,可以到《大数据技术原理与应用(第5版)》教材官网的“下载专区”的“软件”目录下去下载hbase-2.6.7-hadoop3-bin.tar.gz。或者也可以直接点击这里从百度云盘下载软件(提取码:ziyu)。进入百度网盘后,进入“软件”目录,找到hbase-2.6.7-hadoop3-bin.tar.gz文件,下载到本地。

2.解压缩文件

解压安装包hbase-2.6.7-hadoop3-bin.tar.gz至路径 /usr/local,命令如下:

cd ~
sudo tar -zxf ~/Downloads/hbase-2.6.7-hadoop3-bin.tar.gz -C /usr/local

将解压的文件名hbase-2.6.7改为hbase,以方便使用,命令如下:

cd /usr/local
sudo mv ./hbase-2.6.7 ./hbase

下面把hbase目录权限赋予给hadoop用户:

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

3.配置环境变量

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

vim ~/.bashrc

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

export PATH=$PATH:/usr/local/hbase/bin

如果已经引入过PATH请在export PATH这行追加/usr/local/hbase/bin,这里的“:”是分隔符。
编辑完成后,再执行source命令使上述配置在当前终端立即生效,命令如下:

source ~/.bashrc

4.添加HBase权限

cd /usr/local
sudo chown -R hadoop:hadoop ./hbase       #将hbase下的所有文件的所有者改为hadoop,hadoop是当前用户的用户名。

5.查看HBase版本,确定hbase安装成功,命令如下:

/usr/local/hbase/bin/hbase version

启动成功以后如下所示:

$ /usr/local/hbase/bin/hbase version
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/hbase/lib/client-facing-thirdparty/log4j-slf4j-impl-2.25.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/hadoop/share/hadoop/common/lib/slf4j-reload4j-1.7.36.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
HBase 2.6.7-hadoop3
Source code repository git://buildbox.localdomain/home/apurtell/tmp/RM-2.6/hbase revision=a1fad67ad9df4e81335b0524efbc7743fd6be811
Compiled by apurtell on Fri Aug 14 11:01:03 PDT 2026
From source with checksum 921665ba2f538b86f26ba78178db3759c35ea95fa6ce2c17ecd0f169b96f253410e26f21df8ead16bcd2c0e3e8e1a335343bb6e04f5158a7eeb5563ca6e620f5

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

6. 配置文件(伪分布式模式)

(1).配置/usr/local/hbase/conf/hbase-env.sh。命令如下:

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

配置JAVA_HOME,HBASE_CLASSPATH,HBASE_MANAGES_ZK.
HBASE_CLASSPATH设置为本机HBase安装目录下的conf目录(即/usr/local/hbase/conf)

export JAVA_HOME=/usr/lib/jvm/jdk-17.0.20.1+1
export HBASE_CLASSPATH=/usr/local/hbase/conf 
export HBASE_MANAGES_ZK=true

(2)配置/usr/local/hbase/conf/hbase-site.xml
用命令vi打开并编辑hbase-site.xml,命令如下:

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

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

<configuration>
        <property>
                <name>hbase.rootdir</name>
                <value>hdfs://localhost: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进程的错误
(3)接下来测试运行HBase
启动hadoop,如果已经启动hadoop请跳过此步骤。命令如下:

ssh localhost
cd /usr/local/hadoop
./sbin/start-dfs.sh

输入命令jps,能看到NameNode,DataNode和SecondaryNameNode都已经成功启动,表示Hadoop启动成功.

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

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

启动成功,输入命令jps,看到以下进程说明hbase启动成功.

4704 NameNode
5044 SecondaryNameNode
129865 Jps
4843 DataNode
129373 HRegionServer
129196 HMaster
128974 HQuorumPeer

进入shell界面:

bin/hbase shell

截图如下:

停止HBase运行,命令如下:

bin/stop-hbase.sh

二、HBase常用的Shell命令

HBase为用户提供了非常方便的Shell命令,通过这些Shell命令我们可以很方便地对表、列族、列等进行操作。下面介绍一些常用的Shell命令以及具体的操作实例。
在使用具体的Shell命令操作HBase数据之前,需要启动HBase,并且启动HBase Shell,进入Shell命令提示符状态。

1.在HBase中创建表

假设这里要创建一个表student,该表包含Sname、Ssex、Sage、Sdept、course等信息。这里可以为student表创建列族info和列族course,把Sname、Ssex、Sage、Sdept这些学生基本信息放在同一个列族info下,把不同课程的信息放在同一个列族course下。需要注意的是,在关系数据库(如MySQL)中,需要先创建数据库,再创建表,但是,在HBase数据库中,不需要创建数据库,直接创建表即可。在HBase中创建student表的Shell命令如下:

hbase> create 'student','info’,’course’

创建完student表,可通过describe命令查看student表的基本信息,具体命令如下:

hbase> describe 'student'

可以使用list命令查看当前HBase数据库中已经创建了哪些表,具体命令如下:

hbase> list

2.添加数据

HBase使用put命令添加数据,一次只能为一个表的一行数据的一个列(也就是一个单元格,单元格是HBase中的基本概念)添加一个数据,所以直接用Shell命令插入数据的效率很低,在实际应用中,一般是利用编程操作数据。因为这里只需要插入1条学生记录,所以我们可以用Shell命令手动插入数据,具体命令如下:

hbase> put 'student','26001','info:Sname','LiYing'

上面的put命令会为student表添加学号为'95001'、名字为'LiYing'的一个单元格数据,其行键为95001,也就是说,系统默认把跟在表名student后的第一个数据作为行键。
下面继续添加5个单元格的数据,用来记录LiYing同学的相关信息,具体命令如下:

hbase> put 'student','26001','info:Ssex','male'
hbase> put 'student','26001','info:Sage','22'
hbase> put 'student','26001','info:Sdept','CS'
hbase> put 'student','26001','course:math','80'
hbase> put 'student','26001','course:computer','91'

3.查看数据

HBase中有如下两个用于查看数据的命令。
(1)get命令:用于查看表的某一个单元格数据。
(2)scan命令:用于查看某个表的全部数据。
比如,可以执行以下命令返回student表中95001行的数据:

hbase> get 'student','26001'

下面使用scan命令查询student表的全部数据:

hbase> scan 'student'

4.删除数据

在HBase中用delete及deleteall命令进行删除数据操作,二者的区别是:delete命令用于删除一个单元格数据,是put命令的反向操作;而 deleteall命令用于删除一行数据。
首先,使用delete命令删除student表中95001行中Ssex列的所有数据,具体命令如下:

hbase > delete 'student','26001','info:Ssex'

然后,使用deleteall命令删除student表中95001行的全部数据,具体命令如下:

hbase> deleteall 'student','26001'

5.删除表

删除表需要分两步操作,第一步先让该表不可用,第二步删除表。比如,要删除student表,可以执行以下命令:

hbase> disable 'student'
hbase> drop 'student'

6.查询历史数据

在添加数据时,HBase会自动为添加的数据添加一个时间戳。在修改数据时,HBase会为修改后的数据生成一个新的版本(时间戳),从而完成“改”操作,旧的版本依旧保留,系统会定时回收垃圾数据,只留下最新的几个版本,保存的版本数可以在创建表的时候指定。
为了查询历史数据,这里创建一个teacher表。首先,在创建表的时候,需要指定保存的版本数(假设指定为5),命令如下:

hbase> create 'teacher',{NAME=>'info',VERSIONS=>5}

然后,插入数据,并更新数据,使其产生历史版本数据。需要注意的是,这里插入数据和更新数据都使用了put命令,具体如下:

hbase> put 'teacher','91001','info:username','Mary'
hbase> put 'teacher','91001','info:username','Mary1'
hbase> put 'teacher','91001','info:username','Mary2'
hbase> put 'teacher','91001','info:username','Mary3'
hbase> put 'teacher','91001','info:username','Mary4'  
hbase> put 'teacher','91001','info:username','Mary5'

查询时,默认情况下会显示当前最新版本的数据,如果要查询历史版本数据,需要指定查询的历史版本数,由于上面设置了保存的版本数为5,所以在查询时指定的历史版本数的有效取值为1~5,具体命令如下:

hbase> get 'teacher','91001',{COLUMN=>'info:username',VERSIONS=>5}
hbase> get 'teacher','91001',{COLUMN=>'info:username',VERSIONS=>3}

三、HBase Java API编程实践

本实例采用Ubuntu中的TRAE CN开发工具,通过HBase提供的Java API完成创建表、插入数据和查询数据的操作。

1. 创建HBaseExample项目

启动TRAE CN,进入IDE界面。在左侧扩展面板中搜索java,安装“Extension Pack for Java”。已经安装该扩展包的读者可以直接进行后面的操作。该扩展包包含Java语言支持、调试和项目管理等功能,相关功能可参考Java扩展与项目管理说明。

在Ubuntu终端创建用于存放Java项目的父目录:

mkdir -p /home/hadoop/Documents/trae_projects

在TRAE左侧资源管理器中点击鼠标右键,在弹出的菜单中选择“创建Java项目...”。也可以按Ctrl+Shift+P打开命令面板,输入并选择“Java: Create Java Project...”。

图5-9 创建Java项目

在项目类型选择界面选择“No build tools”,创建一个普通Java项目。

随后在文件夹选择窗口中,选择你希望存放项目的文件夹,再点击右下角的“Select the project location”。项目保存位置可以自行选择,截图中的目录仅供参考。

图5-10 选择项目存放目录

在项目名称输入框中输入“HBaseExample”,按Enter确认。

图5-11 输入项目名称

项目创建完成以后,打开HBaseExample文件夹。

项目中通常包含src、bin、lib和.vscode等目录,并在src中生成App.java。点击打开App.java,等待Java扩展完成初始化,资源管理器下方就会显示“Java Projects”视图。

图5-12 打开Java文件并激活Java Projects视图

如果暂时看不到“Java Projects”,先确认已经打开App.java并等待项目加载完成,再通过资源管理器标题栏的“...”菜单勾选“Java Projects”。如果Java语言服务处于轻量模式,应按状态栏提示切换到标准模式,才能解析依赖并运行程序。

2. 为项目添加JAR依赖

为了编写能够与HBase交互的Java程序,需要为项目添加HBase的Java接口及其依赖。本教程的HBase安装目录为/usr/local/hbase。

在“Java Projects”视图中展开HBaseExample,找到“Referenced Libraries(引用的库)”。将鼠标移到该行,点击右侧的“+”,打开JAR文件选择窗口。

图5-13 添加JAR文件到项目Classpath

先进入/usr/local/hbase/lib,选中当前目录下的.jar文件(注意,不要选中client-facing-thirdparty、jdk11、ruby、shaded-clients、trace和zkcli这六个目录),这里可以用按Ctrl+Shift批量选中,对于不需要选中的文件再用Ctrl取消选中,最后点击右下角的“Select Jar Libraries”。

图5-14 选择HBase lib目录中的JAR文件

随后再次点击“Referenced Libraries”右侧的“+”,进入/usr/local/hbase/lib/client-facing-thirdparty目录,选中其中的.jar文件,再点击“Select Jar Libraries”。

图5-15 选择client-facing-thirdparty目录中的JAR文件

本节需要添加的依赖目录如下:

目录 添加内容
/usr/local/hbase/lib 当前目录中的.jar文件
/usr/local/hbase/lib/client-facing-thirdparty 当前目录中的.jar文件

添加完成后,可以展开“Referenced Libraries”查看依赖是否已经加载。

3. 创建ExampleForHBase类

在资源管理器中找到HBaseExample项目的src目录,点击鼠标右键,依次选择“创建Java类”和“类...”。

图5-16 创建Java类

在类名输入框中输入“ExampleForHBase”,按Enter确认。

图5-17 输入类名ExampleForHBase

打开生成的ExampleForHBase.java文件,使用下面的完整代码替换文件中的内容并保存。文件名必须是ExampleForHBase.java,与代码中的public class名称一致。本实例不声明package,文件直接放在src目录下。

客户端通过读取/usr/local/hbase/conf/hbase-site.xml获得HBase连接配置。这里使用的是Ubuntu虚拟机中的路径;仅在Java代码中设置hbase.rootdir不能代替ZooKeeper等客户端连接配置。若HBase安装在其他目录,应同步修改init方法中的配置文件路径。

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.util.Bytes;

public class ExampleForHBase {
    public static Configuration configuration;
    public static Connection connection;
    public static Admin admin;

    public static void main(String[] args) throws IOException {
        try {
            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");
        } finally {
            close();
        }
    }

    public static void init() throws IOException {
        configuration = HBaseConfiguration.create();
        configuration.addResource(new Path("/usr/local/hbase/conf/hbase-site.xml"));
        connection = ConnectionFactory.createConnection(configuration);
        admin = connection.getAdmin();
    }

    public static void createTable(String myTableName, String[] colFamilies)
            throws IOException {
        TableName tableName = TableName.valueOf(myTableName);
        if (!admin.tableExists(tableName)) {
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName);
            for (String family : colFamilies) {
                builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));
            }
            admin.createTable(builder.build());
            return;
        }

        if (!admin.isTableEnabled(tableName)) {
            throw new IOException(myTableName + " 表已禁用,请先在HBase Shell中执行 enable '"
                    + myTableName + "'。");
        }

        TableDescriptor descriptor = admin.getDescriptor(tableName);
        for (String family : colFamilies) {
            if (!descriptor.hasColumnFamily(Bytes.toBytes(family))) {
                admin.addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of(family));
            }
        }
    }

    public static void insertData(String tableName, String rowKey, String colFamily,
            String col, String val) throws IOException {
        try (Table table = connection.getTable(TableName.valueOf(tableName))) {
            Put put = new Put(Bytes.toBytes(rowKey));
            put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(val));
            table.put(put);
        }
    }

    public static void getData(String tableName, String rowKey, String colFamily,
            String col) throws IOException {
        try (Table table = connection.getTable(TableName.valueOf(tableName))) {
            Get get = new Get(Bytes.toBytes(rowKey));
            get.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col));
            Result result = table.get(get);
            byte[] value = result.getValue(Bytes.toBytes(colFamily), Bytes.toBytes(col));
            System.out.println(value == null ? "未找到指定单元格的数据" : Bytes.toString(value));
        }
    }

    public static void close() throws IOException {
        try {
            if (admin != null) {
                admin.close();
            }
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }
}

4. 运行Java程序

保存ExampleForHBase.java,等待Java扩展完成编译和依赖解析。在编辑器右上角点击运行按钮“Run Java”,或者点击main方法上方的“Run”。确认运行的是ExampleForHBase,而不是项目自动生成的App。

图5-18 TRAE中的Run Java运行入口

程序运行成功以后,终端中会显示69,这是行键zhangsan的score:English单元格中的值。运行记录如下图所示:
图5-19 Java程序输出英语成绩69

如果程序提示找不到org.apache.hadoop.hbase等类,应先检查前面两个目录中的JAR是否已经加入Classpath。如果程序长时间等待或提示无法连接ZooKeeper,应检查HDFS和HBase服务是否已经启动,以及程序读取的hbase-site.xml是否与服务使用的配置一致。

5. 在HBase Shell中验证结果

在Ubuntu终端进入HBase Shell:

cd /usr/local/hbase
bin/hbase shell

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

list

该命令执行效果如下图所示:

图5-20 查看student表是否创建成功

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

scan 'student'

该命令执行效果如下图所示:

图5-21 查看student表中的数据