Hive在0.7开始对并发进行支持,本文简述一下Hive(CDH4.2.0)的锁处理流程:1. 首先对query进行编译,生成QueryPlan2. 构建读写锁对象(主要两个成员变量:LockObject,Lockmode)对于非分区表,直接根据需要构建S或者X锁对象对于分区表:(此处是区分input/output)If S mode:直接对Table/related partition 构建S对象Else:If 添加新分区:构建S对象Else构建X对象End3. 对锁对象进行字符表排序(避免死锁),对于同一个LockObject,先获取Execlusive4. 遍历锁对象列表,进行锁申请While trynumber< hive.lock.numretries(default100):创建parent(node)目录,mode= CreateMode.PERSISTENT创建锁目录,mode=CreateMode.EPHEMERAL_SEQUENTIALFor Child:ChildrenIf Child已经有写锁:获取child写锁seqnoIf mode=X 并且 Child 已经有读锁获取child读锁seqnoIf childseqno>0并且小于当前seqno释放锁Trynumber++Sleep(hive.lock.sleep.between.retries:default1min)
因此对于并发相对较高的场景来说默认的sleep时间太长了,并且这里使用的sleep模型也太简单,可能与本身hive并发写场景较少有关系.
另外就是对于是否启用并发是可以在客户端设置的,因此如果对于写的ETL Job担心被读锁住时可以在脚本里关闭该特性.