1. 为什么要使用事务表?
- Hive 原本是不支持事务的,也就是不支持 增删改(insert、delete、update)、回滚等 操作的。因为:
- Hive的核心目标是: 将已经存在的结构化数据文件映射成为表,然后提供基于表的SQL分析处理。也就是说Hive是面向分析的,并不是面向设计的。
- HDFS不支持随机修改文件。
- 但是随着技术的发展,不支持事务在某些方面也会带来很大的弊端,如:
- 所以Hive0.14后开始支持事务,即创建事务表。但是事务表有很大的限制:
2. 创建使用事务表
-
第一步:开启事务配置(可以使用set设置当前session生效 也可以配置在hive-site.xml中)
set hive.support.concurrency = true; --Hive是否支持并发 set hive.enforce.bucketing = true; --从Hive2.0开始不再需要 是否开启分桶功能 set hive.exec.dynamic.partition.mode = nonstrict; --动态分区模式 非严格 set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; -- set hive.compactor.initiator.on = true; --是否在Metastore实例上运行启动线程和清理线程 set hive.compactor.worker.threads = 1; --在此metastore实例上运行多少个压缩程序工作线程
-
第二步:在创建表时加上①
clustered by
关键字;②stored as
关键字;③TBLPROPERTIES('transactional'='true')
关键字create table trans_student( id int, name String, age int ) -- 1. 必须为分桶表(如果在前面通过set开启了分桶功能,那么这里可以不写该语句) clustered by (id) into 2 buckets -- 2. 存储方式为 orc stored as orc -- 3. 设置表属性transactional为true,开启事务 TBLPROPERTIES('transactional'='true');
-
然后就可以使用 insert、update、delete 对事务表进行事务操作。
注意:使用insert update delete操作数据时,并不是真正的插入/修改/删除数据,而是重新创建了一个新文件,将数据写入进去,并将原文件做了删除标记。通过标记的方式来实现事务。(后面会介绍)
3. 实现原理
3.1 事务产生文件夹
由于HDFS中只支持追加数据,并不能像MySQL一样随机修改数据。所以,采用不改变原始数据,创建文件进行标记的方法来实现事务:
-
每次执行一次事务操作都会创建一个文件夹:
- insert语句会创建
delta_xxx_xxx_xxx
文件夹; - delete语句会创建
delete_delta_xxx_xxx_xxx
文件夹; - update语句是通过delete、insert两个语句完成的,即先删除,后添加。
关于
_xxx
是怎么命名的? - insert语句会创建
-
正在执行中的事务,是以一个
.hive-staging_hive_xxx
的文件夹维护的,执行结束后就会改名为delta_xxx_xxx_xxx
或delete_delta_xxx_xxx_xxx
文件夹。
-
当访问Hive数据时,根据HDFS原始文件和相应的delta增量文件做合并,从而得到查询数据。
3.2 那么文件夹里面有什么?
每个事务的delta文件夹下,都有两个文件:
-
orc_acid_version
文件:文件里的内容是2,标识acid版本为2。和版本1的主要区别是UPDATE语句采用了split-update特性,即先删除、后插入。 -
bucket_00000
文件:文件里是写入的数据内容。如果事务表没有分区和分桶,就只有一个这样的文件。
3.3 合并器(Compactor)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84531.html