hbase2.1.x集群:Hive整合HBase

介绍

Hive 整合 HBase 的核心是通过 Hive 外部表映射 HBase 表,实现用 SQL 操作 HBase 中的 NoSQL 数据(无需数据迁移),既保留 HBase 的高并发读写特性,又利用 Hive 的 SQL 分析能力。

注意

  1. 数据类型:HBase 所有数据均以字节数组存储,Hive 表建议全部定义为 STRING 类型,避免类型转换错误;
  2. 表类型:必须创建 Hive 外部表(EXTERNAL),否则删除 Hive 表会同步删除 HBase 表;
  3. 读写权限:Hive 运行用户需有 HBase 表的读写权限(HBase 权限:grant 'hive', 'RW', 'student');
  4. 事务支持:Hive 整合 HBase 不支持事务,避免并发写入导致数据冲突;
  5. 适用场景:适合「HBase 存储明细数据 + Hive 做批量分析」,不适合高并发实时查询(直接用 HBase API 更优)。

整合原理

Hive 与 HBase 的整合依赖 HBaseStorageHandler 组件,本质是:

  1. 元数据映射:Hive 外部表的字段与 HBase 表的「列族:列名」一一绑定;
  2. 数据路由:Hive 执行 SQL 时,通过 StorageHandler 调用 HBase Java API 读写 HBase 数据;
  3. 无数据拷贝:Hive 表仅存储元数据,实际数据仍在 HBase 中,两者实时同步。

整合方式一(推荐)

修改 hive-site.xml 文件

vim /program/hive-3.1.2/conf/hive-site.xml

在末尾增加下面配置:

<!-- 集成HBase:开始 -->
<!-- 指定zookeeper,因为HBase需要zookeeper -->
<property>
    <name>hive.zookeeper.quorum</name>
    <value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
<!-- 添加 HBase jar包 -->
<property>
    <name>hive.aux.jars.path</name>
    <value>
        file:///program/hbase-2.1.9/lib/hbase-common-2.1.9.jar
        file:///program/hbase-2.1.9/lib/hbase-client-2.1.9.jar
        file:///program/hbase-2.1.9/lib/hbase-server-2.1.9.jar
        file:///program/hbase-2.1.9/lib/hbase-hadoop2-compat-2.1.9.jar
        file:///program/hbase-2.1.9/lib/netty-all-4.0.23.Final.jar
        file:///program/hbase-2.1.9/lib/hbase-protocol-2.1.9.jar
        file:///program/hbase-2.1.9/lib/zookeeper-3.4.10.jar
    </value>
</property>
<!-- 集成HBase:结束 -->

整合方式二

将 HBase 的核心配置文件拷贝到 Hive 的 conf 目录(所有 Hive 节点):

# 拷贝HBase配置到Hive
cp $HBASE_HOME/conf/hbase-site.xml $HIVE_HOME/conf/

关键配置 hbase-site.xml:

<property>
    <name>hbase.zookeeper.quorum</name>
    <value>hadoop1,hadoop2,hadoop3</value> <!-- ZK集群地址 -->
</property>
<property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value> <!-- ZK端口 -->
</property>

依赖包

Hive 的 lib 目录需包含 HBase 相关依赖包(若缺失,从 HBase 的 lib 拷贝):

将下面 jar 包拷贝到 Hive 的 lib 目录:

/program/hbase-2.1.9/lib/hbase-common-2.1.9.jar
/program/hbase-2.1.9/lib/hbase-client-2.1.9.jar
/program/hbase-2.1.9/lib/hbase-server-2.1.9.jar
/program/hbase-2.1.9/lib/hbase-hadoop2-compat-2.1.9.jar
/program/hbase-2.1.9/lib/netty-all-4.0.23.Final.jar
/program/hbase-2.1.9/lib/hbase-protocol-2.1.9.jar
/program/hbase-2.1.9/lib/zookeeper-3.4.10.jar

建表方式一:Hive 创建外部表

必须先在 HBase 中创建表,然后在 Hive 中创建外部表,并映射 HBase 表

HBase 创建表(先有 HBase 表)

进入HBase Shell:

hbase shell

创建HBase表:表名 student,列族 info(可多列族)

create 'student', 'info'

