HADOOP

[ Hadoop ] ACID SQL Update error (Map operator initialization failed) - HIVE

Jerry_JH 2022. 7. 25. 16:49
728x90

일반 설정으로는 Hive에서 update 쿼리를 처리할 수 없다.

 

왜냐하면 Hive는 애초에 update & delete 등 데이터의 변화를 고려하지 않고 설계되었기 때문이다.

 

이것에 대한 설명은 나중에 따로 포스팅을 작성할 예정이다.

 


아무튼 ACID를 적용하면 UPDATE & DELETE 쿼리를 할 수 있다.

 

최근에 쿼리를 작성하다가. 해당 에러 때문에 구글링하는데 시간소비를 굉장히 오래했다.

 

[에러내용]

SQL Error [500051] [HY000]: [Cloudera][HiveJDBCDriver](500051) ERROR processing query/statement. Error Code: 2, SQL state: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.tez.TezTask. Vertex failed, vertexName=Map 1, vertexId=vertex_1655118886583_0438_1_01, diagnostics=[Task failed, taskId=task_1655118886583_0438_1_01_000000, diagnostics=[TaskAttempt 0 failed, info=[Error: Error while running task ( failure ) : attempt_1655118886583_0438_1_01_000000_0:java.lang.RuntimeException: java.lang.RuntimeException: Map operator initialization failed
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:296)
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:250)
	at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.run(LogicalIOProcessorRuntimeTask.java:374)
	at org.apache.tez.runtime.task.TaskRunner2Callable$1.run(TaskRunner2Callable.java:73)
	at org.apache.tez.runtime.task.TaskRunner2Callable$1.run(TaskRunner2Callable.java:61)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1729)
	at org.apache.tez.runtime.task.TaskRunner2Callable.callInternal(TaskRunner2Callable.java:61)
	at org.apache.tez.runtime.task.TaskRunner2Callable.callInternal(TaskRunner2Callable.java:37)
	at org.apache.tez.common.CallableWithNdc.call(CallableWithNdc.java:36)
	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:108)
	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:41)
	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.RuntimeException: Map operator initialization failed
	at org.apache.hadoop.hive.ql.exec.tez.MapRecordProcessor.init(MapRecordProcessor.java:354)
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:266)
	... 16 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Unexpected column vector type STRUCT
	at org.apache.hadoop.hive.ql.exec.vector.VectorCopyRow.init(VectorCopyRow.java:302)
	at org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinCommonOperator.initializeOp(VectorMapJoinCommonOperator.java:419)
	at org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinGenerateResultOperator.initializeOp(VectorMapJoinGenerateResultOperator.java:115)
	at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
	at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:573)
	at org.apache.hadoop.hive.ql.exec.Operator.initializeChildren(Operator.java:525)
	at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:386)
	at org.apache.hadoop.hive.ql.exec.tez.MapRecordProcessor.init(MapRecordProcessor.java:335)
	... 17 more
], TaskAttempt 1 failed, info=[Error: Error while running task ( failure ) : attempt_1655118886583_0438_1_01_000000_1:java.lang.RuntimeException: java.lang.RuntimeException: Map operator initialization failed
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:296)
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:250)
	at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.run(LogicalIOProcessorRuntimeTask.java:374)
	at org.apache.tez.runtime.task.TaskRunner2Callable$1.run(TaskRunner2Callable.java:73)
	at org.apache.tez.runtime.task.TaskRunner2Callable$1.run(TaskRunner2Callable.java:61)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)

 

에러 내용이 굉장히 길지만, 계속 반복되어 밑 부분은 잘랐다.

 

이 에러가 발생하게된 원인은 UPDATE 에서 문제가 있었다.

 

UPDATE CompanyA.employee
SET city='seoul'
WHERE employee_id IN (SELECT employee_id from CompanyB.employee_list)
AND city='busan'

예를 들어서 만든 쿼리이다. 전체적인 흐름은 똑같다.

WHERE IN으로 서브쿼리를 넣고, UPDATE를 진행할 때만 이 에러가 발생했다.

 

여기서 신기한 점은 이 쿼리를 조금 전환하여 

UPDATE CompanyA.employee
SET city='seoul'
WHERE employee_id IN ('AAA','BBB')
AND city='busan'

이렇게 서브쿼리를 안하거나

 

혹은

 

SELECT *
FROM CompanyA.employee
WHERE employee_id IN (SELECT employee_id from CompanyB.employee_list)
AND city='busan'

똑같은 쿼리로 UPDATE를 안하면 에러없이 잘 수행이 된다. 

 


이 에러에 대해 구글링한 결과HIVE Map join option 때문에 발생한 오류였다.

 

Map join 은 HIVE의 쿼리 속도를 향상시켜주는 옵션이라서 보통 Default 값으로 true가 되어있다.

원래 join 작업은 Map/Reduce 단계를 거쳐야되지만, 이 옵션을 이용하면 Map/Reduce 단계를 거치지 않고, mapper 내에서 join하여 table을 로드할 수 있다고 한다.

 

여기도 default 값으로 true가 들어가 있어서 join을 할 때 강제로 맵조인이 활성화되었고,

설정된 메모리 값보다 join할려고 하는 테이블의 값이 커서 발생하는 오류로 판단된다.

 

그래서

set hive.auto.convert.join = false;

이 옵션으로 맵조인을 false로 바꾸면 에러 없이 잘 된다. 

728x90