IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> [hive-3.1]当 insert into 表的一个分区时,select 其他分区卡住 -> 正文阅读

[大数据][hive-3.1]当 insert into 表的一个分区时,select 其他分区卡住

1. 使用 hive-cli 执行以下语句

create table t1(c1 string) stored as textfile;
load data local inpath '/etc/profile' overwrite into table t1;

create table t2(c1 int) partitioned by (pt string);

insert overwrite table t2 partition (pt=1) select length(c1) from t1;

在一个会话 session 1 执行时:

insert overwrite table t2 partition (pt=2) select length(c1) from t1;

在会话 session 1 的语句执行时, 另一个会话 session 2 中执行:


select * from t2 where pt=1;

会发现 session 2 在 session 1 执行结束后才开始执行。

2. 原因分析

当前配置:

   <property>
      <name>hive.txn.manager</name>
      <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
    </property>

在 session 1 执行时,会获取 t2 表 partition (pt=2) 这个分区的 exclusive write 权限,现在没有其他会话操作表 t2,获取锁。
session 2的语句,会获取 t2 表的两个权限,分别是 t2 表的 shared read 权限和 t2 表 partition(pt=1) 的 shared read 权限这两个权限。
原因 t2 表的 shared read 权限获取不了。

3. 解决方案

3.1 insert overwrite 的解决方案

hive-site.xml 修改以下参数的值

   <property>
      <name>hive.txn.manager</name>
      <value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
    </property>
    <property>
      <name>hive.support.concurrency</name>
      <value>false</value>
  </property>

以上配置,当调用获取锁、释放锁、开启事务、关闭事务等调用时直接返回。

3.2 insert overwrite 的解决方案2

hive-site.xml 修改以下参数的值

   <property>
      <name>hive.txn.manager</name>
      <value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
    </property>
    <property>
      <name>hive.lock.manager</name>
      <value>org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager</value>
  </property>

3.3 insert into 的解决方案

如果是 insert into 而不是insert overwrite 时,可以设置 hive.txn.strict.locking.mode=false 解决,这时 insert into 获取共享锁。
各配置项如下:

   <property>
      <name>hive.txn.manager</name>
      <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
    </property>
    <property>
      <name>hive.txn.strict.locking.mode</name>
      <value>false</value>
  </property>

4 机制说明

4.1 总体说明

txn manager 里实例化一个 lock mamanger。

Hive txn manager 一共两种实现,一种是 DbTxnManager,一种是 DummyTxnManager.

4.2 DbTxnManager

hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager 时,固定使用 DbLockManager,不论hive.lock.manager 配置为何值。

hive.txn.strict.locking.mode 的作用。仅当 hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager 并且是内部表生效。当值为 false 时,insert into ${TABLE_NAME} partition(不是 insert overwrite table ${TABLE_NAME} partition) 获取 shared 锁。当值为 true 时,insert into ${TABLE_NAME} partition 获取 exclusive 锁。

往分区写数据时,插入一条记录,内容如下:

HL_LOCK_EXT_ID: 2234 // 锁外部 ID
HL_LOCK_INT_ID: 2 // 一个递增编号,和 HL_LOCK_EXT_ID 组成联合主键
HL_TXNID: 2721 // 事务ID 
HL_DB: default // 数据库名
HL_TABLE: t2 // 表名
HL_PARTITION: pt=3 // 分区名
HL_LOCK_STATE: a // 锁状态:a(acquired),w (waiting)
HL_LOCK_TYPE: e // 锁类型: e(exclusive), s (shared)
HL_LAST_HEARTBEAT: 0
HL_ACQUIRED_AT: 1658285505000
HL_USER: houzhizhen
HL_HOST: localhost
HL_HEARTBEAT_COUNT: NULL
HL_AGENT_INFO: houzhizhen_20220720105145_3c787b27-94d0-44d1-be62-10965ac3258e
HL_BLOCKEDBY_EXT_ID: NULL
HL_BLOCKEDBY_INT_ID: NULL

当读取一个分区时(pt=1),需要两个权限,一个是 表的 shared 权限,一个是分区的 shared 权限。表的权限拿不到,因为按数据库名和表名拿到的 lock 记录时exclusive。

HL_LOCK_EXT_ID: 2235
HL_LOCK_INT_ID: 1
HL_TXNID: 2722
HL_DB: default
HL_TABLE: t2
HL_PARTITION: NULL
HL_LOCK_STATE: w
HL_LOCK_TYPE: r
HL_LAST_HEARTBEAT: 0
HL_ACQUIRED_AT: NULL
HL_USER: houzhizhen
HL_HOST: localhost
HL_HEARTBEAT_COUNT: NULL
HL_AGENT_INFO: houzhizhen_20220720105214_f33da326-e509-47af-a208-ea1a7b6b9783
HL_BLOCKEDBY_EXT_ID: NULL
HL_BLOCKEDBY_INT_ID: NULL

4.3 DummyTxnManager

hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager 并且 hive.support.concurrency=false 的时候,不会实例化一个 lock manager。调用获取锁、释放锁、开启事务、关闭事务等调用时直接返回。

hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager 并且 hive.support.concurrency=true 时, lock manager 根据 hive.lock.manager 的值创建对应的对象。这时,没有事务的功能。开启事务、关闭事务调用时直接返回。但是获取锁和释放锁操作,转给 lock manager 对应的方法处理。

DummyTxnManager 会把获取的权限的请求进行拆分。
当写分区(pt=3) 时,锁对象(db=default, table=t2, pt=3),拆成以下3个锁对象。

dbLock = (pathName=["default"], type="shared");
tableLock = (pathName=["default", "t2"], type="shared");
partitionLock = (pathName=["default", "t2", "pt=3"], type="exclusive");

把这些锁对象的 pathName 转成 zookeeper 的 znode,申请之后的 znode 为:

[zk: localhost:2181(CONNECTED) 6] ls /hive_zookeeper_namespace/default
[LOCK-SHARED-0000000000, t2]
[zk: localhost:2181(CONNECTED) 10] ls /hive_zookeeper_namespace/default/t2
[LOCK-SHARED-0000000000, pt=3]
[zk: localhost:2181(CONNECTED) 11] ls /hive_zookeeper_namespace/default/t2/pt=3
[LOCK-EXCLUSIVE-0000000000]

当读分区(pt=1) 时,需要两个锁对象(db=default, table=t2, pt=1)和(db=default, table=t2)。

(db=default, table=t2, pt=1)拆成以下3个锁对象。

dbLock = (pathName=["default"], type="shared");
tableLock = (pathName=["default", "t2"], type="shared");
partitionLock = (pathName=["default", "t2", "pt=1"], type="shared");

(db=default, table=t2)拆成以下2个锁对象。

dbLock = (pathName=["default"], type="shared");
tableLock = (pathName=["default", "t2"], type="shared");

对这5个对象进行去重。
得到3个对象

dbLock = (pathName=["default"], type="shared");
tableLock = (pathName=["default", "t2"], type="shared");
partitionLock = (pathName=["default", "t2", "pt=1"], type="shared");

把这些锁对象的 pathName 转成 zookeeper 的 znode,申请之后的 znode 为:

[zk: localhost:2181(CONNECTED) 6] ls /hive_zookeeper_namespace/default
[LOCK-SHARED-0000000000, t2]
[zk: localhost:2181(CONNECTED) 10] ls /hive_zookeeper_namespace/default/t2
[LOCK-SHARED-0000000000, pt=3]
[zk: localhost:2181(CONNECTED) 11] ls /hive_zookeeper_namespace/default/t2/pt=1
[LOCK-SHARED-0000000000]

所以当写 pt=3 时,读取 pt=1 是没有问题。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:37:17  更:2022-07-21 21:37:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:35:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码