插入测试数据(行键1001,列族info,列name/age/sex)


put 'student', '1001', 'info:name', '张三'
put 'student', '1001', 'info:age', '20'
put 'student', '1001', 'info:sex', '男'
put 'student', '1002', 'info:name', '李四'
put 'student', '1002', 'info:age', '21'
put 'student', '1002', 'info:sex', '女'

查看数据:

scan 'student'

Hive 创建表

CREATE EXTERNAL TABLE student_hive_hbase (
    rowkey STRING,  -- 必须映射HBase的行键(名称可自定义,需和下方rowkey对应)
    name STRING,    -- 映射info:name
    age STRING,     -- 映射info:age
    sex STRING      -- 映射info:sex
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'  -- 核心Handler
WITH SERDEPROPERTIES (
    'hbase.columns.mapping' = ':key,info:name,info:age,info:sex'  -- 映射规则
)
TBLPROPERTIES (
    'hbase.table.name' = 'student_hive_hbase'  -- 关联的HBase表名
);

映射规则说明(hbase.columns.mapping)

Hive 字段 HBase 映射规则 说明
rowkey :key 固定写法,映射HBase行键
name info:name 映射列族info的列name
age info:age 映射列族info的列age

建表方式二: hive创建管理表(内部表)

通过 hive创建管理表(内部表),会自动在 hbase 创建表

注意:由于是管理表(内部表),通过 hive 删除表时,也同时删除 hbase 中的表,生产环境中较少使用

CREATE EXTERNAL TABLE student_hive_hbase (
    rowkey STRING,  -- 必须映射HBase的行键(名称可自定义,需和下方rowkey对应)
    name STRING,    -- 映射info:name
    age STRING,     -- 映射info:age
    sex STRING      -- 映射info:sex
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'  -- 核心Handler
WITH SERDEPROPERTIES (
    'hbase.columns.mapping' = ':key,info:name,info:age,info:sex'  -- 映射规则
)
TBLPROPERTIES (
    'hbase.table.name' = 'student_hive_hbase'  -- 关联的HBase表名
);

映射规则说明(hbase.columns.mapping)

Hive 字段 HBase 映射规则 说明
rowkey :key 固定写法,映射HBase行键
name info:name 映射列族info的列name
age info:age 映射列族info的列age

插入数据

INSERT INTO student_hive_hbase VALUES ('1001', '张三', '20', '男');
INSERT INTO student_hive_hbase VALUES ('1002', '李四', '21', '女');

执行 mapreduce 插入数据

hive查询数据

select * from student_hive_hbase;

执行结果:

1001    张三    20      男
1002    李四    21      女

hbase查询数据

启动 hbase shell,执行下面命令:

scan 'student_hive_hbase',{FORMATTER => 'toString'}

执行结果:

 1001                                    column=info:age, timestamp=1765073576636, value=20                                                                 
 1001                                    column=info:name, timestamp=1765073576636, value=张三                                                                
 1001                                    column=info:sex, timestamp=1765073576636, value=男                                                                  
 1002                                    column=info:age, timestamp=1765073593222, value=21                                                                 
 1002                                    column=info:name, timestamp=1765073593222, value=李四                                                                
 1002                                    column=info:sex, timestamp=1765073593222, value=女

hive删除表

由于是管理表(内部表),通过 hive 删除表时,也同时删除 hbase 中的表,生产环境中较少使用

drop table student_hive_hbase;

查看 HBase 中的 student_hive_hbase 表:

scan 'student_hive_hbase'

查询报错,提示表不存在,如下:

Hive SQL 操作 HBase 数据

查询数据(最常用)

-- 查所有数据
SELECT * FROM student_hive_hbase;

-- 条件查询(行键/字段过滤)
SELECT rowkey, name, age FROM student_hive_hbase WHERE rowkey = '1001';
SELECT rowkey, name FROM student_hbase WHERE age > '20';

预期结果:

rowkey name age sex
1001 张三 20 男
1002 李四 21 女

插入数据(Hive → HBase)

-- 插入单行
INSERT INTO student_hive_hbase VALUES ('1003', '王五', '22', '男');

-- 批量插入(从其他Hive表导入)
INSERT INTO student_hive_hbase 
SELECT '1004', name, age, sex FROM other_table WHERE id = 1004;

插入后在 HBase 验证:scan 'student' 可看到 1003/1004 行数据。

更新数据(通过覆盖插入)

Hive 无直接 UPDATE 语法,需通过 INSERT OVERWRITE 或单行插入覆盖:

-- 覆盖更新1001行的age
INSERT INTO student_hive_hbase VALUES ('1001', '张三', '23', '男');

删除数据

Hive 无直接 DELETE 语法,需通过 HBase Shell 或 HBase API 删除:

# HBase Shell删除行键1004
deleteall 'student', '1004'

验证数据一致性

-- Hive中查询
SELECT * FROM student_hive_hbase WHERE rowkey = '1003';

-- HBase中查询
hbase(main):001:0> get 'student', '1003'

两者结果需完全一致,说明映射正常。

进阶用法

映射多列族 HBase 表

若 HBase 表有多个列族(如 info、score),Hive 表映射如下:

CREATE EXTERNAL TABLE student_hbase_multi (
    rowkey STRING,
    name STRING,  -- info:name
    age STRING,   -- info:age
    math INT,     -- score:math
    english INT   -- score:english
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
    'hbase.columns.mapping' = ':key,info:name,info:age,score:math,score:english'
)
TBLPROPERTIES ('hbase.table.name' = 'student');

分区表映射(优化查询)

对大数据量 HBase 表,可在 Hive 中创建分区表:

CREATE EXTERNAL TABLE student_hbase_part (
    rowkey STRING,
    name STRING,
    age STRING
)
PARTITIONED BY (dt STRING)  -- 按日期分区
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
    'hbase.columns.mapping' = ':key,info:name,info:age'
)
TBLPROPERTIES ('hbase.table.name' = 'student');

-- 添加分区(分区仅作用于Hive,不影响HBase)
ALTER TABLE student_hbase_part ADD PARTITION (dt='20250101');

自定义序列化/反序列化

若 HBase 数据是二进制/自定义格式,可指定 SERDE:

WITH SERDEPROPERTIES (
    'hbase.columns.mapping' = ':key,info:name',
    'serialization.format' = '1',  -- 序列化格式
    'hbase.serde.class' = 'org.apache.hadoop.hive.hbase.HBaseSerDe'  -- 自定义SerDe
)

常见问题

1. 报错:Cannot connect to ZooKeeper

  • 原因:Hive 未读取到 HBase 的 ZK 配置;
  • 解决方案:确认 hbase-site.xml 已拷贝到 Hive conf,且 ZK 地址正确,ZK 集群正常运行。

2. 报错:Unknown column family info

  • 原因:Hive 映射的列族/列名与 HBase 表不一致;
  • 解决方案:执行 list/describe 'student' 确认 HBase 表的列族名称。

3. Hive 查询数据为空,但 HBase 有数据

  • 原因1:行键/列名大小写不一致(HBase 大小写敏感,Hive 不敏感);
  • 原因2:Hive 表字段类型与 HBase 数据类型不兼容(如 HBase 是字符串,Hive 定义为 int);
  • 解决方案:统一大小写,字段类型全部先设为 STRING(HBase 数据默认是字符串)。

4. 插入数据后 HBase 无数据

  • 原因:Hive 插入操作触发 MapReduce 任务,需等待任务完成;
  • 解决方案:执行 yarn application -list 查看任务状态,或直接用 INSERT OVERWRITE 替代 INSERT INTO。

5. 性能问题:Hive 查询 HBase 慢

  • 优化1:限定行键范围(HBase 行键是有序的,避免全表扫描);
  • 优化2:禁用 Hive 并行执行:set hive.exec.parallel=false;
  • 优化3:调整 HBase 扫描缓存:set hbase.client.scanner.caching=1000。

总结

Hive 整合 HBase 的核心是通过外部表+StorageHandler 实现元数据映射,关键步骤:

  1. 同步配置文件和依赖包;
  2. HBase 创建表并插入数据;
  3. Hive 创建外部表绑定 HBase 表;
  4. 用 Hive SQL 分析 HBase 数据。

参考:
https://blog.csdn.net/Yian123456/article/details/143986749


原文出处:/show_1GW2MVVdydxh.html