欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hive 3.x 支持 ACID 增删改查 博客分类: 大数据 hive hadoop 大数据 

程序员文章站 2024-03-15 10:30:59
...

Hive 3 ACID事务
Hive 3通过使用涉及增量文件的写入,读取,插入,创建,删除和更新操作中的技术实现事务性表的原子性和隔离操作,这些操作可以提供查询状态信息并帮助您解决查询问题。

写入和读取操作
Hive 3写入和读取操作改进了事务表的ACID属性和性能。事务表与其他表一样执行。Hive支持所有TPC Benchmark DS(TPC-DS)查询。

Hive 3及更高版本通过简单的写入和插入扩展了原子操作,以支持以下操作:
写入多个分区
在单个SELECT语句中使用多个insert子句
单个语句可以写入多个分区或多个表。如果操作失败,则用户看不到部分写入或插入。即使数据经常变化,操作仍然保持高效,例如每小时百分之一。Hive 3及更高版本不会覆盖整个分区以执行更新或删除操作。

读取语义包括快照隔离。当读取操作开始时,Hive在逻辑上锁定仓库的状态。读操作不受操作期间发生的更改的影响。

仅插入表中的原子性和隔离
当仅插入事务开始时,事务管理器获取事务ID。对于每次写入,事务管理器都会分配写入ID。此ID确定实际写入数据的路径。以下代码显示了仅插入事务表的架构:

CREATE TABLE tm (a int, b int) TBLPROPERTIES
('transactional'='true',
'transactional_properties'='insert_only');
假设发生了三次插入操作,第二次操作失败:

INSERT INTO tm VALUES(1,1);
INSERT INTO tm VALUES(2,2); // Fails
INSERT INTO tm VALUES(3,3);
对于每个写入操作,Hive都会创建一个delta目录,事务管理器将数据文件写入该目录。Hive将所有数据写入由写入ID指定的增量文件,并映射到表示原子操作的事务ID。如果发生故障,则事务被标记为中止,但它是原子的:

tm
___ delta_0000001_0000001_0000
└── 000000_0
___ delta_0000002_0000002_0000       //Fails
└── 000000_0
___ delta_0000003_0000003_0000
└── 000000_0
在读取过程中,事务管理器维护每个事务的状态。当阅读器启动时,它会询问由高水印表示的快照信息。水印标识系统中的最高事务ID,后跟表示仍在运行或已中止的事务的异常列表。

读者查看增量并过滤掉或跳过任何已中止或仍在运行的事务ID。读者将此技术与参与事务的任意数量的分区或表一起使用,以实现事务表的操作的原子性和隔离。

CRUD表中的原子性和隔离性
支持更新和删除的表需要稍微不同的技术来实现原子性和隔离。Hive运行在仅附加文件系统之上,这意味着Hive不执行就地更新或删除。在存在就地更新或删除的情况下,不能发生读取器和写入器的隔离。在这种情况下,隔离需要锁管理器或其他一些机制。这些机制为长时间运行的查询带来了问题。

Hive不是就地更新,而是使用行ID装饰每一行。行ID是 struct由以下信息组成的:
映射到创建该行的事务的写入ID
桶ID,创建该行的物理写入器的具有几位信息的位支持整数
行ID,在写入数据文件时对行进行编号
以下示例显示完整CRUD(创建,检索,更新,删除)事务表的架构:

CREATE TABLE acidtbl (a INT, b STRING)
STORED AS ORC TBLPROPERTIES
('transactional'='true');

当发生删除时,Hive会将更改附加到表中,而不是就地删除。删除的数据变得不可用,压缩过程稍后处理垃圾收集。

创建操作
以下示例将多行数据插入完整的CRUD事务表,创建增量文件,并将行ID添加到数据文件中。

INSERT INTO acidtbl (a,b) VALUES (100, "oranges"), (200, "apples"), (300, "bananas");
此操作将生成具有以下数据的目录和文件delta_00001_00001 / bucket_0000:
ROW_ID 一个 b
{1,0,0} 100 “橙子”
{} 1,0.1 200 “苹果”
{1,0,2} 300 “香蕉”
删除操作
与单行匹配的delete语句还会创建一个delta文件,称为delete-delta。该文件为与您的查询匹配的行存储一组行ID。在阅读时,读者会查看此信息。当它找到与行匹配的删除事件时,它会跳过该行,并且该行不包含在运算符管道中。以下示例从事务表中删除数据:

DELETE FROM acidTbl where a = 200;
此操作生成具有以下数据的目录和文件delete_delta_00002_00002 / bucket_0000:
ROW_ID 一个 b
{1,0,1} 空值 空值
更新操作
更新结合了删除和插入新数据。以下示例更新了一个事务表:

UPDATE acidTbl SET b = "pears" where a = 300;
一个delta文件包含delete事件,另一个包含insert事件:


需要AcidInputFormat的阅读器应用所有插入事件并封装所有逻辑来处理删除事件。读取操作首先从事务管理器获取快照信息,基于该事件管理器,它选择与该读取操作相关的文件。接下来,该过程将每个数据文件拆分为每个进程必须处理的块数。相关删除事件已本地化到每个处理任务。删除事件存储在已排序的ORC文件中。压缩的存储数据是最小的,这是Hive 3的一个重要优势。您不再需要担心delta文件中的插入事件使网络饱和。