HIVE3 深度剖析 (上篇)

# HIVE3 深度剖析 (上篇)

大家好,我是明哥!

HIVE3 相对于HIVE2,差异还是很大的,为方便大家了解这些差异点以更有效地使用HIVE,接下来我会通过几篇文章,重点剖析下这些差异点。

整个系列分为上下两篇文章,涵盖以下章节:

1. 从 HIVE 架构的演进看 HIVE 的发展趋势

2. 盘点下 HIVE3.X 和 HIVE2.X 的那些重大差异点

3. HIVE3.X 的 ORC 事务表详解

4. HIVE3.X 的 LEGACY 传统模式详解

5. 周边生态如 SPARK/DATAX 如何对接HIVE 3x

6. 大数据应用对接 HIVE3.x 的几点建议

本片文章是上篇,包含前三个章节,希望大家喜欢。

## 1. 从 HIVE 架构的演进看 HIVE 的发展趋势

***早期的 HIVE,按照 METASTORE SERVICE/DB 所处的位置,经常会提到三种模式:内嵌模式,本地模式,远程模式:***

- 内嵌模式:客户端和服务端还有底层存储元数据的数据库是同一个进程(使用的是derby这种jvm嵌入式数据库),是一体的(即不区分客户端和服务端);

- 本地模式:在内嵌模式的基础上,把存储元数据的数据库拆分了出来,但客户端和服务端还是同一个进程,是一体的(即不区分客户端和服务端);

- 远程模式:在本地模式的基础上,把元数据服务 hms 也拆分出来作为一个单独的进程,有了真正意义上的客户端和服务端,从 HIVE1.X 开始,所有生产环境推荐使用的都是 remote metastore 模式;

