错误:失败:获取锁时出错:与元存储 org.apache.hadoop.hive.ql.lockmgr.LockException 通信时出错

Posted

技术标签:

【中文标题】错误:失败:获取锁时出错:与元存储 org.apache.hadoop.hive.ql.lockmgr.LockException 通信时出错【英文标题】:ERROR : FAILED: Error in acquiring locks: Error communicating with the metastore org.apache.hadoop.hive.ql.lockmgr.LockException 【发布时间】:2020-04-21 09:01:48 【问题描述】:

在尝试在分区表上运行 count(*) 时获取Error in acquiring locks。 当过滤 时,该表有 365 个分区,查询工作正常。 当尝试为查询包含更多分区时,它会因错误而失败。

处理 Hive 管理的 ACID 表,具有以下默认值

hive.support.concurrency=true //不能设为假,它会抛出<table> is missing from the ValidWriteIdList config: null,对于ACID读写来说应该是真的。 hive.lock.manager=org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager hive.txn.strict.locking.mode=false hive.exec.dynamic.partition.mode=nonstrict

尝试通过直线会话增加/减少这些后续的值。

hive.lock.numretries hive.unlock.numretries hive.lock.sleep.between.retries hive.metastore.batch.retrieve.max=default 300 //改为10000 hive.metastore.server.max.message.size=default 104857600 // 改为 10485760000 hive.metastore.limit.partition.request=default -1 //没有改变,因为 -1 是无限的 hive.metastore.batch.retrieve.max=default 300 //更改为 10000。 hive.lock.query.string.max.length=default 10000 //更改为更高的值

使用 HDI-4.0 interactive-query-llap 集群,meta-store 由提供的默认 sql-server 支持。

【问题讨论】:

【参考方案1】:

问题不是由于 hive 元存储数据库的服务层。 这很可能是由于基于症状的一个查询中的分区太多。 我多次遇到同样的问题。 在 hivemetastore.log 中,您应该可以看到这样的错误:

metastore.RetryingHMSHandler: MetaException(message:Unable to update transaction database com.microsoft.sqlserver.jdbc.SQLServerException: The incoming request has too many parameters. The server supports a maximum of 2100 parameters. Reduce the number of parameters and resend the request.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:254)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1608)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:578)

这是由于在 Hive Metastore 中,每个参与 Hive 查询的分区最多需要 8 个参数来获取锁。

一些可能的解决方法:

将查询分解为多个子查询以从更少的读取 分区。

通过设置不同的分区键来减少分区的数量。

如果分区键没有任何过滤器,则删除分区。

以下是管理直接 SQL 生成的 INSERT 查询的批量大小的参数。它们的默认值是 1000。在 Hive configs via 的 Custom hive-site 部分中将它们都设置为 100(作为一个很好的起点)。 Ambari 并重新启动所有 Hive 相关组件(包括 Hive 元存储)。

hive.direct.sql.max.elements.values.clause=100 hive.direct.sql.max.elements.in.clause=100

【讨论】:

【参考方案2】:

我们在 HDInsight 中也遇到了同样的错误,在进行了与您所做的类似的许多配置更改之后,唯一有效的方法是扩展我们的 Hive Metastore SQL DB 服务器。

我们必须将其一直扩展到具有 250 个 DTU 的 P2 层,以便我们的工作负载在没有这些锁定异常的情况下正常工作。您可能知道,随着层数和 DTU 数量的增加,SQL Server 的 IOPS 和响应时间会提高,因此我们怀疑 Metastore 性能是随着工作负载增加而导致这些 Lock Exceptions 的根本原因。

以下链接提供了有关 Azure 中 SQL 服务器中基于 DTU 的性能变化的信息。

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-service-tiers-dtu

另外,据我所知,当您选择在集群创建中不提供外部数据库时,默认配置的 Hive 元存储只是一个 S1 层数据库。这不适用于任何高容量工作负载。同时,作为最佳实践,始终将您的元存储配置到集群外部并在集群配置时附加,因为这使您可以灵活地将同一个元存储连接到多个集群(以便您的 Hive 层架构可以在多个集群之间共享)集群,例如用于 ETL 的 Hadoop 和用于处理/机器学习的 Spark),您可以随时根据需要完全控制扩展或缩减元存储。

扩展默认元存储的唯一方法是使用 Microsoft 支持。

【讨论】:

是的,在从默认元存储外部化元存储后,锁定问题得到缓解。由于在元存储方面防止了节流,因此性能也得到了巨大的提升。【参考方案3】:

我们在 HDINSIGHT 中遇到了同样的问题。我们通过升级 Metastore 解决了这个问题。 默认元存储只有 5 个 DTU,不建议用于生产环境。因此,我们迁移到自定义 Metastore 并旋转 Azure SQL SERVER(P2 高于 250 DTU)并设置以下属性:

hive.direct.sql.max.elements.values.clause=200
hive.direct.sql.max.elements.in.clause=200

设置了以上值是因为 SQL SERVER 无法处理超过 2100 个参数。当您的分区超过 348 个时,您会遇到此问题,因为 1 个分区会为 Metastore 8 x 348 创建 8 个参数

【讨论】:

以上是关于错误:失败:获取锁时出错:与元存储 org.apache.hadoop.hive.ql.lockmgr.LockException 通信时出错的主要内容,如果未能解决你的问题,请参考以下文章

无法对表运行任何查询

Terraform:获取状态锁时出错:ConditionalCheckFailedException

地形:获取状态锁时出错:ConditionalCheckFailedException

29 异常处理与元类

出错处理- 错误码-错误检查

使用 Julia 将 in() 与元组数组一起使用时出错