大数据技术原理(四) 熟悉常用的 Hbase 操作

(实验二 熟悉常用的 Hbase 操作

--------------------------------------------------------------------------------------------------------------------------------

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊!

喜欢我的博客的话,记得点个红心❤️和小关小注哦!您的支持是我创作的动力!(有什么问题可以私信)

一、实验目的

1.理解 HBase 在 Hadoop体系结构中的角色。

分布式存储:HBase以分布式方式存储数据,利用HDFS作为底层存储介质,确保数据的高可用性和可靠性。面向列的存储:HBase将数据按列存储,提供高效的随机读写能力,尤其适合需要频繁访问单个数据列的应用场景。实时读写:HBase支持实时的数据读写,能够满足对数据实时性要求较高的应用需求,如在线交易处理、日志分析等。整合Hadoop生态系统:HBase与其他Hadoop生态系统组件(如HDFS、MapReduce、YARN等)紧密集成,能够协同工作,提供全面的大数据解决方案。

2.熟练 HBase 操作常用的 Shell命令。

# 创建表
create 'student', 'info', 'score'
        # 插入数据
put 'student', '001', 'info:name', 'Alice'
        # 获取数据
get 'student', '001'
        # 扫描表
scan 'student'
        # 删除数据
delete 'student', '001', 'info:age'
        # 删除表
disable 'student'
drop 'student'

3.熟悉 HBase 操作常用的 JavaAPI。

熟悉HDFS操作常用的Java API:除了Shell命令,HBase提供了一套Java API,开发者通过编程的方式操作HDFS。

二、实验环境

1. VMware WorkStation Pro 16

2. Jdk 1.8.0_241

3. Hadoop2.7.5

4. Zookeeper3.4.6

5. HBase2.1.0

三、实验原理

1. 连接Hbase集群

创建一个HBase配置对象,设置ZooKeeper的主机名或IP地址。通过ConnectionFactory类创建一个Connection对象,用于与HBase集群建立连接。

2. 插入Hbase数据

创建一个Put对象,指定要插入数据的行键,然后添加列族、列限定符和对应的值。通过Table对象的put方法将数据插入到HBase表中。

3. 读取Hbase数据

创建一个Get对象,指定要读取数据的行键,可添加列族和列限定符进行条件查询。通过Table对象的get方法获取指定行的数据,返回一个Result对象。从Result对象中提取数据。

4. 修改Hbase数据

创建一个Put对象,指定要修改数据的行键,然后添加列族、列限定符和对应的新值。通过Table对象的put方法执行修改操作,将新值覆盖原有的值。

5. 删除Hbase数据

创建一个Delete对象,指定要删除数据的行键。通过Table对象的delete方法执行删除操作,从HBase表中删除指定行的数据。

  1. 实验原理解释

HBase是一个分布式、可扩展、面向列的NoSQL数据库,通过Java客户端API可以访问和操作HBase。Java代码与HBase集群建立连接,通过Connection对象获取Table对象,用于操作HBase表。插入数据使用Put对象,指定行键和列族、列限定符以及对应的值,将数据插入到HBase表中。读取数据使用Get对象,指定要读取的行键和列族、列限定符,从HBase表中获取指定行的数据。修改数据也使用Put对象,指定要修改的行键和列族、列限定符以及新值,通过put方法执行修改操作。删除数据使用Delete对象,指定要删除的行键,通过delete方法执行删除操作,从HBase表中删除指定行的数据。这些操作可以通过Java代码实现,实现了对HBase表中数据的增加、删除、修改和查询。

四、实验步骤与实验结果

(一)安装Zookeeper。

1.准备安装包。

rz zookeeper-3.4.6.tar.gz

2.解压。

tar zxvf zookeeper-3.4.6.tar.gz -C /export/server/

3.创建文件夹zkdata,并建立三个节点文件夹zk。

# 切换到数据目录

cd /export/data/

# 创建zkdata文件夹,并建立子文件夹

mkdir zkdata

cd zkdata

mkdir zk1

mkdir zk2

mkdir zk3

4.创建zoo.cfg文件。

# 第一个文件

cd /export/data/zkdata/zk1

vim zoo1.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/export/data/zkdata/zk1

clientPort=2181

server.1=192.168.88.100:2888:3888

server.2=192.168.88.100:2889:3889

server.3=192.168.88.100:2890:3890

# 第二个文件

cd /export/data/zkdata/zk2

vim zoo2.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/export/data/zkdata/zk2

clientPort=2182

server.1=192.168.88.100:2888:3888

server.2=192.168.88.100:2889:3889

server.3=192.168.88.100:2890:3890

# 第三个文件

cd /export/data/zkdata/zk3

vim zoo3.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/export/data/zkdata/zk3

clientPort=2183

server.1=192.168.88.100:2888:3888

server.2=192.168.88.100:2889:3889

server.3=192.168.88.100:2890:3890

5.创建文件myid。

#在每台机器的dataDir指定的目录下创建一个文件 名字叫做myid

#myid里面的数字就是该台机器上server编号。server.N  N的数字就是编号

[root@node1 conf]# echo 1 >/export/data/zkdata/zk1/myid

[root@node1 conf]# echo 2 >/export/data/zkdata/zk2/myid

[root@node1 conf]# echo 3 >/export/data/zkdata/zk3/myid

6.启动单台zookeeper服务。

#在哪个目录执行启动命令 默认启动日志就生成当前路径下 叫做zookeeper.out

/export/server/zookeeper/bin/zkServer.sh start /export/data/zkdata/zk1/zoo1.cfg                             # 启动命令

jps # 查看服务进程

/export/server/zookeeper/bin/zkServer.sh stop /export/data/zkdata/zk1/zoo1.cfg                             # 关闭命令

7.封装脚本启动zookeeper服务。

本质:在node1机器上执行shell脚本,由shell程序通过ssh免密登录到各个机器上帮助执行命令。

一键关闭脚本

[root@node1 ~]# vim stopZk.sh

#!/bin/bash

hosts=(node1)

for host in ${hosts[*]}

do

 ssh $host "/export/server/zookeeper/bin/zkServer.sh stop /export/data/zkdata/zk1/zoo1.cfg"

done

一键启动脚本

[root@node1 ~]# vim stopZk.sh

#!/bin/bash

hosts=(node1)

for host in ${hosts[*]}

do

 ssh $host "/export/server/zookeeper/bin/zkServer.sh start /export/data/zkdata/zk1/zoo1.cfg"

done

(二)安装HBase。

1.准备安装包。

rz hbase-2.1.0.tar.gz

2.上传、解压。

tar -zxvf hbase-2.1.0.tar.gz -C /export/server/

3.修改配置文件hbase-env.sh。

# 切换到配置文件目录下

cd /export/server/hbase-2.1.0/conf/

# 修改hbase-env.sh

#28行

export JAVA_HOME=/export/server/jdk1.8.0_241

#125行

export HBASE_MANAGES_ZK=false

4.修改配置文件hbase-site.sh。

# 修改hbase-site.xml

cd /export/server/hbase-2.1.0/

mkdir datas

vim conf/hbase-site.xml

 <property >

    <name>hbase.tmp.dir</name>

    <value>/export/server/hbase-2.1.0/datas</value>

  </property>

    <property >

    <name>hbase.rootdir</name>

    <value>hdfs://node1:8020/hbase</value>

  </property>

  <property >

    <name>hbase.cluster.distributed</name>

    <value>true</value>

  </property>

  <property>

    <name>hbase.zookeeper.quorum</name>

    <value>node1</value>

  </property>

  <property>

    <name>hbase.unsafe.stream.capability.enforce</name>

    <value>false</value>

  </property>

5.修改配置文件regionservers。

vim conf/regionservers

node1

6.配置环境变量。

vim /etc/profile

#HBASE_HOME

export HBASE_HOME=/export/server/hbase-2.1.0

export PATH=:$PATH:$HBASE_HOME/bin

# 刷新环境变量

source /etc/profile

7.复制jar包。

#切换目录

cd /export/server/hbase-2.1.0

# 复制jar包到lib目录

cp lib/client-facing-thirdparty/htrace-core-3.1.0-incubating.jar lib/

8.启动hbase服务。

# 首先启动hdfs

cd /export/server/hadoop-2.7.5/sbin

./start-all.sh

# 再启动zookeeper

cd

./startZk.sh

# 最后启动hbase

cd /export/server/hbase-2.1.0/bin

./start-hbase.sh

9.关闭hbase服务。

# 首先关闭hbase

cd /export/server/hbase-2.1.0/bin

./stop-hbase.sh

# 再关闭zookeeper

cd

./stopZk.sh

# 最后关闭hdfs

cd /export/server/hadoop-2.7.5/sbin

./stop-all.sh

10.观察Hbase的UI界面。

# 浏览器上打开

node1:16010

(三)编程实现一下指定功能,并用hadoop提供的hbase shell命令完成相同的任务。

1.提前准备实验数据。

# 进入命令行shell模式

hbase shell

# 当创建 HBase 表时,需要使用 create 命令,并设置好表的名称、列族等信息

# 这条命令会创建一个名为 student 的表,包含两个列族,分别为 info 和 score。

create 'student', 'info', 'score'

# 可以使用 put 命令向表中插入数据,

put 'student', '001', 'info:name', 'Tom'

put 'student', '001', 'info:gender', 'male'

put 'student', '001', 'score:math', '85'

put 'student', '001', 'score:english', '78'

2.列出Hbase所有表的相关信息,如表名,创建时间等。

(1)shell版本

# hbase罗列数据表

list

# 表信息

scan 'student'

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 09:36:56
 * @description TODO
 */

import org.apache.hadoop.conf.Configuration;
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.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;


import java.io.IOException;

public class result_1_1 {
    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    public static void main(String[] args) throws IOException {
        // 创建 HBase 配置
        Configuration config = HBaseConfiguration.create();

        // 设置HBase集群的ZooKeeper节点的主机名
        config.set("hbase.zookeeper.quorum", "node1");

        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {

            // 列出所有数据表
            TableName[] tableNames = admin.listTableNames();
            System.out.println(RED_COLOR + "List of Tables:" + RESET_COLOR);
            for (TableName tableName : tableNames) {
                System.out.println(tableName.getNameAsString());
            }
            System.out.println("-------------------------------------");

            // 获取指定表的信息
            String tableName = "student";
            // 根据表名获取表对象
            try (Table table = connection.getTable(TableName.valueOf(tableName))) {
                Scan scan = new Scan();
                // 获取扫描结果
                org.apache.hadoop.hbase.client.ResultScanner scanner = table.getScanner(scan);
                System.out.println(RED_COLOR + "Table: " + tableName + RESET_COLOR);

                // 遍历结果并打印
                for (Result result : scanner) {
                    System.out.println(result);
                }

System.out.println("-------------------------------------");
            }
        }
    }
}

3.在终端打印指定表的所有记录数据。

(1)shell版本

# 表信息

scan 'student'

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 10:42:32
 * @description TODO
 */

import org.apache.hadoop.conf.Configuration;
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.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

public class result_1_2 {
    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    public static void main(String[] args) throws IOException {
        // 创建 HBase 配置
        Configuration config = HBaseConfiguration.create();

        // 设置HBase集群的ZooKeeper节点的主机名
        config.set("hbase.zookeeper.quorum", "node1");

        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {

            // 获取指定表的信息
            String tableName = "student";
            // 根据表名获取表对象
            try (Table table = connection.getTable(TableName.valueOf(tableName))) {
                Scan scan = new Scan();
                // 获取扫描结果
                org.apache.hadoop.hbase.client.ResultScanner scanner = table.getScanner(scan);
                System.out.println(RED_COLOR + "Table: " + tableName + RESET_COLOR);

                // 遍历结果并打印
                for (Result result : scanner) {
                    System.out.println(RED_COLOR + "Row key: " + Bytes.toString(result.getRow()) + RESET_COLOR);
                    for (Cell cell : result.listCells()) {
                        String family = Bytes.toString(CellUtil.cloneFamily(cell));
                        String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
                        String value = Bytes.toString(CellUtil.cloneValue(cell));
                        long timestamp = cell.getTimestamp();
                        System.out.println("Family: " + family);
                        System.out.println("Qualifier: " + qualifier);
                        System.out.println("Value: " + value);
                        System.out.println("Timestamp: " + timestamp);
                        System.out.println("-------------------------------------");
                    }
                }
            }
        }
    }
}

4.向已经创建好的表添加和删除指定的列族或者列。

(1)shell版本

# 添加列簇

alter 'student', {NAME => 'newColumnFamily'}

# 删除列簇

alter 'student', {NAME => 'newColumnFamily', METHOD => 'delete'}

# 添加列

put 'student', '001', 'info:newColumn', 'NewValue'

# 删除列

delete 'student', '001', 'info:newColumn'

==============经过以上操作:数据表student不变==================

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 11:09:20
 * @description 该类包含了对HBase数据库进行列簇和列操作的方法,并且提供了一个示例方法进行测试。
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

public class result_1_3 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    // 获取HBase配置
    public static Configuration getHBaseConfiguration() {
        Configuration config = HBaseConfiguration.create();
        // 设置ZooKeeper集群地址
        config.set("hbase.zookeeper.quorum", "node1");
        return config;
    }

    // 添加列簇
    public static void addColumnFamily(String tableName, String newColumnFamily) throws IOException {
        Configuration config = getHBaseConfiguration();

        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {
            TableName table = TableName.valueOf(tableName);

            // 获取当前表的描述信息
            TableDescriptor currentDescriptor = admin.getDescriptor(table);

            // 创建新列簇的描述信息
            ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes(newColumnFamily))
                    .build();

            // 更新表的描述信息,添加新的列簇
            TableDescriptor newDescriptor = TableDescriptorBuilder
                    .newBuilder(currentDescriptor)
                    .setColumnFamily(columnFamilyDescriptor)
                    .build();

            admin.modifyTable(newDescriptor);
            System.out.println(RED_COLOR + "Successfully added column family: " + RESET_COLOR);
            System.out.println(newColumnFamily);
            System.out.println("================================================================");
        }
    }

    // 删除列簇
    public static void deleteColumnFamily(String tableName, String columnFamily) throws IOException {
        Configuration config = getHBaseConfiguration();

        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {
            TableName table = TableName.valueOf(tableName);

            // 获取当前表的描述信息
            TableDescriptor currentDescriptor = admin.getDescriptor(table);

            // 创建新的表描述构造器
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(currentDescriptor);

            // 从表描述中移除指定的列簇
            builder.removeColumnFamily(Bytes.toBytes(columnFamily));

            // 应用更新后的表描述信息
            admin.modifyTable(builder.build());
            System.out.println(RED_COLOR + "Successfully deleted column family: " + RESET_COLOR);
            System.out.println(columnFamily);
            System.out.println("================================================================");
        }
    }

    // 添加列
    public static void addColumn(String tableName, String rowKey, String columnFamily, String qualifier, String value) throws IOException {
        Configuration config = getHBaseConfiguration();

        try (Connection connection = ConnectionFactory.createConnection(config);
             Table table = connection.getTable(TableName.valueOf(tableName))) {
            // 创建Put对象并添加列数据
            Put put = new Put(Bytes.toBytes(rowKey));
            put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier), Bytes.toBytes(value));
            // 将数据写入表中
            table.put(put);
            System.out.println(RED_COLOR + "Successfully added column: " + RESET_COLOR);
            System.out.println(qualifier);
            System.out.println(RED_COLOR + " with value: " + RESET_COLOR);
            System.out.println(value);
            System.out.println("================================================================");
        }
    }

    // 删除列
    public static void deleteColumn(String tableName, String rowKey, String columnFamily, String qualifier) throws IOException {
        Configuration config = getHBaseConfiguration();

        try (Connection connection = ConnectionFactory.createConnection(config);
             Table table = connection.getTable(TableName.valueOf(tableName))) {
            // 创建Delete对象并删除指定列数据
            Delete delete = new Delete(Bytes.toBytes(rowKey));
            delete.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier));
            // 执行删除操作
            table.delete(delete);
            System.out.println(RED_COLOR + "Successfully deleted column: " + RESET_COLOR);
            System.out.println(qualifier);
            System.out.println("================================================================");
        }
    }

    // 主方法
    public static void main(String[] args) {
        String tableName = "student";
        String newColumnFamily = "newColumnFamily";
        String rowKey = "001";
        String columnFamily = "info";
        String qualifier = "newColumn";
        String value = "NewValue";

        try {
            // 运行示例方法进行测试
            addColumnFamily(tableName, newColumnFamily);
            deleteColumnFamily(tableName, newColumnFamily);
            addColumn(tableName, rowKey, columnFamily, qualifier, value);
            deleteColumn(tableName, rowKey, columnFamily, qualifier);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5.清空指定表的所有记录数据。

(1)shell版本

truncate 'student'

# 如果执行完之后,表就是空表了,记得补充数据进去才能进行java实验!

put 'student', '001', 'info:name', 'Tom'

put 'student', '001', 'info:gender', 'male'

put 'student', '001', 'score:math', '85'

put 'student', '001', 'score:english', '78'

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 15:48:38
 * @description TODO
 */
import org.apache.hadoop.conf.Configuration;
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.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;

import java.io.IOException;

public class result_1_4 {
    // 获取HBase配置信息,设置ZooKeeper的主机名或IP地址
    public static Configuration getHBaseConfiguration(String zkHost) {
        Configuration config = HBaseConfiguration.create();
        config.set("hbase.zookeeper.quorum", zkHost);
        return config;
    }

    // 清空指定表数据
    public static void truncateTable(String tableName, String zkHost) throws IOException {
        Configuration config = getHBaseConfiguration(zkHost);
        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {
            TableName table = TableName.valueOf(tableName);
            admin.disableTable(table);
            admin.truncateTable(table, true);
        }
    }

    public static void main(String[] args) {
        String tableName = "student";
        String zkHost = "node1"; // 指定ZooKeeper的主机名或IP地址
        try {
            // 调用清空表数据的方法
            truncateTable(tableName, zkHost);
            System.out.println("Table " + tableName + " truncated successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

# 如果执行完之后,表就是空表了,记得补充数据进去才能进行一个实验!

put 'student', '001', 'info:name', 'Tom'

put 'student', '001', 'info:gender', 'male'

put 'student', '001', 'score:math', '85'

put 'student', '001', 'score:english', '78'

6.统计表的行数。

(1)shell版本

Count student

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 15:56:11
 * @description TODO
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;


import java.io.IOException;

public class result_1_5 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    public static void main(String[] args) {

        // 指定表名
        String tableName = "student";

        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();
        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config);
             Table table = connection.getTable(TableName.valueOf(tableName))) {
            // 创建Scan对象,并设置扫描参数
            Scan scan = new Scan();
            ResultScanner scanner = table.getScanner(scan);

            int count = 0;
            // 遍历结果集
            for (Result result : scanner) {
                count++;
            }

            // 输出行数
            System.out.println(RED_COLOR + "Number of rows in table " + tableName + RESET_COLOR + ": " + count);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(四)现有以下关系型数据库中的表(见表4-20、表4-21、表4-22),要求将其转换为适合HBase存储的表并插入数据。

表4-20                           学生表(Student)

学号(S_No)

姓名(S_Name)

性别(S_Sex)

年龄(A_Age)

2015001

Zhangsan

male

23

2015002

Mary

female

22

2015003

Lisi

male

24

表4-21                           课程表(Course)

课程号(C_No)

课程名(C_Name)

学分(C_Credit)

123001

Math

2.0

123001

Computer Science

5.0

123003

English

3.0

表4-22                           选课表(SC)

学号(SC_Sno)

课程号(SC_Cno)

成绩(SC_Score)

2015001

123001

86

2015001

123003

69

2015002

123002

77

2015002

123003

99

2015003

123001

98

2015003

123002

95

1.准备数据源

(1)shell版本

# 创建学生表

create 'Student', 'info'

# 插入学生数据

put 'student', '2015001', 'info:S_No', '2015001'

put 'student', '2015001', 'info:S_Name', 'Zhangsan'

put 'student', '2015001', 'info:S_Sex', 'male'

put 'student', '2015001', 'info:A_Age', '23'

put 'student', '2015002', 'info:S_No', '2015002'

put 'student', '2015002', 'info:S_Name', 'Mary'

put 'student', '2015002', 'info:S_Sex', 'female'

put 'student', '2015002', 'info:A_Age', '22'

put 'student', '2015003', 'info:S_No', '2015003'

put 'student', '2015003', 'info:S_Name', 'Lisi'

put 'student', '2015003', 'info:S_Sex', 'male'

put 'student', '2015003', 'info:A_Age', '24'

# 创建课程表

create 'Course', 'info'

# 插入课程数据

put 'Course', '123001', 'info:C_No', '123001'

put 'Course', '123001', 'info:C_Name', 'Math'

put 'Course', '123001', 'info:C_Credit', '2.0'

put 'Course', '123002', 'info:C_No', '123002'

put 'Course', '123002', 'info:C_Name', 'Computer Science'

put 'Course', '123002', 'info:C_Credit', '5.0'

put 'Course', '123003', 'info:C_No', '123003'

put 'Course', '123003', 'info:C_Name', 'English'

put 'Course', '123003', 'info:C_Credit', '3.0'

# 创建选课表

create 'SC', 'info'

# 插入选课数据

put 'SC', '2015001', 'info:SC_Sno', '2015001'

put 'SC', '2015001', 'info:SC_Cno', '123001'

put 'SC', '2015001', 'info:SC_Score', '86'

put 'SC', '2015001', 'info:SC_Sno', '2015001'

put 'SC', '2015001', 'info:SC_Cno', '123003'

put 'SC', '2015001', 'info:SC_Score', '69'

put 'SC', '2015002', 'info:SC_Sno', '2015002'

put 'SC', '2015002', 'info:SC_Cno', '123002'

put 'SC', '2015002', 'info:SC_Score', '77'

put 'SC', '2015002', 'info:SC_Sno', '2015002'

put 'SC', '2015002', 'info:SC_Cno', '123003'

put 'SC', '2015002', 'info:SC_Score', '99'

put 'SC', '2015003', 'info:SC_Sno', '2015003'

put 'SC', '2015003', 'info:SC_Cno', '123001'

put 'SC', '2015003', 'info:SC_Score', '98'

put 'SC', '2015003', 'info:SC_Sno', '2015003'

put 'SC', '2015003', 'info:SC_Cno', '123002'

put 'SC', '2015003', 'info:SC_Score', '95'

(2)Java版本

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 16:17:04
 * @description TODO
 */
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 result_2_1 {

    public static void main(String[] args) {

        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();  // 创建HBase配置对象

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {  // 使用try-with-resources语句创建HBase连接
            Admin admin = connection.getAdmin();  // 获取HBase管理员对象

            // 创建学生表
            TableName studentTableName = TableName.valueOf("Student");  // 定义学生表名
            HTableDescriptor studentTableDesc = new HTableDescriptor(studentTableName);  // 创建学生表描述符
            HColumnDescriptor studentColumnInfo = new HColumnDescriptor(Bytes.toBytes("info"));  // 创建学生表列族描述符
            studentTableDesc.addFamily(studentColumnInfo);  // 向学生表中添加列族
            admin.createTable(studentTableDesc);  // HBase中创建学生表

            // 插入学生数据
            Table studentTable = connection.getTable(studentTableName);  // 获取学生表对象
            putData(studentTable, "2015001", "info", "S_No", "2015001");  // 向学生表中插入数据
            putData(studentTable, "2015001", "info", "S_Name", "Zhangsan");
            putData(studentTable, "2015001", "info", "S_Sex", "male");
            putData(studentTable, "2015001", "info", "A_Age", "23");

            putData(studentTable, "2015002", "info", "S_No", "2015002");
            putData(studentTable, "2015002", "info", "S_Name", "Mary");
            putData(studentTable, "2015002", "info", "S_Sex", "female");
            putData(studentTable, "2015002", "info", "A_Age", "22");

            putData(studentTable, "2015003", "info", "S_No", "2015003");
            putData(studentTable, "2015003", "info", "S_Name", "Lisi");
            putData(studentTable, "2015003", "info", "S_Sex", "male");
            putData(studentTable, "2015003", "info", "A_Age", "24");

            // 创建课程表
            TableName courseTableName = TableName.valueOf("Course");  // 定义课程表名
            HTableDescriptor courseTableDesc = new HTableDescriptor(courseTableName);  // 创建课程表描述符
            HColumnDescriptor courseColumnInfo = new HColumnDescriptor(Bytes.toBytes("info"));  // 创建课程表列族描述符
            courseTableDesc.addFamily(courseColumnInfo);  // 向课程表中添加列族
            admin.createTable(courseTableDesc);  // HBase中创建课程表

            // 插入课程数据
            Table courseTable = connection.getTable(courseTableName);  // 获取课程表对象
            putData(courseTable, "123001", "info", "C_No", "123001");  // 向课程表中插入数据
            putData(courseTable, "123001", "info", "C_Name", "Math");
            putData(courseTable, "123001", "info", "C_Credit", "2.0");

            putData(courseTable, "123002", "info", "C_No", "123002");
            putData(courseTable, "123002", "info", "C_Name", "Computer Science");
            putData(courseTable, "123002", "info", "C_Credit", "5.0");

            putData(courseTable, "123003", "info", "C_No", "123003");
            putData(courseTable, "123003", "info", "C_Name", "English");
            putData(courseTable, "123003", "info", "C_Credit", "3.0");

            // 创建选课表
            TableName scTableName = TableName.valueOf("SC");  // 定义选课表名
            HTableDescriptor scTableDesc = new HTableDescriptor(scTableName);  // 创建选课表描述符
            HColumnDescriptor scColumnInfo = new HColumnDescriptor(Bytes.toBytes("info"));  // 创建选课表列族描述符
            scTableDesc.addFamily(scColumnInfo);  // 向选课表中添加列族
            admin.createTable(scTableDesc);  // HBase中创建选课表

            // 插入选课数据
            Table scTable = connection.getTable(scTableName);  // 获取选课表对象
            putData(scTable, "2015001", "info", "SC_Sno", "2015001");  // 向选课表中插入数据
            putData(scTable, "2015001", "info", "SC_Cno", "123001");
            putData(scTable, "2015001", "info", "SC_Score", "86");

            putData(scTable, "2015001", "info", "SC_Sno", "2015001");
            putData(scTable, "2015001", "info", "SC_Cno", "123003");
            putData(scTable, "2015001", "info", "SC_Score", "69");

            putData(scTable, "2015002", "info", "SC_Sno", "2015002");
            putData(scTable, "2015002", "info", "SC_Cno", "123002");
            putData(scTable, "2015002", "info", "SC_Score", "77");

            putData(scTable, "2015002", "info", "SC_Sno", "2015002");
            putData(scTable, "2015002", "info", "SC_Cno", "123003");
            putData(scTable, "2015002", "info", "SC_Score", "99");

            putData(scTable, "2015003", "info", "SC_Sno", "2015003");
            putData(scTable, "2015003", "info", "SC_Cno", "123001");
            putData(scTable, "2015003", "info", "SC_Score", "98");

            putData(scTable, "2015003", "info", "SC_Sno", "2015003");
            putData(scTable, "2015003", "info", "SC_Cno", "123002");
            putData(scTable, "2015003", "info", "SC_Score", "95");

            System.out.println("数据插入成功!");  // 打印数据插入成功的消息
        } catch (IOException e) {
            e.printStackTrace();  // 捕获并打印异常信息
        }
    }

    // 向表中插入数据的方法
    private static void putData(Table table, String rowKey, String family, String qualifier, String value) throws IOException {
        Put put = new Put(Bytes.toBytes(rowKey));  // 创建一个Put对象
        put.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier), Bytes.toBytes(value));  // Put对象中添加要插入的数据
        table.put(put);  // 将数据插入到表中
    }
}

(五)同时,请编程完成以下指定功能。

1.createTable(String tableName, String[] fields)。

创建表,参数tableName为表的名称,字符串数组 fields为存储记录各个域名称的数组。要求当HBase已经存在名为tableName的表的时候,先删除原有的表,再创建新的表。

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 16:25:01
 * @description TODO
 */
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

public class result_3_1 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";


    /**
     * 创建表
     *
     * @param tableName 表名
     * @param fields    字段数组
     */
    public static void createTable(String tableName, String[] fields) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();  // 创建HBase配置对象

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Admin admin = connection.getAdmin();  // 获取HBase管理员对象

            TableName table = TableName.valueOf(tableName);  // 定义表名

            if (admin.tableExists(table)) {  // 如果表已存在,则先删除原有表
                admin.disableTable(table);
                admin.deleteTable(table);
                System.out.println(RED_COLOR+"已删除同名表:" + tableName+RESET_COLOR);
            }

            HTableDescriptor tableDesc = new HTableDescriptor(table);  // 创建表描述符

            for (String field : fields) {  // 添加字段列族
                HColumnDescriptor columnDesc = new HColumnDescriptor(Bytes.toBytes(field));
                tableDesc.addFamily(columnDesc);
            }

            admin.createTable(tableDesc);  // 创建表
            System.out.println(RED_COLOR+"创建表成功:" + tableName+RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String tableName = "student";  // 小写的表名
        String[] fields = {"info", "score"};  // 字段数组
        createTable(tableName, fields);
    }
}

2addRecord(String tableName, String row, String[] fields, String[] values)。

向表tableName、行 row (用S_Name表示)和字符串数组fields指定的单元格中添加对应的数据 values。其中 fields中每个元素如果对应的列族下还有相应的列限定符的话,用"columnFamily:column”表示。例如,同时向“Math”,“Computer Science”,“English”3列添加成绩时,字符串数组fields为{“Score:Math”,"Score: Computer Science”, "Score:English"},数组 values存储这3门课的成绩。

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 16:31:58
 * @description TODO
 */

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 result_3_2 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    /**
     * 创建表
     *
     * @param tableName 表名
     * @param families  列族数组
     */
    public static void createTable(String tableName, String[] families) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Admin admin = connection.getAdmin();  // 获取Admin对象

            TableName table = TableName.valueOf(tableName);  // 表名转换为TableName对象

            if (admin.tableExists(table)) {  // 如果表已存在,则先删除表
                admin.disableTable(table);
                admin.deleteTable(table);
                System.out.println(" " + tableName + " 已存在,已删除旧表。");
            }

            HTableDescriptor tableDescriptor = new HTableDescriptor(table);  // 创建表描述对象

            for (String family : families) {  // 添加列族到表描述对象
                tableDescriptor.addFamily(new HColumnDescriptor(family));
            }

            admin.createTable(tableDescriptor);  // 创建表

            System.out.println(RED_COLOR + " " + tableName + " 创建成功!" + RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向表中添加数据
     *
     * @param tableName 表名
     * @param row       行键
     * @param fields    列族和列限定符数组
     * @param values    值数组
     */
    public static void addRecord(String tableName, String row, String[] fields, String[] values) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Table table = connection.getTable(TableName.valueOf(tableName));  // 获取表对象

            Put put = new Put(Bytes.toBytes(row));  // 创建一个Put对象,指定行键

            for (int i = 0; i < fields.length; i++) {
                String[] column = fields[i].split(":");  // 分割列族和列限定符
                put.addColumn(Bytes.toBytes(column[0]), Bytes.toBytes(column[1]), Bytes.toBytes(values[i]));  // Put对象中添加数据
            }

            table.put(put);  // 将数据插入到表中
            System.out.print(RED_COLOR + "向表 " + tableName + " 添加数据成功!" + RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String tableName = "Student_Score";  // 表名
        String[] families = {"info", "score"};  // 列族数组
        String row = "2015001";  // 行键
        String[] fields = {"info:S_Name", "score:Math", "score:Computer Science", "score:English"};  // 列族和列限定符数组
        String[] values = {"Zhangsan", "80", "75", "90"};  // 值数组

        createTable(tableName, families);  // 创建表
        addRecord(tableName, row, fields, values);
    }
}

3 scanColumn(String tableName, String column)。

浏览表tableName某一列的数据,如果某一行记录中该列数据不存在,则返回null。要求当参数column为某一列族名称时,如果底下有若干个列限定符,则要列出每个列限定符代表的列的数据;当参数column为某一列具体名称(如“Score:Math”)时,只需要列出该列的数据。

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 16:53:44
 * @description TODO
 */
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 result_3_3 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    /**
     * 浏览表中某一列的数据
     *
     * @param tableName 表名
     * @param column 列名(列族名称或具体列名称)
     */
    public static void scanColumn(String tableName, String column) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Table table = connection.getTable(TableName.valueOf(tableName));  // 获取表对象

            String[] columnParts = column.split(":");
            if (columnParts.length != 2) {
                throw new IllegalArgumentException("Invalid column format. Should be 'columnFamily:qualifier'.");
            }

            System.out.println("正在扫描表 " + tableName + " 中的列:" + column);

            Scan scan = new Scan();
            scan.addColumn(Bytes.toBytes(columnParts[0]), Bytes.toBytes(columnParts[1]));  // 设置要扫描的列

            ResultScanner scanner = table.getScanner(scan);  // 执行扫描操作

            boolean found = false;  // 判断是否找到了结果

            for (Result result : scanner) {
                if (!result.isEmpty()) {  // 判断结果是否为空
                    byte[] value = result.getValue(Bytes.toBytes(columnParts[0]), Bytes.toBytes(columnParts[1]));  // 获取列的值
                    System.out.println(RED_COLOR + "获取到的值为:" + Bytes.toString(value) + RESET_COLOR);
                    found = true;
                }
            }

            if (!found) {
                System.out.println(RED_COLOR + "该行记录中该列数据不存在" + RESET_COLOR);
            }

            scanner.close();  // 关闭ResultScanner
        } catch (TableNotFoundException e) {
            System.out.println(RED_COLOR + " " + tableName + " 不存在" + RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String tableName = "Student_Score";  // 表名
        String columnFamilyAndQualifier = "score:Math";  // 列族名称和具体列名称

        scanColumn(tableName, columnFamilyAndQualifier);
    }
}

4.modifyData(String tableName,String row,String column)。

修改表tableName,行row(可用学生姓名S_Name表示),列column指定的单元格的数据。

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 17:10:41
 * @description TODO
 */
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 result_3_4 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    /**
     * 修改表中指定行和列的单元格数据
     *
     * @param tableName 表名
     * @param row       行键
     * @param column    列名(列族名称:列限定符)
     * @param value     要修改的值
     */
    public static void modifyData(String tableName, String row, String column, String value) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Table table = connection.getTable(TableName.valueOf(tableName));  // 获取表对象

            Put put = new Put(Bytes.toBytes(row));  // 创建Put对象,并指定行键

            String[] columnParts = column.split(":");
            if (columnParts.length != 2) {
                throw new IllegalArgumentException("Invalid column format. Should be 'columnFamily:qualifier'.");
            }

            put.addColumn(Bytes.toBytes(columnParts[0]), Bytes.toBytes(columnParts[1]), Bytes.toBytes(value));  // 设置要修改的列和值

            table.put(put);  // 执行修改操作

            System.out.println(RED_COLOR+"成功修改表 " + tableName + " 中的行 " + row + " 的列 " + column + " 的值为:" + value+RESET_COLOR);
        } catch (TableNotFoundException e) {
            System.out.println(RED_COLOR + " " + tableName + " 不存在" + RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String tableName = "Student_Score";  // 表名
        String row = "张三";  // 行键,可用学生姓名表示
        String column = "score:math";  // 列名(列族名称:列限定符)
        String value = "90";  // 要修改的值

        modifyData(tableName, row, column, value);
    }
}