![](https://files.mdnice.com/user/17092/70e74f83-54d6-4c44-890b-f34bbf948c5f.png)

![](https://files.mdnice.com/user/17092/86fad24c-1c6e-4faa-b888-648c58b76f2d.png)

***我们重点看下从 HIVE1.X 开始,生产环境使用的 远程模式:***

- 远程模式,在服务端,包括一个或多个查询引擎 HiveServer2 和一个元数据引擎 HMS (Hive Metastore Service);

- 远程模式,从客户端使用方式来看,在 hive1.x 和 hive2.x 中又可以进一步分为两种方式:hive cli 的胖客户端模式,和 beeline 的瘦客户端模式;

- Hive cli 的胖客户端模式,客户端承载了 hiveserver2 的查询引擎角色,只需要访问服务端的元数据服务 hms 即可;

- Beeline 的瘦客户端模式,客户端需要访问服务端的 hiveserver2 ,并通过 hiveserver2 访问底层的 hms;

- 从 hive3.x 开始,hive 不再支持 cli 胖客户端模式, 仅仅支持 beeline 瘦客户端模式;

- 目前HIVE远程模式,完整的架构图如下:

![](https://files.mdnice.com/user/17092/1f409579-614a-437f-9c5c-6a7643d45d82.png)

***从上述HIVE 架构的演进,可以看到 HIVE 如下发展趋势:***

- HIVE 将客户端与服务端分离,并在服务端进一步按照功能拆分出 hiveserver2 和 hms 两个服务,就可以应对多个客户端的并发访问,也能够适配大数据生态的其它计算引擎,如 spark/impala/presto/flink;

- 为了提高数据质量,也为了提高数据查询和分析的效率 Hive 社区还孵化出了列式存储 orc ,目前 Orc 已经是 apache 顶级项目;

- HIVE 进一步补强优化了 hiveserver2 服务端,通过 ORC 事务表提供了对增删改查的完善的 ACID 语义的支持,也通过 LLAP 加强了互动查询的效率,还通过 streaming 增强了实时流处理能力;

- 综上所述, HIVE 已经从早期一个简单的存储引擎之上的 SQL 解析层(单纯的 JAR 而没有服务),逐渐迭代优化,补齐功能短板,越来越像传统的关系型数据库,成为一个完善的数据仓库解决方案了!

- 注意 1: HIVE 是针对数据仓库的 OLAP 场景,不是针对事务交易的 OLTP 场景,不能当做 OLTP 数据库来 使 用!

- 注意 2:虽然 HIVE 做了大量性能方面的优化,但由于它是存算分离的架构,在执行时也需要向 YARN 等资源管理器动态申请资源,所以其查询性能一般比 OLAP 数据库还是要差些的,比如 GP/DORIS/CK 等。

***Cloudera 官方建议,为最有效地使用HIVE3,需要注意一下几点:***

![](https://files.mdnice.com/user/17092/63842e72-43f2-4878-9e97-1a295b8a7811.png)

## 2. 盘点下 HIVE3.X 和 HIVE2.X 的那些重大差异点

***HIVE3.X不再支持以下特性:***

- Hive cli: HIVE3.X 不再支持 胖客户端 Hive CLI, 仅支持瘦客户端 beeline;

- Hive on mr: HIVE3.X 底层执行引擎不再支持 hive on mr , CDP 中也不再支持 hive on spark 仅支持 hiveon tez (Hive on Tez 提供更好的 ETL 性能);

- Hive index: 通过 HIVE 18448 在 hive 3.x 中彻底移除了对 Index 的支持;(orc/parquet 列式文件存储格式本身提供了对 index 和 bloom filter 的支持, 相关参数 hive.optimize.index.filter 默认为 true; hive2.3.0 也增加了对物化视图 materialzed views 的 automatic rewriting 的支持,这些功能很好地替代了Index);

***在 DDL 执行效果上,HIVE3.X和HIVE2.X有以下差异:***

- HIVE3.X CREATE TABLE,不指定格式时,默认 为 ORC 格式,之前版本默认为 text 格式;

- HIVE3.X CREATE TABLE,不指定是否为事务表时,默认为 ORC 事务内表,之前版本默认为 ORC 非事务内表;

- Hive3.x 的 ORC 事务内表,支持高效 的 insert/update/delete/merge, 且不再需要进行分桶;

- Hive3.x 的 ORC 事务内 表,分为 full acid 事务内表,和 Insert only 事务内

表: TBLPROPERTIES(‘transactional’=‘true',transactional_properties='insert_only’或'default');

- HIVE3.X 增加了新的语法 CREATE MANAGED TABLE xyz(col1 type,...) type,...),来显示创建 managed table;

- HIVE3.X 中,external 外表有两种类型:external purge table 和 external non purge table: TBLPROPERTIES ('EXTERNAL'='TRUE',external.table.purge’=’TRUE;

- Hive3.x 中,内表和外表的默认存储路径,分别由参数 hive.metastore.warehouse.dir 和hive.metastore.warehouse.external.dir 控制,在 cdp 中默认值分别为 /warehouse/ tablespace/managed/hive 和 /warehouse/ tablespace/external/hive;

- HIVE3.X 中,内表和外表的存储路径,分别可以在 DATABASE” 级别和 “TABLE” 级别通过 location 参数来修改;

- HIVE3.X CREATE TABLE 创建 managed table 时,推荐不在 TABLE 级别指定 location ,此时会使用 hive.metastore.warehouse.dir 指定的默认值或 DATABASE 级别覆盖的值;(如果指定路径,路劲的值必须是 managed

warehouse root dir 或 database 的 managedLocationUrI 之下的路径);

- HIVE3.X CREATE TABLE 创建 external table 时, 也推荐不指定 location,此时会使用参数 hive.metastore.warehouse.external.dir 指定的默认值 (也可以在 TABLE 级别来指定);

- HIVE3.X Drop external table 时,会不会删除表底层实际的数据,取决于参数 external.table.purge;

- HIVE3.X truncate table,只能对内部 表,或‘external.table.purge’=’TRUE' 的外部表,才能被 truncate ;(否则会报错);

![](https://files.mdnice.com/user/17092/1481b695-c4a6-4d81-a578-f87e2a3199d9.png)

***HIVE3.X相比HIVE2.X,重大参数变化如下:***

- hive.default.fileformat.managed:升级前None,升级后ORC;

- hive.metastore.disallow.incompatible.col.type.changes:控制是否允许更改不兼容的列类型,比如将 STRING 列更改为 INT 列;升级前FALSE,升级后TRUE;

- hive.metastore.warehouse.dir:升级前 /user/hive/warehouse,升级后/tablespace /managed/hive;

- hive.server2.enable.doAs:升级前TRUE (in case of unsecure cluster only),升级后FALSE;

- hive.txn.manager:升级前org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager ,升级后 org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;

- hive.execution.engine:升级前mr,升级后tez;

- hive.cbo.enable: 升级前 FALSE,升级后 TRUE;

- hive.auto.convert.sortmerge.join/hive.auto.convert.sortmerge.join.reduce.side: 升级前: FALSE in the old CDH,TRUE in the old HDP; 升级后TRUE;

- hive.auto.convert.sortmerge.join.to.mapjoin: 升级前FALSE,升级后TRUE;

- hive.exec.dynamic.partition.mode:升级前strict,升级后nonstrict;

- hive.exec.max.dynamic.partitions:升级前1000,升级后5000;

- hive.exec.max.dynamic.partitions.pernode:升级前100,升级后2000;

## 3. HIVE3.X 的 ORC 事务表详解

***如上文所说,HIVE的一个最主要的发展趋势,就是已经从早期一个简单的存储引擎之上的SQL解析层(单纯的JAR而没有服务),逐渐迭代优化,补齐功能短板,越来越像传统的关系型数据库,成为一个完善的数据仓库解决方案了!这其中最显眼的功能点,就是 HIVE 推出的 ORC ACID 事务表,通过该特性,HIVE可以向其它流行的数据湖框架 deltaLake/hudi/iceberg 一样,通过 ACID 事务特性,提供对并发读写的支持,提供记录级别的增删改查。***

- 在默认情况 下 HIVE3.X CREATE TABLE 语句会在 Hive Metastore 中创建一个 ORC 格式的 Full ACID v2 事务内表;

- Hive 严格控制对 ORC 事务表的访问,并定期在后台对表执行压缩 compaction 操作 当然, Spark 和其他客户端访问 Hive ORC 事务表的方式也相应地需要作出变化);

- 与 Non ACID 表相比, Hive Full ACID v2 (事务内表)提供了更好的批量性能、安全保障和用户体验

- Full ACID v2 Hive 表有以下四个特点:

  - 支持 Insert/Update/Delete/Merge 操作;

  - ETL 性能与 Non ACID 表一样好;

  - 无需进行分桶操作;

  - 与 S3 等云端对象存储完全兼容;

- 与 Non ACID 表相比, Hive Full ACID v2(事务内表 )提供了 row 级别的 ACID 语义,而不再仅仅是 table或 partition 级别的 ACID ,并基于此支持了以下场景:

  - 提供了多任务并发读写同一个表或同一个分区的能力: one application can add rows while another reads from the same partition without interfering with each other;

  - 提供了对 Streaming ingest of data 的支持:不再引起 dirty read 和 小 文件问题;(可以更好地对接 flink/kafka/flume)

  - 提供了对数仓的 SCD Slowly changing dimensions 的支持:HIVE ACID 通过提供记录级别的 inserts/delete,可以完善地支持数仓星型模型的缓慢渐变维度;

  - 提供了记录级别的数据修复 data restatement 功能:HIVE ACID 通过提供记录级别的Insert/Update/Delete,支持了数据修复和删除功能;

  - 提供了批量更新功能:通过 Merge 提供了批量更新功能;


***HIVE 官方文档对 ORC ACID 事务内表的实现机制,有详细的描述,建议大家翻阅下,部分要点概括如下:***

- HDFS 文件不支持原地更新,在APPEND追加写入文件时也不支持对该文件并发读取时的数据一致性;

- 为了在 HDFS 文件系统的以上特性基础上提供 ACID 语义,HIVE 对 ACID 事务表(或表分区)底层的 HDFS 目录,做了类似 deltalake/hudi/iceberg 一样的精细化管理,在该目录底层又创建了两个子目录,一个是 base 子目录,一个是 delta 子目录:

![](https://files.mdnice.com/user/17092/11f449f2-9dd2-43d5-83a7-334347ccb3a6.png)

- 表或表分区的大部分数据,都以文件形式存储在 base 子目录下;

- 每次对表或表分区的增删改操作,都对应一个事务,都会创建一个对应的 delta 子目录,并将这些增量操作产生的数据,以文件形式存储在该 delta 子目录下;

- 读取表或分区数据时,会合并 base 子目录和 delta子目录下的所有文件,以呈现完整的数据;

- 在后台 hms 中有一系列 compactor 线程,会合并/压缩 base 和 delta子目录下的众多文件,以优化读取性能;

- compactor 在后台的执行,不会影响前台用户对表或分区的并发读取操作;

- compactor 分为 major 和 minor 两种类型,类似 hbase 的 compactor;

![](https://files.mdnice.com/user/17092/184e3cca-29b7-4125-8a8a-d5c85dddf487.png)

***事务表主要参数如下:***

- ORC事务表客户端相关参数:

  - hive.support.concurrency:true

  - hive.enforce.bucketing: true (Not required as of Hive 2.0

  - hive.exec.dynamic.partition.mode: nonstrict

  - hive.txn.manager:org.apache.hadoop.hive.ql.lockmgr.DbTxnManager

- ORC事务表服务端相关参数(hms):

  - hive.compactor.initiator.on:true

  - hive.compactor.worker.threads: a positive number on at least one instance of the Thrift metastore service

***HIVE3对事务表新增了一些命令,主要有以下这些:***

- 提供了对以下 DML 命令的支持: INSERT…VALUES, UPDATE,DELETE,merge into;

- 可以通过以下命令查看压缩任务,事务,锁等:SHOW TRANSACTIONS/COMPACTIONS/LOCKS;

- 可以通过以下命令手动触发对表的压缩:Alter table xxx compact ‘minor/ major’and wait (自动压缩之外的补充)

- MERGE INTO 是一个很方便的命令,其语法如下:

~~~java

MERGE INTO AS T USING AS S

ON < boolean expression1>

WHEN MATCHED [AND < boolean expression2>] THEN UPDATE SET

WHEN MATCHED [AND < boolean expression3>] THEN DELETE

WHEN NOT MATCHED [AND < boolean expression4>] THEN INSERT VALUES

~~~

你可能感兴趣的:(HIVE3 深度剖析 (上篇))