由于hive查询错误导致hadoop作业出错

时间:2017-06-21 23:26:23

标签: java hadoop hive amazon-emr

例外:

2017-06-21 22:47:49,993 FATAL ExecMapper (main): org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing writable org.apache.hadoop.dynamodb.DynamoDBItemWritable@2e17578f
    at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:643)
    at org.apache.hadoop.hive.ql.exec.ExecMapper.map(ExecMapper.java:149)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:441)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:377)
    at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1132)
    at org.apache.hadoop.mapred.Child.main(Child.java:249)
Caused by: java.lang.RuntimeException: Exception while processing record: org.apache.hadoop.dynamodb.DynamoDBItemWritable@2e17578f
    at org.apache.hadoop.hive.dynamodb.DynamoDBObjectInspector.getColumnData(DynamoDBObjectInspector.java:136)
    at org.apache.hadoop.hive.dynamodb.DynamoDBObjectInspector.getStructFieldData(DynamoDBObjectInspector.java:97)
    at org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters$StructConverter.convert(ObjectInspectorConverters.java:328)
    at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:626)
    ... 9 more
Caused by: java.lang.NumberFormatException: For input string: "17664956244983174066"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Long.parseLong(Long.java:444)
    at java.lang.Long.parseLong(Long.java:483)
    at org.apache.hadoop.hive.dynamodb.DynamoDBDataParser.getNumberObject(DynamoDBDataParser.java:179)
    at org.apache.hadoop.hive.dynamodb.type.HiveDynamoDBNumberType.getHiveData(HiveDynamoDBNumberType.java:28)
    at org.apache.hadoop.hive.dynamodb.DynamoDBObjectInspector.getColumnData(DynamoDBObjectInspector.java:128)
    ... 12 more

我发送的配置单元查询是:

INSERT OVERWRITE TABLE temp_1 
         SELECT * FROM temp_2 
         WHERE t_id="17664956244983174066" and t_ts="636214684577250000000";

这个数字太大而无法转换为int吗?我甚至尝试发送17664956244983174066没有引号,但我得到了同样的例外。

t_idBIGINThive table中定义为N或在dynamobd中定义为

编辑:

我尝试将t_id定义为string ==> Schema mismatch as dynamodb stores this as int

t_id作为double ==>> precision lost. no match.

这里有什么解决方案?

5 个答案:

答案 0 :(得分:2)

  

此数字是否太大而无法转换为int?

是的,这个数字太大,无法转换为整数类型。根据{{​​3}}上的Apache Hive文档,BIGINT的最大值为9223372036854775807.您的输入17664956244983174066大于此值。

以下是一个vanilla Hive查询(没有DynamoDB集成),演示了尝试将各种输入转换为BIGINT的效果。

SELECT
    "9223372036854775807" AS str,
    cast("9223372036854775807" AS BIGINT) AS numbigint,
    cast("9223372036854775807" AS DOUBLE) AS numdouble
UNION ALL
SELECT
    "9223372036854775808" AS str,
    cast("9223372036854775808" AS BIGINT) AS numbigint,
    cast("9223372036854775808" AS DOUBLE) AS numdouble
UNION ALL
SELECT
    "17664956244983174066" AS str,
    cast("17664956244983174066" AS BIGINT) AS numbigint,
    cast("17664956244983174066" AS DOUBLE) AS numdouble
;

    str numbigint   numdouble
0   9223372036854775807 9223372036854775807 9.2233720368547758e+18
1   9223372036854775808 NULL    9.2233720368547758e+18
2   17664956244983174066    NULL    1.7664956244983173e+19

在记录的最大值BIGINT处,值正确转换。只有1,转换失败,导致NULL。您的输入也会发生同样的事情。

该查询还表明转换为DOUBLE成功。也许这是一个解决方案,具体取决于您的使用案例。与整数数据类型相比,这将面临遇到浮点精度问题的风险。

在堆栈跟踪中,似乎DynamoDB集成导致NumberFormatException这种情况而不是NULL。这可以说是DynamoDB连接器中的一个错误,但即使它被更改为映射到NULL,您仍然无法成功转换。

答案 1 :(得分:2)

AWS人员告诉的解决方案是

  1. git clone开源emr-dynamodb-connector
  2. 修改代码
  3. 准备自己的Jar
  4. 使用bootstrapper将其上传到EMR
  5. 在run_job_flow中,发送hadoop env的配置,在HADOOP_CLASSPATH附加您自己的广告位置。
  6. 与Java不同,修改emr-dynamodb-connector对我来说是不可能的,但这是解决方案。另外还有两件事可以做......如果你在dynamodb中不使用Strings,那么map版本号string hive的{​​{1}},否则将number的映射和支持从hive添加到dynamodb decimal

答案 2 :(得分:1)

你的号码超出了bigint的范围 将所有内容定义为双方的字符串。

答案 3 :(得分:1)

根据https://www.tutorialspoint.com/hive/hive_data_types.htm,DECIMAL类型适合您。

  

Hive中的DECIMAL类型与Java的Big Decimal格式相同。它用于表示不可变的任意精度。语法和示例如下:

DECIMAL(precision, scale)
decimal(10,0)

答案 4 :(得分:1)

我没有使用EMR,但我猜这里:)

Hive会自动尝试转换您的输入,因为您的目标字段是BigInt,您是否尝试过类似的内容?

INSERT OVERWRITE TABLE temp_1 
SELECT * FROM temp_2 
WHERE cast(t_id as string)="17664956244983174066" and cast(t_ts as string)="636214684577250000000";

根据我的经验,这应该避免输入您的输入,但是您可以在新表中插入异常,您可以在选择期间投射字段,如果您有太多列,您也可以尝试这个

https://community.hortonworks.com/questions/7703/whether-hive-supports-hive-select-all-query-with-e.html