hive 中的锁

hive表中的锁

任务报错:ERROR : FAILED: Error in acquiring locks: Lock acquisition for LockRequest

场景:
在执行insert into或insert overwrite任务时,中途手动将程序停掉,会出现卡死情况(无法提交MapReduce),只能执行查询操作,而drop insert操作均不可操作。

原因
hive表被锁或者某个分区被锁,需要解锁

如何查看锁:

show locks 表名

如何解锁:

unlock table 表名;  -- 解锁表 ,测试这个命令没什么用,表依然处于无法操作状态
unlock table 表名 partition(dt='2020-04-01');  -- 解锁某个分区

注意:

  • 表锁和分区锁是两个不同的锁,对表解锁,对分区是无效的,分区需要单独解锁
  • 高版本hive默认插入数据时,不能查询,因为有锁

解决办法:
关闭锁机制
报错的sql中加入以下语句

set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;

或者下列语句

set hive.support.concurrency=false;// 默认为true,可强制忽略锁,但为了数据完整性,不建议常用此操作。

终极解决办法:
修改 hive-site.xml 配置文件

[hadoop@hadoop01 ~]$ find / -name hive-site.xml 
[hadoop@hadoop01 conf]$ vi hive-site.xml
<property>
   <name>set hive.txn.manager</name>
   <value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
</property>

注:hive-site.xml中如有下列配置可以不配置,默认为true,如果设置成false则会报错!

<property>
   <name>set hive.support.concurrency</name>
   <value>true</value>
</property>

hive锁的其他配置
可以在锁冲突时 fail fast 或者 重试等待锁释放

hive.lock.numretries #重试次数
hive.lock.sleep.between.retries #重试时sleep的时间
hive默认的sleep时间是60s,比较长,在高并发场景下,可以减少这个的数值来提供job的效率

HIVE锁原理

Hive中锁类型:

  • 共享锁(Share)
  • 互斥锁(Exclusive)
    不同锁之间的兼容性如下图:
    在这里插入图片描述

锁的基本机制:

  • 元信息和数据的变更需要互斥锁,它会阻止其他的查询、修改操作
  • 数据的读取需要共享锁,共享锁是可以多重、并发使用的

关闭锁机制的影响:

  • 并发读写同一份数据时,读操作可能会随机失败
  • 并发写操作的结果在随机出现,后完成的任务覆盖之前完成任务的结果
  • SHOW LOCKS, UNLOCK TABLE 会报错

hive 处理表的流程 (CDH4.2.0)

  1. 首先对query进行编译,生成QueryPlan
  2. 构建读写锁对象(主要两个成员变量:LockObject,Lockmode)
    对于非分区表,直接根据需要构建S或者X锁对象
    对于分区表:(此处是区分input/output)
    If S mode:
    直接对Table/related partition 构建S对象
    Else:
    If 添加新分区:
    构建S对象
    Else
    构建X对象
    End
  3. 对锁对象进行字符表排序(避免死锁),对于同一个LockObject,先获取Execlusive
  4. 遍历锁对象列表,进行锁申请
    While trynumber< hive.lock.numretries(default100):
    创建parent(node)目录,mode= CreateMode.PERSISTENT
    创建锁目录,mode=CreateMode.EPHEMERAL_SEQUENTIAL
    For Child:Children
    If Child已经有写锁:
    获取child写锁seqno
    If mode=X 并且 Child 已经有读锁
    获取child读锁seqno
    If childseqno>0并且小于当前seqno
    释放锁
    Trynumber++
    Sleep(hive.lock.sleep.between.retries:default1min)

总结:
想要避免 Hive 锁报错,可以注意以下3点:
1、表建议设置分区,锁的粒度可以到分区,否则容易遭遇长时间锁表,尤其大字典表、单张全量表要注意。
2、建议脚本重跑一段时间范围数据时设置 sleep 间隔,避免长期持有锁,造成依赖表的任务调度失败。
3、我们可以通过 set hive.support.concurrency=false 来关闭锁,优先保证插入数据成功,虽然此时读数据会有问题。

Refer:

https://blog.51cto.com/caiguangguang/1344453
https://cwiki.apache.org/confluence/display/Hive/Locking

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值