On this page
Hive 并发模型
Use Cases
数据库中必须有并发支持(http://issues.apache.org/jira/browse/HIVE-1293),并且它们的用例已广为人知。至少,我们希望尽可能地支持并发的 Reader 和 Writer。添加一种机制来发现当前已获取的锁将很有用。并不需要立即添加 API 来显式获取任何锁,因此将隐式获取所有锁。
蜂房中将定义以下锁定模式(请注意,不需要“意图锁定”)。
Shared (S)
Exclusive (X)
顾名思义,可以同时获取多个共享锁,而 X 锁则阻止所有其他锁。
兼容性矩阵如下:
Lock | |||
兼容性 |
现有锁 | ||
S | X | ||
请求 锁定 | S | 正确 | 错误 |
X | 错误 | 错误 |
对于某些操作,锁本质上是分层的;例如,对于某些分区操作,表也被锁定(以确保在创建新分区时不能删除该表)。
获取锁定模式背后的理由如下:
对于未分区的表,锁定模式非常直观。读取表时,将获取 S 锁,而对于所有其他操作(将 X 锁插入表中,更改任何种类的表等)均将获取 X 锁。
对于分区表,其思路如下:
执行读取时,将在表和相关分区上获得“ S”锁。对于所有其他操作,将在分区上使用“ X”锁。但是,如果更改仅适用于较新的分区,则在表上获取“ S”锁,而如果更改适用于所有分区,则在表上获取“ X”锁。因此,可以将较旧的分区读取和写入,而将较新的分区转换为 RCFile。每当分区以任何模式锁定时,其所有父级都被锁定为“ S”模式。
基于此,为操作获取的锁如下:
Hive Command | Locks Acquired |
选择.. T1 分区 P1 | S 在 T1,T1.P1 上 |
插入 T2(分区 P2),选择..T1 分区 P1 | T2,T1,T1.P1 上的 S 和 T2.P2 上的 X |
插入 T2(分区 P.Q)中,选择..T1 分区 P1 | T2,T2.P,T1,T1.P1 上的 S 和 T2.P.Q 上的 X |
更改表 T1 重命名为 T2 | T1 上的 X |
更改表 T1 添加列 | T1 上的 X |
更改表 T1 替换列 | T1 上的 X |
更改表 T1 更改列 | T1 上的 X |
变更表 T1 串联 **** | T1 上的 X |
更改表 T1 添加分区 P1 | S 在 T1 上,X 在 T1.P1 上 |
更改表 T1 删除分区 P1 | S 在 T1 上,X 在 T1.P1 上 |
更改表 T1 触摸分区 P1 | S 在 T1 上,X 在 T1.P1 上 |
更改表 T1 设置 serdeproperties | T1 上的 |
变更表 T1 集序列化器 | T1 上的 |
更改表 T1 设置文件格式 | T1 上的 |
更改表 T1 设置 tblproperties | T1 上的 X |
更改表 T1 分区 P1 并置 | T1.P1 上的 X |
放置表 T1 | T1 上的 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 语义的事务。有关更多信息,请参见: