是的,Hive 支持事务,但有严格的限制和特定的使用场景。
它不是像 MySQL 或 Oracle 那样传统的 OLTP(联机事务处理)数据库,它的事务功能是为数据仓库的 OLAP(联机分析处理)场景设计的,主要用于解决批量数据插入、更新和删除的需求。
一、Hive 事务的关键特性与限制
-
有限的表类型:
- 事务功能仅支持内部表(Managed Table),不支持外部表(External Table)。
- 表必须是分桶表(Bucketed Table)。分桶是 Hive 实现事务 ACID 特性的基础。
-
ACID 语义支持:
- 原子性(Atomicity):一个事务内的所有操作,要么全部完成,要么全部不完成。例如,一个更新多行的事务如果中途失败,所有更改都会回滚。
- 一致性(Consistency):事务必须使数据从一个一致的状态转变为另一个一致的状态。
- 隔离性(Isolation):Hive 目前主要支持 快照隔离(Snapshot Isolation)。这意味着一个事务看到的数据版本,是事务开始时的数据快照。它不会看到其他并发事务正在修改的中间状态。这避免了脏读、不可重复读和幻读。
- 持久性(Durability):一旦事务提交,其所作的更改就会永久保存。
-
主要使用场景:
- 流式数据摄取:例如,每分钟将一批数据从 Kafka 插入到 Hive 表,并避免出现部分数据可见的情况。
- 数据更新与删除(缓慢变化维 SCD):这是最重要的用途。例如,修正历史错误数据、根据 GDPR 等法规要求删除用户数据、更新维度表中等。
- 事务性数据合并:将多个数据源的数据合并到一个表中,并保证一致性。
二、如何使用 Hive 事务?
1. 配置 Hive 以启用事务
首先,必须在 Hive 会话或 hive-site.xml 配置文件中设置以下参数:
-- 必须的配置
SET hive.support.concurrency = true; -- 启用并发
SET hive.enforce.bucketing = true; -- 强制分桶(通常建议)
SET hive.exec.dynamic.partition.mode = nonstrict; -- 建议设置为非严格模式
SET hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; -- 使用 DbTxnManager
-- 可选配置,用于自动压缩
SET hive.compactor.initiator.on = true; -- 启用自动启动压缩线程
SET hive.compactor.worker.threads = 1; -- 压缩工作的线程数
2. 创建事务表
创建表时,必须使用 CLUSTERED BY 分桶,并且添加 STORED AS ORC 和 TBLPROPERTIES 来声明这是一个事务表。
CREATE TABLE employee_transactional (
id INT,
name STRING,
salary FLOAT,
department STRING
)
CLUSTERED BY (id) INTO 2 BUCKETS -- 必须分桶,通常选择高基数列
STORED AS ORC -- 必须使用 ORC 格式(目前只支持 ORC)
TBLPROPERTIES (
'transactional' = 'true' -- 必须设置为 true 以启用事务
-- ‘orc.compress’='SNAPPY’ -- 可以像普通ORC表一样指定压缩
);
3. 执行 DML 操作
一旦表创建成功,你就可以使用标准的 DML 语句进行操作。
-
INSERT:
INSERT INTO TABLE employee_transactional VALUES (1, 'Alice', 5000, 'IT'); -
UPDATE:
UPDATE employee_transactional SET salary = 6000 WHERE id = 1; -
DELETE:
DELETE FROM employee_transactional WHERE id = 1; -
MERGE (功能最强大,类似 UPSERT):
MERGE INTO employee_transactional AS target USING source_table AS source ON target.id = source.id WHEN MATCHED AND source.op = 'update' THEN UPDATE SET ... WHEN MATCHED AND source.op = 'delete' THEN DELETE WHEN NOT MATCHED THEN INSERT VALUES ...;
请注意:这些 DML 操作在 Hive 中执行成本很高,因为它们会创建新的文件(delta 文件)而不是原地修改,主要用于批量操作,而不是高频率的单行操作。
三、底层原理:如何实现的?
Hive 事务的实现非常精巧,理解了它就能明白为什么有那些限制:
-
写时复制(Copy-on-Write)与
delta文件:- 当你执行
INSERT、UPDATE、DELETE时,Hive 不会直接修改原有的基础数据文件。 - 对于
INSERT,它会将新数据写入新的文件。 - 对于
UPDATE和DELETE,它会先找到需要修改/删除的行所在的基础文件(base文件),然后将未修改的行和新的行值一起写入一个新的delta文件,并标记旧行的删除。这避免了昂贵的原地更新,但会产生很多小文件。
- 当你执行
-
自动压缩(Compaction):
- 由于上述机制运行一段时间后会产生大量小
delta文件,这会严重降低读取性能。 - Hive 的压缩器(Compactor) 是一个后台进程,它会定期(或手动触发)将多个
delta文件和base文件合并成新的、更大的base文件,从而优化存储结构和读取效率。 - 压缩分为两种:
- Minor Compaction:将多个小
delta文件合并成一个更大的delta文件。 - Major Compaction:将一个或多个
delta文件与base文件合并,生成全新的base文件。这相当于完全重写数据,是最彻底的优化。
- Minor Compaction:将多个小
- 由于上述机制运行一段时间后会产生大量小
-
事务管理器与锁:
DbTxnManager会管理事务的并发和隔离,使用锁来确保快照隔离。
四、总结:什么时候该用,什么时候不该用?
-
应该使用 Hive 事务的场景:
- 你需要对数据仓库中的历史数据进行批量更新或删除(如合规性要求、数据修正)。
- 你需要精确一次的流式数据插入,保证数据不重不漏。
- 你在实现缓慢变化维(SCD),特别是 Type 2(增加新版本记录)。
-
不应该使用 Hive 事务的场景:
- 高频率的单行 OLTP 操作(例如,每秒钟更新用户状态成百上千次)。Hive 完全不适合这种场景,应选择 HBase、Cassandra 或传统关系型数据库。
- 你的表不需要更新和删除,只是用于追加插入和查询。那么使用普通的 ORC 表即可,无需事务开销。
- 你的表是外部表。
总而言之,Hive 的事务是一个强大的企业级功能,但它并非为了替代 OLTP 数据库而生。它的核心价值在于为大规模数据仓库提供了必要的数据治理能力(更新和删除),使其能够应对更复杂和真实的数据管理需求。

9319

被折叠的 条评论
为什么被折叠?



