排除 HCatalog 连接器故障
使用 HCatalog 连接器时,可能会遇到以下问题。
连接错误
在定义架构和查询架构时,HCatalog 连接器都可能遇到错误。出现哪种类型的错误要看哪些 CREATE HCATALOG SCHEMA 参数是不正确的。假设您针对元存储数据库设置的参数不正确,但针对 HiveServer2 设置了正确的参数。在这种情况下,与 HCatalog 相关的系统表查询会成功,而在 HCatalog 架构上进行的查询会失败。下面的示例演示了如何使用正确的默认 HiveServer2 信息创建 HCatalog 架构。但元存储数据库的端口号是不正确的。
=> CREATE HCATALOG SCHEMA hcat2 WITH hostname='hcathost'
-> HCATALOG_SCHEMA='default' HCATALOG_USER='hive' PORT=1234;
CREATE SCHEMA
=> SELECT * FROM HCATALOG_TABLE_LIST;
-[ RECORD 1 ]------+---------------------
table_schema_id | 45035996273864536
table_schema | hcat2
hcatalog_schema | default
table_name | test
hcatalog_user_name | hive
=> SELECT * FROM hcat2.test;
ERROR 3399: Failure in UDx RPC call InvokePlanUDL(): Error in User Defined
Object [VHCatSource], error code: 0
com.vertica.sdk.UdfException: Error message is [
org.apache.hcatalog.common.HCatException : 2004 : HCatOutputFormat not
initialized, setOutput has to be called. Cause : java.io.IOException:
MetaException(message:Could not connect to meta store using any of the URIs
provided. Most recent failure: org.apache.thrift.transport.TTransportException:
java.net.ConnectException:
Connection refused
at org.apache.thrift.transport.TSocket.open(TSocket.java:185)
at org.apache.hadoop.hive.metastore.HiveMetaStoreClient.open(
HiveMetaStoreClient.java:277)
. . .
要解决这些问题,您必须删除并重新创建架构,或更改架构以更正参数。如果问题仍然存在,请确定 Vertica 群集和 Hadoop 群集之间是否存在连接性问题。此类问题可能包括能够阻止一个或多个 Vertica 主机联系 HiveServer2、元存储或 HDFS 主机的防火墙。
查询数据时 UDx 发生故障:错误 3399
查询数据(而不是架构信息等元数据)时,您可能会看到错误消息。伴随该消息的出现,日志中可能会记录一个 ClassNotFoundException。发生这种情况的原因可能如下:
-
您在 Hadoop 和 Vertica 节点上使用的 Java 版本不同。在这种情况下,您需要对其中之一进行更改,使其与另一个相匹配。
-
您还没有使用 hcatUtil 将所有的 Hadoop 和 Hive 库以及配置文件复制到 Vertica;或者您运行了 hcatutil,然后更改了您的 Hadoop 或 Hive 版本。
-
您将 Vertica 升级到了新版本,而没有重新运行 hcatutil 并重新安装 HCatalog 连接器。
-
您使用的 Hadoop 版本依赖于一个必须手动复制的第三方库。
-
您要读取使用 LZO 压缩的文件,但还没有复制库或设置
core-site.xml
中的io.compression.codecs
属性。 -
您要从 Hive 读取 Parquet 数据,且多个列在表中已经存在一些数据之后被添加到表中。添加列不会更新现有数据,Hive 提供并由 HCatalog 连接器使用的 ParquetSerDe 无法处理这种情况。此错误是由于 Hive 中的限制造成的,并且没有解决方法。
-
查询花费的时间太长并且即将超时。如果这是一个常见问题,您可以增加 UDxFencedBlockTimeout 配置参数的值。请参阅常规参数。
如果您未曾复制库或配置 LZO 压缩,请遵循为 HCatalog 配置 Vertica 中的说明。
如果您从 Hadoop 复制的 Hive jar 文件过期,您可能会看到像下面这样的错误消息。
ERROR 3399: Failure in UDx RPC call InvokePlanUDL(): Error in User Defined Object [VHCatSource],
error code: 0 Error message is [ Found interface org.apache.hadoop.mapreduce.JobContext, but
class was expected ]
HINT hive metastore service is thrift://localhost:13433 (check UDxLogs/UDxFencedProcessesJava.log
in the catalog directory for more information)
此错误通常指示 hive-hcatalog-core jar
出现问题。请确保您拥有此文件的最新副本。请记住,如果重新运行 hcatUtil,您还需要重新创建 HCatalog 架构。
您可能还会看到不同形式的此错误:
ERROR 3399: Failure in UDx RPC call InvokePlanUDL(): Error in User Defined Object [VHCatSource],
error code: 0 Error message is [ javax/servlet/Filter ]
即使 hcatUtil 报告您的库都是最新的,您仍可能收到此错误的报告。部分 Hadoop 版本会使用 javax.servlet.Filter
类所在的库,但该库通常情况下并非 Hadoop 安装的直接组成部分。如果您看到提及此类的错误,请在 Hadoop 节点上找到 servlet-api-*.jar
,然后将其复制到所有数据库节点上的 hcat/lib
目录。如果您在 Hadoop 节点上找不到它,请通过互联网查找并下载。(这种情况很少见。)库的版本必须为 2.3 或更高版本。
将该 jar 文件复制到 hcat/lib
目录后,请按照为 HCatalog 配置 Vertica 中的说明,重新安装 HCatalog 连接器。
查询数据时发生身份验证错误
您可能已经使用 CREATE HCATALOG SCHEMA 成功创建了架构,但在查询时出现如下错误:
=> SELECT * FROM hcat.clickdata;
ERROR 6776: Failed to glob [hdfs:///user/hive/warehouse/click-*.parquet]
because of error: hdfs:///user/hive/warehouse/click-12214.parquet: statAll failed;
error: AuthenticationFailed
如果 Hive 使用授权服务,您可能会看到此错误。如果 HDFS 中底层文件的权限与授权服务中的权限匹配,则 Vertica 在访问该数据时必须使用用户模拟。要启用用户模拟,请将 EnableHCatImpersonation 配置参数设置为 1。
Vertica 使用数据库主体访问 HDFS。因此,如果 EnableHCatImpersonation 为 0,则 Vertica 数据库主体必须有权访问 HDFS 上 Hive 仓库内的数据。如果无权访问,您可能会看到以下错误:
=> SELECT * FROM hcat.salesdata;
ERROR 6776: Failed to glob [vertica-hdfs:///hive/warehouse/sales/*/*]
because of error: vertica-hdfs:///hive/warehouse/sales/: listStat failed;
error: Permission denied: user=vertica, access=EXECUTE, inode="/hive/warehouse/sales":hdfs:hdfs:d---------
此错误消息中的 URL 方案已从 hdfs
更改为 vertica-hdfs
。这是一个内部方案,在 Vertica 之外的 URL 中无效。在 HDFS 中指定路径时不能使用此方案。
Hive 和 Vertica 查询的结果不一致
有些时候,通过 HCatalog 连接器在 Hive 和 Vertica 上运行相同的查询可能会返回不同的结果。这个问题有几种常见原因。
这种差异往往由 Hive 和 Vertica 支持的数据类型不同导致。有关受支持的数据类型的详细信息,请参阅从 Hive 到 Vertica 的数据类型转换。
如果 Hive 字符串的值在 Vertica 中被截断,这可能是由 Hive 中的多字节字符编码导致的。Hive 以字符为单位报告字符串长度,而 Vertica 则以字节为单位记录该长度。对于 Unicode 等两字节编码,您需要在 Vertica 中将列大小增加一倍以避免其被截断。
如果 Hive 表使用除字符串以外的其他类型的分区列,也有可能会产生差异。
如果 Hive 表将分区数据存储在自定义位置而不是默认位置,且您在创建 Vertica 架构时未指定 CUSTOM_PARTITIONS 参数,您将看到不同的查询结果。请参阅使用分区数据。此外,即使使用自定义分区,Vertica 和 Hive 之间也存在差异:
-
如果自定义分区在查询时不可用,则 Hive 将忽略它并返回其余结果。Vertica 报告错误。
-
如果在创建表后在 Hive 中更改分区以使用自定义位置,则 Hive 仅从新位置读取数据,而 Vertica 从默认位置和新位置读取数据。
-
如果分区值与其对应的目录名称不一致,Hive 将使用其元数据中的值,而 Vertica 使用目录名称中的值。
下面的示例说明了这些差异。Hive 中按状态列分区的表以下面的数据开头:
hive> select * from inventory;
+--------------+-----------------+-----------------+--+
| inventory.ID | inventory.quant | inventory.state |
+--------------+-----------------+-----------------+--+
| 2 | 300 | CA |
| 4 | 400 | CA |
| 5 | 500 | DC |
| 1 | 100 | PA |
| 2 | 200 | PA |
+--------------+-----------------+-----------------+--+
然后,移动状态为 CA 的分区。该目录已经包含一些数据。请注意,查询现在会针对 CA 分区返回不同的结果。
hive> ALTER TABLE inventory PARTITION (state='CA') SET LOCATION 'hdfs:///partitions/inventory/state=MD';
hive> select * from inventory;
+--------------+-----------------+-----------------+--+
| inventory.ID | inventory.quant | inventory.state |
+--------------+-----------------+-----------------+--+
| 20 | 30000 | CA |
| 40 | 40000 | CA |
| 5 | 500 | DC |
| 1 | 100 | PA |
| 2 | 200 | PA |
+--------------+-----------------+-----------------+--+
5 rows selected (0.399 seconds)
CA 分区已移至名为 state=MD 的目录。由于目录名称,Vertica 将前两行(新分区位置中的行)的状态报告为 MD。除了新位置之外,它还报告来自原始位置的 CA 值:
=> SELECT * FROM hcat.inventory;
ID | quant | state
----+----------+------
20 | 30000 | MD
40 | 40000 | MD
2 | 300 | CA
4 | 400 | CA
1 | 100 | PA
2 | 200 | PA
5 | 500 | DC
(7 rows)
MapR 上的 HCatalog 连接器安装失败
如果您将 MapR 文件系统挂载为 NFS 挂载点,然后安装 HCatalog 连接器,则可能会失败并显示如下消息:
ROLLBACK 2929: Couldn't create new UDx side process,
failed to get UDx side process info from zygote: Broken pipe
这可能伴随着 dbLog
中的如下错误:
java.io.IOException: Couldn't get lock for /home/dbadmin/node02_catalog/UDxLogs/UDxFencedProcessesJava.log
at java.util.logging.FileHandler.openFiles(FileHandler.java:389)
at java.util.logging.FileHandler.<init>(FileHandler.java:287)
at com.vertica.udxfence.UDxLogger.setup(UDxLogger.java:78)
at com.vertica.udxfence.UDxSideProcess.go(UDxSideProcess.java:75)
...
如果您在创建 NFS 挂载点时将其锁定,则会出现此错误。锁定是默认设置。如果您使用 HCatalog 连接器并将 MapR 挂载为 NFS 挂载点,则必须使用 -o nolock
选项创建挂载点。例如:
sudo mount -o nolock -t nfs MaprCLDBserviceHostname:/mapr/ClusterName/vertica/$(hostname -f)/ vertica
您可以将 HCatalog 连接器与 MapR 一起使用,而无需挂载 MapR 文件系统。如果您挂载 MapR 文件系统,则必须在没有锁定的情况下执行此操作。
过多的查询延迟
网络问题或 HiveServer2 服务器上的高系统负载可能会在使用 HCatalog 连接器查询 Hive 数据库时导致长时间延迟。虽然 Vertica 不能解决这些问题,但您可以设置参数,限制 Vertica 在取消 HCatalog 架构上的查询之前等待多长时间。您可以使用 Vertica 配置参数在全局范围内设置这些参数。您还可以在 CREATE HCATALOG SCHEMA 语句中针对特定的 HCatalog 架构设置这些参数。这些特定设置将覆盖配置参数中的设置。
HCatConnectionTimeout 配置参数和 CREATE HCATALOG SCHEMA 语句的 HCATALOG_CONNECTION_TIMEOUT 参数控制 HCatalog 连接器在连接到 HiveServer2 服务器时等待多少秒。值为 0(配置参数的默认设置)是指无限期地等待。如果到此超时过去后,服务器仍然没有响应,HCatalog 连接器会断开连接并取消查询。如果您发现在 HCatalog 架构上执行的某些查询暂停时间过长,请尝试将此参数设置为一个超时值,这样查询就不会无限期挂起了。
HCatSlowTransferTime 配置参数和 CREATE HCATALOG SCHEMA 语句的 HCATALOG_SLOW_TRANSFER_TIME 参数指定 HCatlog 连接器在成功连接到服务器后等待数据的时间。指定时间过去后,HCatalog 连接器将确定来自服务器的数据传输速度是否达到了在 HCatSlowTransferLimit 配置参数中(或通过 CREATE HCATALOG SCHEMA 语句的 HCATALOG_SLOW_TRANSFER_LIMIT 参数)设置的值。如果没有达到,那么 HCatalog 连接器将终止连接并取消查询。
您可以设置这些参数,以取消运行非常缓慢但最终确实可以完成的查询。然而,导致查询延迟的原因通常是连接缓慢而不是无法建立连接。因此,请先尝试调整缓慢的传输速度设置。如果您发现导致问题的原因是连接永远都无法完成,您还可以将 Linux TCP 套接字超时调整为合适的值,而不是完全依赖于 HCatConnectionTimeout 参数。
SerDe 错误
如果您尝试查询使用非标准 SerDe 的 Hive 表,可能会发生错误。如果您尚未在 Vertica 群集上安装 SerDe JAR 文件,您将收到与以下示例中类似的错误消息:
=> SELECT * FROM hcat.jsontable;
ERROR 3399: Failure in UDx RPC call InvokePlanUDL(): Error in User Defined
Object [VHCatSource], error code: 0
com.vertica.sdk.UdfException: Error message is [
org.apache.hcatalog.common.HCatException : 2004 : HCatOutputFormat not
initialized, setOutput has to be called. Cause : java.io.IOException:
java.lang.RuntimeException:
MetaException(message:org.apache.hadoop.hive.serde2.SerDeException
SerDe com.cloudera.hive.serde.JSONSerDe does not exist) ] HINT If error
message is not descriptive or local, may be we cannot read metadata from hive
metastore service thrift://hcathost:9083 or HDFS namenode (check
UDxLogs/UDxFencedProcessesJava.log in the catalog directory for more information)
at com.vertica.hcatalogudl.HCatalogSplitsNoOpSourceFactory
.plan(HCatalogSplitsNoOpSourceFactory.java:98)
at com.vertica.udxfence.UDxExecContext.planUDSource(UDxExecContext.java:898)
. . .
您可在错误消息中看到,出错的根本原因是缺少一个 SerDe 类(以粗体显示)。要解决此问题,请在 Vertica 群集上安装 SerDe 类。有关详细信息,请参阅使用非标准 SerDes。
如果群集中仅一个或少量主机没有 SerDe 类,此错误可能会间歇性出现。