hive锁 hive锁表原因及如何处理

1.背景

在数据仓库开发中,遇到了读取数据任务导致锁表问题,发现是因为补数据或月度大任务跨天运行,此时凌晨定时的写入操作就会被阻塞进入等待状态(如果超过最大等待时间会失败),直到读取任务完成写入任务才可以继续运行,导致当天结果层数据输出延迟。因此分析并总结下锁表机制原理以及解决方式。

2.锁机制及原理分析

Hive 目前主要有两种锁,SHARED(共享锁 S)和 Exclusive(排他锁 X),同时又分表锁与分区锁,分区锁为最小粒度。

解释:

1)表锁与分区锁,分区锁为最小粒度(如果表锁未锁写入的分区,是可以执行写入任务的)

2)查询操作使用共享锁(S锁),共享锁是可以多重、并发使用的(就是说其他查询也可以挂S锁,并发查询不会阻塞修改会阻塞)

3)修改表操作使用独占锁(X锁),它会阻止其他的查询、修改操作

4)S锁和X锁同时出现会出现死锁情况(查询和写入不可同时发生)

3.解决方式

Hive锁机制会影响我们数据仓库输出效率,如果在已知表/分区的解锁对正运行的任务没有影响情况下我们可以在session 中关闭锁,通常我们会在X锁操作任务加上set hive.support.concurrency=false; 这个参数为 false 既能保证session忽略任何锁强行操作数据,又能保证session里的SQL对表不加任何锁;非分区表慎用由于不加锁写入时候同时读取会导致数据一致性问题。

show locks tableName; #查看表锁

show locks tableName partition(dt='2014-04-01'); #查看分区锁

unlock table; unlock table partition(dt='2014-04-01'); #解锁表

set hive.support.concurrency=false; #在 session 中关闭锁默认为true,

4.拓展分析

SHOW LOCKS <TABLE_NAME>; #查看HIVE表是否被锁
SHOW LOCKS <TABLE_NAME> EXTENDED;#查看哪一个SQL锁了HIVE表 
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>); #查看HIVE表分区是否被锁 
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>) EXTENDED;#查看哪一个SQL锁了HIVE表分区

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

(hive默认的sleep时间是60s,比较长,在高并发场景下,可以减少这个的数值来提供job的效率)

hive.lock.numretries #重试次数
hive.lock.sleep.between.retries #重试时sleep的时间

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)

5.总结:

避免Hive因为锁导致的读写任务阻塞等待或失败:

1、建议表设置分区,因为锁可以到分区粒度,防止大字典表,单张全量表类似表长时间锁表,导致长时间阻塞读写任务。

2、如果新分区被锁可以通过 set hive.support.concurrency=false 来关闭锁机制,保证新分区写入数据成功。非分区表慎用由于不加锁写入时候同时读取会导致数据一致性问题。

3、脚本重跑一段时间范围数据时设置 sleep 间隔,避免长期持有锁,造成依赖此表的下游任务调度失败(这种方式需要根据下游任务分析运行状态时间)。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值