Java 由于配置单元查询错误,hadoop作业中出现错误

Java 由于配置单元查询错误,hadoop作业中出现错误,java,hadoop,hive,amazon-emr,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.MapOp

例外情况:

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";
这个数字太大,不能转换成整数吗?我甚至试着发送没有引号的
17664956244983174066
,但我得到了同样的异常

t\u id
hive表中定义为
BIGINT
,在dynamobd中定义为
N
或数字

编辑:

我尝试将
t\u id
定义为
string
==>
模式不匹配,因为dynamodb将其存储为int

t\u id
as
double
==>
精度丢失。不匹配。

这里的解决方案是什么

这个数字太大,不能转换成整数吗

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

下面是一个普通的配置单元查询(无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
,您仍然无法成功转换。

您的数字超出了bigint的范围。
将所有内容定义为两边的字符串。

根据,十进制类型适用于您

配置单元中的十进制类型与Java的大十进制格式相同。它用于表示不可变的任意精度。语法和示例如下所示:


我没有使用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";
根据我的经验,这应该可以避免强制转换输入,但是您可能会在新表中插入异常,您可以在选择期间强制转换字段,如果列太多,您也可以尝试此操作


AWS专家的解决方案是

  • git clone开源emr dynamodb连接器
  • 修改代码
  • 准备你自己的罐子
  • 使用引导程序将其上载到EMR
  • 在run_job_flow中,发送
    hadoop env
    的配置,并在
    hadoop_CLASSPATH
    中附加您自己的jar位置

  • 由于不太了解Java,修改emr dynamodb连接器对我来说是不可能的,但这就是解决方案。还有两件事可以做。。。如果在Dynamodb中不使用
    字符串
    ,请将
    蜂巢的
    字符串
    映射到Dynamodb的
    编号
    ,否则,添加映射并支持从hive到Dynamodb的
    十进制
    数字

    ,将其转换为
    1.7664956244983173e+19
    ,搜索结果变为0。是否有其他方法或options@vks,我不知道你所说的“搜索结果变为0”是什么意思。这是否意味着您需要对值进行相等匹配?如果是这样,那么切换到十进制值的模糊匹配是否可以接受,比如
    X和Y之间的值在哪里
    ?不幸的是,对于在配置单元查询中使用大于8字节的整数值,我没有进一步的建议。有可能阻止源数据中出现如此大的值吗?没有可能阻止大的值:(@vks,不用担心!谢谢你的提示。
    t\u id
    t\u ts
    的数据类型是什么?@dududumarkovitz-BIGINT-in-Hive………中的数字dynamodb@WestonE有什么想法吗?我不能那样做(…无法更改表,但Amazon EMR dynamodb连接器不接受十进制数据类型在git上也对其发出开放功能请求,因此在转换为双精度时不起作用…检查EMR dynamodb连接器代码…因此降低了精度
    INSERT OVERWRITE TABLE temp_1 
    SELECT * FROM temp_2 
    WHERE cast(t_id as string)="17664956244983174066" and cast(t_ts as string)="636214684577250000000";