簡體   English   中英

由於 hive 查詢錯誤導致 hadoop 作業出錯

[英]Error in hadoop jobs due to hive query error

例外:

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_idhive table定義為BIGINTt_id中定義為N或 Number

編輯:

我嘗試將t_id定義為string ==> Schema mismatch as dynamodb stores this as int

t_id as double ==>> precision lost. no match. precision lost. no match.

這里有什么解決方案?

這個數字太大而不能轉換為 int 嗎?

是的,這個數字太大,無法轉換為整數類型。 根據關於Numeric Types的 Apache Hive 文檔, BIGINT的最大值為 9223372036854775807。您的輸入 17664956244983174066 大於該值。

以下是一個普通的 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 ,您仍然不會成功轉換。

AWS 專家的解決方案是

  1. git clone 開源emr-dynamodb-connector
  2. 修改代碼
  3. 准備你自己的罐子
  4. 使用引導程序將其上傳到 EMR
  5. 在 run_job_flow 中,發送hadoop env配置,並在HADOOP_CLASSPATH附加您自己的 jars 位置。

對 Java 不太了解,修改 emr-dynamodb-connector 對我來說是不可能的,但這是解決方案。 另外兩件事情可以做...如果你不使用Strings中Dynamodb,地圖stringhive ,以number Dynamodb的,否則添加映射,支持decimal從蜂巢Dynamodb number

您的數字超出了 bigint 的范圍。
將所有內容定義為兩邊的字符串。

根據https://www.tutorialspoint.com/hive/hive_data_types.htm , DECIMAL 類型適合您。

Hive 中的 DECIMAL 類型與 Java 的 Big Decimal 格式相同。 它用於表示不可變的任意精度。 語法和示例如下:

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

我沒有使用過 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM