Hive 并发模型

来源:互联网 发布:网络视频课程快进方法 编辑:程序博客网 时间:2024/06/14 13:21

使用案例

并发支持 (http://issues.apache.org/jira/browse/HIVE-1293) 是数据库的必须,而且他们的使用案例很好懂。至少,我们要尽可能支持并发读和写。添加几个发现当前已经锁定的锁,是有用的。这里没有一个直接的需求添加一个API显式获取锁,所以,所有锁都是隐式获取的。

hive定义一下模式的锁(注意不需要意向锁)

  • 共享 (S)
  • 排他 (X)

见名知意,多个共享锁可以同时获取,而排他锁会阻塞其他锁。

兼容性列表如下:

  • *
Existing LockSXRequested Lock
  • *
  • *
  • *
S
  • *
TrueFalseX
  • *
FalseFalse

对于一些操作,锁的性质是有层次的。例如,一些分区操作,表也是被锁定(例如,保证表的分区正在创建时,表不能被删除)

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

对于非分区表,锁定模式相当直观。当表正在读取时,一个S锁被获取。而对其他操作(插入数据到表,修改表的任何属性)就要获取X锁。

对于分区表,原理如下:

当读取表分区时,会获取表的S锁。对于其他操作,会获取分区的X锁。但是,如果修改仅仅是针对新分区,就会获取表的S锁,而修改是针对所有分区,会获取表的X锁。

所以,当旧分区读写时,新分区也可以被转换为RCFile。

无论何时,分区被锁定时,会获取所有的它的父节点的S锁。

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

Hive CommandLocks Acquiredselect .. T1 partition P1S on T1, T1.P1insert into T2(partition P2) select .. T1 partition P1S on T2, T1, T1.P1 and X on T2.P2insert into T2(partition P.Q) select .. T1 partition P1S on T2, T2.P, T1, T1.P1 and X on T2.P.Qalter table T1 rename T2X on T1alter table T1 add colsX on T1alter table T1 replace colsX on T1alter table T1 change colsX on T1alter table T1 add partition P1S on T1, X on T1.P1alter table T1 drop partition P1S on T1, X on T1.P1alter table T1 touch partition P1S on T1, X on T1.P1*alter table T1 set serdeproperties *S on T1*alter table T1 set serializer *S on T1*alter table T1 set file format *S on T1*alter table T1 set tblproperties *X on T1drop table T1X on T1

为了避免死锁,这里提出一个非常简单的计划.所有锁定的对象按照字典排序,然后在按照锁定模式获取。注意一些场景,对象列表可能不知道——例如,动态分区,编译时不知道正在修改的分区列表。所以,列表会保守生成,由于分区的数量可能不知道,所以会在表或所知的前缀上获取排他锁。

添加两个可配置的参数,决定锁尝试时,锁尝试次数和等待时间。如果重试的次数是非常高的,它可以导致一个活锁。参考zookeeper recipes(http://hadoop.apache.org/zookeeper/docs/r3.1.2/recipes.html#sc_recipes_Locks),理解如何使用zookeeper apis实现read/write锁。需要注意的是,不是等待的锁请求将被拒绝。存在的锁将会释放,然后等待的锁会在尝试周期后继续尝试。

因为锁的分层特性,上面列出的规定recipe将无法正常工作:

 

表T的S锁规定如下:

调用create( ),创建一个路径名为"/warehouse/T/read-"的节点。协议中,这个锁定的节点会在后面使用。保证设置序列和临时标志。

在锁定的节点调用getChildren( ),不设置watch的标记

如果已经有一个子节点,路径名以"write-"和一个更小的序列号数字开头,已经被获取了,那么这个锁不能被获取。删除第一步骤创建的节点,返回。

否则授权锁。

 

表T的X锁规定如下:

调用create( ),创建一个路径名为"/warehouse/T/write-"的节点。协议中,这个锁定的节点会在后面使用。保证设置序列和临时标志。

在锁定的节点调用getChildren( ),不设置watch的标记

如果已经有一个子节点,路径名以"read-"或者"write-"和一个更小的序列号数字开头,已经被获取了,那么这个锁不能被获取。删除第一步骤创建的节点,返回。

否则授权锁。

拟定的计算,为了读饥饿了写,如果遇到长时间的读,会导致写的饥饿。

这个默认hive行为不会改变,并发不会支持。

 

关闭并发

关闭并发,可以修改下面的变量为false: hive.support.concurrency

调试

查看表的锁,可以执行下面的命令:

SHOW LOCKS <TABLE_NAME>;SHOW LOCKS <TABLE_NAME> extended;SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>);SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>) extended;

 

翻译自 https://cwiki.apache.org/confluence/display/Hive/Locking

0 0
原创粉丝点击