5.deleteRow(String tableName, String row)。

删除表tableName 中 row指定的行的记录。

package cn.itcast.Exp_3;

/**
 * @author lql
 * @time 2023-11-16 17:15:20
 * @description TODO
 */
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 result_3_5 {

    // ANSI转义序列,用于设置终端输出为红色
    public static final String RED_COLOR = "\u001B[31m";
    // ANSI转义序列,用于重置终端输出的颜色
    public static final String RESET_COLOR = "\u001B[0m";

    /**
     * 删除表中指定行的记录
     *
     * @param tableName 表名
     * @param row       行键
     */
    public static void deleteRow(String tableName, String row) {
        // 创建HBase配置对象
        Configuration config = HBaseConfiguration.create();

        config.set("hbase.zookeeper.quorum", "node1"); // 设置ZooKeeper的主机名或IP地址

        try (Connection connection = ConnectionFactory.createConnection(config)) {
            Table table = connection.getTable(TableName.valueOf(tableName));  // 获取表对象

            Delete delete = new Delete(Bytes.toBytes(row));  // 创建Delete对象,并指定行键

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

            System.out.println(RED_COLOR+"成功删除表 " + tableName + " 中的行 " + row + " 的记录"+RESET_COLOR);
        } catch (TableNotFoundException e) {
            System.out.println(RED_COLOR + " " + tableName + " 不存在" + RESET_COLOR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String tableName = "Student_Score";  // 表名
        String row = "张三";  // 要删除的行键

        deleteRow(tableName, row);
    }
}

实验总结

(一)发现问题与解决问题

1.至少需要指定一个列簇

Caused by: org.apache.hadoop.hbase.ipc.RemoteWithExtrasException(org.apache.hadoop.hbase.DoNotRetryIOException): org.apache.hadoop.hbase.DoNotRetryIOException: Table should have at least one column family. Set hbase.table.sanity.checks to false at conf or table descriptor if you want to bypass sanity checks

原因分析根据报错信息进行查询资料发现,在创建表的时候需要指定列簇,并且一旦指定就无法轻易删除,只能通过修改名字来进行更改!这个异常的意思是表至少应该有一个列族。HBase要求表在创建时必须至少包含一个列族,否则会触发这个异常。

在HBase中,数据是按照行键(rowkey)、列族(column family)、列限定符(qualifier)和时间戳(timestamp)来组织的。列族是表的一个重要组成部分,每个表都必须至少有一个列族。如果在创建表的时候没有指定列族,就会出现这个异常。

解决方法:所以在创建表的时候,一定要为表指定至少一个列族。可以通过HBase shell或者Java API来创建表,并在创建表的时候指定列族。

2.zookeeper需要伪分布式安装

2023-11-13 09:57:58,097 INFO  [main-SendThread(node1.itcast.cn:2182)] zookeeper.ClientCnxn: Opening socket connection to server node1.itcast.cn/192.168.88.100:2182. Will not attempt to authenticate using SASL (unknown error)

2023-11-13 09:57:58,098 WARN  [main-SendThread(node1.itcast.cn:2182)] zookeeper.ClientCnxn: Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect

java.net.ConnectException: Connection refused

        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)

        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)

org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:361)

        at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)

原因分析根据报错信息可知,根据提供的错误日志,可以看出出现了连接拒绝的错误(Connection refused)。这通常表示在与服务器建立连接时遇到了问题。

可能的原因和解决方法如下:

服务器未启动或未正确配置。请确保Zookeeper服务器已启动并正常运行,并且可以通过指定的主机名和端口号进行访问。

防火墙或网络配置问题。防火墙设置可能会阻止与指定主机和端口的连接。请检查防火墙配置并确保允许与Zookeeper服务器的通信。

网络连接问题。连接拒绝错误可能是由于网络连接问题引起的。请确保网络连接正常,并且没有任何故障或中断。

端口号错误。请确保正在使用正确的端口号连接到Zookeeper服务器。默认情况下,Zookeeper使用2181端口。

解决方法:所以在搭建zookeeper的时候采取伪分布式安装,即可实现一个node节点可以有三个zookeeper服务,进而在连接hbase时可以正常使用。

3.hregionserver服务启动失败

2023-11-13 09:30:45,378 WARN  [main] regionserver.HRegionServerCommandLine: Not starting a distinct region server because hbase.cluster.distributed is false

原因分析根据提供的警告日志,可以看到"HRegionServerCommandLine"指示不会启动独立的区域服务器。

解决方法:所以在hbase-site.xml中设置集群模式为true。

4.端口占用报错

Could not start ZK at requested port of 2181.  ZK was started at port: 2182.  Aborting as clients (e.g. shell) will not be able to find this ZK quorum.

原因分析根这个问题的原因是在尝试启动Zookeeper时,发现使用的默认端口2181已经被占用,所以Zookeeper启动在了备选的端口2182上。然而,由于客户端(例如shell)通常会默认连接到2181端口,所以Zookeeper启动在备选端口上可能导致客户端无法正确连接到Zookeeper集群。

解决方法:

[root@node1 hbase-2.1.0]#  netstat -tlnp | grep 2181

tcp6    0    0 :::2181        :::*           LISTEN      4390/java           

[root@node1 hbase-2.1.0]# kill -9 4390

[root@node1 hbase-2.1.0]#  netstat -tlnp | grep 2181

hbase-site.xml

<property>

    <name>hbase.zookeeper.property.clientPort</name>

    <value>2182</value>

  </property>

(二)实验心得与思考体会

在进行Java操作HBase的实验过程中,我获得了一些实验心得和思考体会。下面是我总结的几点:

  1. HBase的数据模型:

HBase是一个基于列族的分布式数据库,它的数据模型与传统的关系型数据库有所不同。在实验中,我学会了如何创建表、定义列族,并根据需要插入、查询和删除数据。这让我更好地理解了HBase的数据组织方式和操作方法。

  1. 使用Java API操作HBase:

通过Java API,我可以在Java程序中对HBase进行增删查改操作。我学会了如何使用HBase的Java API连接到HBase集群、创建和删除表,以及对表中的数据进行CRUD操作。这为我开发基于HBase的应用程序提供了基础。

  1. 批量操作和过滤器:

在实验中,我还学习了如何使用批量操作和过滤器来提高HBase的性能。通过批量操作,我可以一次性插入或删除多行数据,减少网络开销和通信次数。而过滤器则可以帮助我在查询时快速定位到所需数据,避免不必要的数据传输和处理。

  1. 异常处理和错误调试:

在实验过程中,我遇到了一些异常情况和错误,例如连接超时、表不存在等。通过仔细阅读异常信息和调试代码,我学会了如何正确处理这些异常,并找出问题所在。这对于开发稳定和可靠的HBase应用程序至关重要。

总的来说,通过这次实验,我不仅对HBase有了更深入的理解,还提升了自己的Java编程能力和错误调试能力。我意识到在使用分布式数据库时,需要考虑到数据模型、性能优化和异常处理等方面的问题。这对于我今后的工作和学习都具有重要的指导意义。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡林神不是猫

如果您觉得有帮助可以鼓励小卡哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值