文档章节

Hive Lock 那些事儿

大数据之路
 大数据之路
发布于 2017/06/09 00:45
字数 1538
阅读 3714
收藏 3

0、背景

最近两天数据仓库中一张核心表遭遇了锁的问题,导致数据插入失败,影响挺大,之前一直没注意到这个问题,借此总结一下这块的知识和遇到的坑。

hive 在 0.7 版本之后开始支持并发,线上的环境默认是用 zookeeper 做 hive 的锁管理,Hive开启并发功能的时候自动开启锁功能。

1、Hive 锁的类型与关系

hive 目前主要有两种锁,SHARED(共享锁 S)和 Exclusive(排他锁 X)。共享锁 S 和  排他锁 X 它们之间的兼容性矩阵关系如下:

总结起来就是:

  • 1)查询操作使用共享锁,共享锁是可以多重、并发使用的
  • 2)修改表操作使用独占锁,它会阻止其他的查询、修改操作
  • 3)可以对分区使用锁。

以下情况会出发锁,以及它的类型和锁定范围如下:

Hive Command

Locks Acquired

select .. T1 partition P1

S on T1, T1.P1

insert into T2(partition P2) select .. T1 partition P1

S on T2, T1, T1.P1 and X on T2.P2

insert into T2(partition P.Q) select .. T1 partition P1

S on T2, T2.P, T1, T1.P1 and X on T2.P.Q

alter table T1 rename T2

X on T1

alter table T1 add cols

X on T1

alter table T1 replace cols

X on T1

alter table T1 change cols

X on T1

alter table T1 concatenate X on T1

alter table T1 add partition P1

S on T1, X on T1.P1

alter table T1 drop partition P1

S on T1, X on T1.P1

alter table T1 touch partition P1

S 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 T1

alter table T1 partition P1 concatenate X on T1.P1

drop table T1

X on T1

2、如何开启锁机制

修改hive-site.xml,配置如下:

<property>
    <name>hive.zookeeper.quorum</name>
    <value>zk1,zk2,zk3</value>
  </property>
<property>
    <name>hive.support.concurrency</name>
    <value>true</value>
</property>

除此之外,还可以手动显式设置独占锁:

-- 1)锁表
hive> lock table t1 exclusive;
-- 表被独占锁之后,将不能执行查询操作:
hive> SELECT COUNT(*) FROM people;
conflicting lock present for default@people mode SHARED
FAILED: Error in acquiring locks: locks on the underlying objects
cannot be acquired. retry after some time

-- 2)解除锁
hive> unlock table t1;

注:Lock 是一种悲观的顺序化机制。它假设很可能发生冲突,因此在操作数据时,就加锁。

如果冲突的可能性很小,多数的锁都是不必要的。比如 Innodb 实现了一个延迟加锁的机制,来减少加锁的数量,提升性能,在代码中称为隐式锁(Implicit Lock),在本文中提到的 Hive锁默认都是隐式锁,除非手动加锁才是显式锁。

3、如何 debug lock

可以使用以下命令开始debug和排查锁问题:

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

比如我们执行以下语句就可以知道是那个SQL锁Hive表了:

show locks hdp_ubu_zhuanzhuan_defaultdb.token extended

4、如何关闭锁

hive的锁在某些情况下会影响job的效率。在对数据一致性要求不高,或者已经明确了解到lock不会对job产生影响的情况下可以在session级别关闭lock的支持,又或者在表被任务循环持续读取时,insert 插入失败(建议脚本重跑一段时间范围数据时设置 sleep 间隔,避免长期持有锁,造成依赖表的任务调度失败)。我们可以通过 set hive.support.concurrency=false 参数在 session 中关闭锁,这个参数为 false 既能保证session忽略任何锁强行操作数据,又能保证session里的SQL对表不加任何锁

  • 场景1:离线下载分析商业cdn的qos job。

使用load data将数据导入hive中,hive的表按 dt,hour,domain进行明确分区,因此,是否有锁对数据的一致性影响不大,反而有了锁之后,job之间就会有锁竞争的问题(报错信息:conflicting lock present for table  mode EXCLUSIVE)。

调整 job:

hive --database cdnlog -e "
    set hive.support.concurrency=false;
    load data local inpath 'file' 
    OVERWRITE into table chinanetcenter_log_origin 
    partition(dt='2013-12-17',hour='04',domain='xxx')
"

数据load时就不会有报错了,效率也高了不少

  • 场景2:hive锁的几个配置,可以在锁冲突时 fail fast 或者 重试等待锁释放
hive.lock.numretries #重试次数
hive.lock.sleep.between.retries #重试时sleep的时间

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

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:

[1] Hive Concurrency Model:Locking

https://cwiki.apache.org/confluence/display/Hive/Locking

[2] Hive Locks -- Table/Partition Level

https://community.mapr.com/docs/DOC-1299

[3] hive lock的配置问题

http://caiguangguang.blog.51cto.com/1652935/1344453

[4] MySQL数据库InnoDB存储引擎中的锁机制 

http://www.uml.org.cn/sjjm/201205302.asp

[5] mysql锁机制浅析(1)

https://segmentfault.com/a/1190000004507047

© 著作权归作者所有

大数据之路
粉丝 1601
博文 515
码字总数 333234
作品 0
武汉
架构师
私信 提问
Hive 使用陷阱(Lock table) 排查过程

前言 业务部门使用python通过hive thrift api做数据统计,早段时间发现在频繁创建表的时候,接口会卡死。经过一番的排查,是因为hive的lock table manager特性对于hive server的接口服务不兼...

kisops
2013/08/11
9.4K
6
Hive 使用陷阱(Lock table) 排查过程

前言 业务部门使用python通过hive thrift api做数据统计,早段时间发现在频繁创建表的时候,接口会卡死。经过一番的排查,是因为hive的lock table manager特性对于hive server的接口服务不兼...

snakelxc
2013/08/11
488
1
Hive Transaction 事务性 小试

提到Hive一般都会想到,Hive是数据仓库,支持类SQL查询,有很多语法支持,可以嵌套MR,写Transform、写UDF/UDAF等,但是,不支持更新操作。所以Hive的常见也一般都是一次写入,频繁读取。从H...

王二铁
2016/07/14
8.9K
8
Hive权限控制和超级管理员的实现

Hive权限控制 Hive权限机制: Hive从0.10可以通过元数据控制权限。但是Hive的权限控制并不是完全安全的。基本的授权方案的目的是防止用户不小心做了不合适的事情。 先决条件: 为了使用Hive的...

蘑菇街隐修
2013/06/20
0
0
Monitor的另一种用法

在多线程编程时我们可以使用lock(obj){}代码块来控制关键代码的访问,lock其实是Monitor.Enter(obj)和Monitor.Exit(obj)的一种简单写法(语法糖)。 这个随笔的标题是“Monitor的另一种用法”,...

长平狐
2012/06/08
64
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
6
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
7
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
9
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部