Hive 并发模型

Use Cases

数据库中必须有并发支持(http://issues.apache.org/jira/browse/HIVE-1293),并且它们的用例已广为人知。至少,我们希望尽可能地支持并发的 Reader 和 Writer。添加一种机制来发现当前已获取的锁将很有用。并不需要立即添加 API 来显式获取任何锁,因此将隐式获取所有锁。

蜂房中将定义以下锁定模式(请注意,不需要“意图锁定”)。

  • Shared (S)

  • Exclusive (X)

顾名思义,可以同时获取多个共享锁,而 X 锁则阻止所有其他锁。

兼容性矩阵如下:

Lock

兼容性
现有锁
SX
请求 锁定S正确错误
X错误错误

对于某些操作,锁本质上是分层的;例如,对于某些分区操作,表也被锁定(以确保在创建新分区时不能删除该表)。

获取锁定模式背后的理由如下:

对于未分区的表,锁定模式非常直观。读取表时,将获取 S 锁,而对于所有其他操作(将 X 锁插入表中,更改任何种类的表等)均将获取 X 锁。

对于分区表,其思路如下:

执行读取时,将在表和相关分区上获得“ S”锁。对于所有其他操作,将在分区上使用“ X”锁。但是,如果更改仅适用于较新的分区,则在表上获取“ S”锁,而如果更改适用于所有分区,则在表上获取“ X”锁。因此,可以将较旧的分区读取和写入,而将较新的分区转换为 RCFile。每当分区以任何模式锁定时,其所有父级都被锁定为“ S”模式。

基于此,为操作获取的锁如下:

Hive CommandLocks Acquired
选择.. T1 分区 P1S 在 T1,T1.P1 上
插入 T2(分区 P2),选择..T1 分区 P1T2,T1,T1.P1 上的 S 和 T2.P2 上的 X
插入 T2(分区 P.Q)中,选择..T1 分区 P1T2,T2.P,T1,T1.P1 上的 S 和 T2.P.Q 上的 X
更改表 T1 重命名为 T2T1 上的 X
更改表 T1 添加列T1 上的 X
更改表 T1 替换列T1 上的 X
更改表 T1 更改列T1 上的 X
变更表 T1 串联 ****T1 上的 X
更改表 T1 添加分区 P1S 在 T1 上,X 在 T1.P1 上
更改表 T1 删除分区 P1S 在 T1 上,X 在 T1.P1 上
更改表 T1 触摸分区 P1S 在 T1 上,X 在 T1.P1 上
更改表 T1 设置 serdepropertiesT1 上的
变更表 T1 集序列化器T1 上的
更改表 T1 设置文件格式T1 上的
更改表 T1 设置 tblpropertiesT1 上的 X
更改表 T1 分区 P1 并置T1.P1 上的 X
放置表 T1T1 上的 X

为了避免死锁,这里提出一种非常简单的方案。所有要锁定的对象按字典 Sequences 排序,并获得所需的模式锁定。请注意,在某些情况下,对象列表可能是未知的-例如,在动态分区的情况下,在编译时不知道要修改的分区的列表-因此,该列表是保守生成的。由于分区的数目可能未知,因此应该在表或已知的前缀上使用排他锁(但当前不是由于HIVE-3509 bug)。

将添加两个新的可配置参数,以决定锁的重试次数以及每次重试之间的 await 时间。如果重试次数确实很高,则可能导致锁定。查看 ZooKeeper 配方(http://hadoop.apache.org/zookeeper/docs/r3.1.2/recipes.html#sc_recipes_Locks),了解如何使用 zookeeper api 实现读/写锁定。请注意,锁定请求不会 await,而是会被拒绝。现有锁将被释放,并且所有重试间隔将在重试间隔后重试。

由于锁的层次结构,上面列出的配方将无法按指定方式工作。

表 T 的“ S”锁指定如下:

  • 调用 create()创建路径名为“/warehouse/T/read-”的节点。这是协议后面使用的锁定节点。确保设置 Sequences 和短暂标志。

  • 在不设置监视标志的情况下,在锁定节点上调用 getChildren()。

  • 如果有一个孩子的路径名以“ write-”开头,并且序列号比获得的序列号低,则无法获取该锁。删除第一步中创建的节点并返回。

  • 否则,将授予锁定。

表 T 的“ X”锁指定如下:

  • 调用 create()创建路径名为“/warehouse/T/write-”的节点。这是协议后面使用的锁定节点。确保设置 Sequences 和短暂标志。

  • 在不设置监视标志的情况下,在锁定节点上调用 getChildren()。

  • 如果有一个孩子的路径名以“ read-”或“ write-”开头,并且序列号比获得的序列号低,则无法获取该锁。删除第一步中创建的节点并返回。

  • 否则,将授予锁定。

拟议的计划使 Writer 感到饥饿。如果 Reader 比较长,可能会导致 Writer 饥饿。

默认的 Hive 行为将不会更改,并且不支持并发。

关闭并发

您可以通过将以下变量设置为 false 来关闭并发:hive.support.concurrency

Debugging

您可以通过发出以下命令来查看表上的锁:

  • 显示锁\ <TABLE_NAME>;

  • 显示锁定\ <TABLE_NAME>扩展;

  • 显示锁\ <TABLE_NAME> PARTITION( <PARTITION_DESC>);

  • 显示锁\ <TABLE_NAME>分区( <PARTITION_DESC>)已扩展;

另请参见EXPLAIN LOCKS

Configuration

Hive 锁定的配置属性在Locking中描述。

锁定 HiveTransaction

配置单元0.13.0使用新的锁 Management 器添加具有行级 ACID 语义的事务。有关更多信息,请参见: