资讯动态

Hive 源码导读(五):集群还有资源,SQL 为什么仍然不动?

发布时间:2026/10/13 3:18:40 来源:尧图企业网站定制
Hive 源码导读五集群还有资源SQL 为什么仍然不动前四篇我们陪着一项订单任务走完了正常执行路线。现在任务开始多起来了一个会话正在修正订单 1001 的状态另一个会话想修正同一天订单 1002 的状态。第二条 SQL 一直没有进入 MR 提交YARN 上看起来还有资源。加内存有用吗先别急。它可能还没走到向 YARN 申请资源的那一步。这一篇讨论 Hive 锁。先把“在哪排队”认清楚再判断是不是需要更多资源。本文基于Hive 3.1.2、Hadoop 3.2.1MR on YARN。数据锁案例明确使用DbTxnManager hive.support.concurrencytrue full ACID 管理表。锁行为还取决于表类型、操作和配置不能套到所有 Hive 环境。一、先把三种等待分开等待在等什么从哪里找证据编译锁等待HS2 内部的编译并发协调Driver 编译日志、编译相关配置、必要时查看线程状态表或分区锁等待与其他操作存在冲突的读写许可Query ID、SHOW LOCKS、锁对象与阻塞关系YARN 资源等待AM 或任务所需的运行资源Application、队列、调度诊断、AM 日志三种等待都可能让客户端长时间没返回但负责解决问题的地方不同。Driver.compileInternal()中会尝试取得编译锁tryAcquireCompileLock()根据并行编译配置选择会话级或全局锁。这种 Java 进程内的编译锁不是SHOW LOCKS里展示的表锁。不要看到日志里的 lock 就直接查 HMS 锁表先看锁的名字和调用位置。二、说 Hive 锁之前先看事务管理器先记录当前环境SEThive.txn.manager;SEThive.support.concurrency;SEThive.txn.strict.locking.mode;SHOWTBLPROPERTIES csdn_hive_lab.orders_lock;Hive 3.1.2 上游源码中hive.txn.manager的默认值是DummyTxnManagerhive.support.concurrency默认关闭。发行版和公司配置可能覆盖它们。路径核心区别DummyTxnManager不提供 ACID 事务在启用相应并发控制时按锁管理器配置走传统锁路径例如 ZooKeeper 锁DbTxnManager通过 HMS 管理锁与事务锁状态持久化在 Metastore 数据库中接下来只沿第二条路径讲。配置切换需要准备正确的测试服务环境不要默认在一个已经使用过的会话里改一条 SET就完成了整套事务能力切换。这里还有一个很容易漏掉的版本细节。Hive 3.1.2 的DbTxnManager.isLockableTable()先排除临时表再接受MANAGED_TABLE和MATERIALIZED_VIEW外部表不在它接受的类型中。因此前四篇的外部表orders_raw不能直接拿来演示这条数据锁路径。本篇专门准备一张 ACID 管理表orders_lock事务细节放到下一篇解释。三、锁申请为什么发生在 MR 提交之前Driver 拿到计划后知道这条 SQL 要读哪些对象、写哪些对象。DbTxnManager.acquireLocks()据此构建锁请求。从Driver.runInternal()抽出正常主线可以写成取得已编译计划 → lockAndRespond() → 必要时申请锁并检查事务快照状态 → execute() → 成功后的提交或失败后的回滚与清理真实代码还有重编译和异常分支这里只保留位置关系。如果等锁查询就可能还没进入 MR 的任务提交。此时 YARN 再空闲也不会替 Hive 绕过锁检查。可以把锁理解为动手前的协调有人正在重写这一页订单另一个操作是否能同时读写必须先按规则判断。四、三种锁名先认识它们保护什么DbTxnManager 这条路径会用到SHARED_READ、SHARED_WRITE、EXCLUSIVE。针对同一冲突资源忽略同事务特殊处理、层级和排队细节基础兼容关系可以先这样理解已持有的锁 / 新申请的锁SHARED_READSHARED_WRITEEXCLUSIVESHARED_READ兼容兼容冲突SHARED_WRITE兼容冲突冲突EXCLUSIVE冲突冲突冲突SHARED_WRITE这个名字容易让人误会它允许与某些读锁共存并不表示多个这样的写锁可以随便同时拿到。最终是否等待还需要看锁定的数据库、表、分区是否重叠以及排队中是否已有冲突请求。两个不同分区的操作不能机械地照“同一个资源”的表判断。为什么某些读写可以共存ACID 的读取还依赖版本和可见性规则。下一篇会接着讲这部分。五、相同 INSERT为什么拿到的锁可能不同DbTxnManager.acquireLocks()先筛选需要锁定的对象再按操作和表属性选择锁类型。下面几行必须建立在“对象通过本版本的可加锁检查”这个前提上操作和条件本版本对应分支的选择向事务表 INSERT共享读锁类型用于相应并发协调向可加锁的非事务管理表 INSERTstrict lockingtrue排他锁向可加锁的非事务管理表 INSERTstrict lockingfalse共享读锁类型UPDATE / DELETE共享写锁类型向可加锁的非事务管理表 INSERT OVERWRITE排他锁这里的锁名是实现中的协调类型不能只看名字猜测 SQL 做了什么。非事务管理表还涉及部署的严格管理表约束这张表不是建议读者关闭约束来建表。事务表上的 INSERT OVERWRITE 另有适用限制本文不拿它做实验。因此“我们这里两个 INSERT 可以同时执行”是一个需要带条件描述的观察。先把表类型和配置写清楚结论才有意义。六、拿不到锁源码会怎样等DbLockManager.lock()首先调用 HMSLockResponserestxnManager.getMS().lock(lock);如果返回WAITING它会按退避和重试逻辑再次检查restxnManager.getMS().checkLock(res.getLockid());这一过程像拿了号以后定期问“现在轮到我了吗”。不是每次询问都在创建一个新的 YARN 任务。HMS 的lock()、check_lock()再交给TxnHandler处理。DbTxnManager 还会通过心跳维持相应锁或事务的存活信息持有者异常退出后超时与清理机制也需要时间发挥作用。心跳、重试等待和事务超时是不同概念。调大锁重试次数只能改变等待行为不能消除一个仍然存在的冲突。七、用两个会话看一次“资源充足但等锁”实验表orders_lock是独立的 full ACID ORC 管理表已在 实验准备 中定义。这里不修改业务表。会话 A 修正订单 1001UPDATEcsdn_hive_lab.orders_lockSETstatusREFUNDEDWHEREdt2026-10-09ANDorder_id1001;会话 B 修正同一日期的订单 1002UPDATEcsdn_hive_lab.orders_lockSETstatusREFUNDEDWHEREdt2026-10-09ANDorder_id1002;第三个观察会话查看SHOWLOCKS csdn_hive_lab.orders_lockPARTITION(dt2026-10-09)EXTENDED;关键前提是 A 仍持有与 B 冲突的共享写锁。虽然更新的是不同订单锁请求并不是按order_id建立两把互不相干的行锁。这里两次操作落在同一日期分区需要结合实际请求确认表或分区锁范围。六行数据可能执行得很快手工敲第二条 SQL 时第一条早已结束。没看到 WAITING不等于不存在锁规则。要稳定观察可以在隔离的测试 HS2 调试环境里按 A 的 Query ID 设置条件断点停在Driver.runInternal()已完成lockAndRespond()、即将进入execute()的位置。只暂停当前查询线程保留心跳线程和其他会话的运行观察结束后及时继续执行。此时再发起 B观察锁请求状态。恢复 A 后关注它完成、释放相应锁以及 B 后续重新检查锁和快照的过程。拿到锁不保证 B 最终提交成功重叠事务还可能触发快照校验或写冲突处理必须继续观察最终状态。无需占满 YARN也无需靠大数据量拖慢任务。这是源码驱动的复现方案本次写作没有运行该并发实验。仓库中TestDbTxnManager2的锁相关测试也提供了通过分开编译和申请锁来控制时序的思路。八、看到等待先查持有者至少记下锁 ID、状态、类型、数据库、表、分区、事务标识以及可用的阻塞关系再关联 Query ID 和用户。看到的证据下一步当前锁为 WAITING找到冲突持有者和具体资源范围持有者仍在正常执行确认剩余工作和业务并发安排持有者失败或连接失联核对操作、事务状态、心跳和超时清理查不到 DbTxnManager 锁重新确认事务管理器、编译等待和实际阶段直接删 HMS 库里的锁记录会绕过事务协调不能作为正常排障手段。是否取消持有者应先弄清业务影响和它正在做的写入。我们现在知道了SQL 不动可能还在等一张“允许动手”的凭据。但问题还没有结束。有些读写可以并发HDFS 上也会同时出现旧文件、新文件。查询怎么保证不会把订单旧金额和新金额算两遍下一篇看事务与可见性。本篇关键源码位置Driver.tryAcquireCompileLock()、Driver.lockAndRespond()两类不同的锁入口。DbTxnManager.java根据读写对象构建锁请求。DbLockManager.java请求、等待与重试。HiveMetaStore.HMSHandler、TxnHandler.checkLock()及锁兼容判断服务端锁状态。ql/src/test/.../lockmgr/TestDbTxnManager2.java并发锁行为的测试用例。上一篇后续更新可从专栏目录查看 · 下一篇事务与数据可见性后续更新可从专栏目录查看

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