2012-07-08 2 views
9

약 30 열 및 약 400,000 레코드를 선택하고 다른 테이블에 삽입하는 하이브 쿼리가 있습니다. 내 SQL 절에 하나의 조인이 있습니다.이 조인은 내부 조인입니다.성능 튜닝 하이브 쿼리

Java GC 오버 헤드 제한을 초과하여 쿼리가 실패합니다.

이상한 점은 조인 절을 제거하고 테이블에서 데이터를 선택하면 (약간 큰 볼륨) 쿼리가 올바르게 작동한다는 것입니다.

저는 하이브를 아주 좋아합니다. 이 조인이 메모리 예외를 일으키는 이유를 이해할 수 없습니다.

이러한 문제가 발생하지 않도록 Hive 쿼리를 작성하는 방법에 대해 알고 있어야하는 것이 있습니까? 누구나 조인이이 문제를 일으킬 수있는 이유를 설명 할 수 있지만 더 많은 양의 데이터를 선택하고 동일한 수의 열을 선택하지 않아도됩니다.

감사합니다. 감사합니다.

답변

6

응답 마크에 많은 감사드립니다. 매우 감사.

많은 시간이 지나자 결국 join 문에서 테이블의 순서가 차이가 있음을 알았습니다. 최적의 성능 및 메모리 관리를 위해서는 마지막 조인이 가장 큰 테이블이어야합니다.

조인문에서 내 테이블의 순서를 변경하면 문제가 해결되었습니다.

은 위의 설명뿐만 아니라 매우 유용 http://hive.apache.org/docs/r0.9.0/language_manual/joins.html

에서 마지막 최대의 표를 참조하십시오. 많은 감사

+5

정말로 해결책은 아니지만 정답에 대한 감사 인 자신의 솔루션을 수락하는 대신 자신의 솔루션에 동의하는 경우 이봐, Mark Grover의 대답을 받아 들여야합니다. 위의 덧글에 –

+0

+1. 하지만 그는 새로 입사 한 이래로 상황이 어떻게 작동하는지 깨닫지 못했을 것입니다. –

34

하이브 버전 및 구성에 따라 질문에 대한 답변이 다를 수 있습니다. 두 테이블의 create 문 및 크기 추정과 함께 정확한 쿼리를 공유하는 것이 더 쉬울 것입니다.

문제를 더 잘 이해하기 위해 하이브에서 "일반"내부 조인이 어떻게 작동하는지 살펴 보겠습니다.

하이브 MapReduce에 조인 : 여기

는 MapReduce를 컴파일 도착 내측이 하이브에 참여하는 방법의 간략한 설명이다. 일반적으로 같은 조인 쿼리에 두 개의 테이블 T1과 T2가있는 경우 :

, T1은 다음과 같은 내용을 가지고
SELECT 
    t1.key, t1.value, t2.value 
FROM 
    t1 
    JOIN 
    t2 (ON t1.key = t2.key); 

:

, T2는 다음과 같은 내용이있다
k_1 v1_1 
k_2 v1_2 
k_3 v1_3  

:

k_2 v2_2 
k_3 v2_3 
k_4 v2_4  

우리는 결과가 될 결합 기대

k_2 v1_2 v2_2 
k_3 v1_3 v2_3 
,

테이블이 HDFS에 저장된다고 가정하면 그 내용이 파일 분할로 나뉩니다. 매퍼는 파일 분할을 입력으로 가져와 키를 테이블의 키 열로 내보내고 값을 테이블의 값 열과 플래그 (레코드가 어떤 테이블을 나타내는지 즉 t1 또는 t2)와 합성합니다. . t2로

k_1, <v1_1, t1> 
k_2, <v1_2, t1> 
k_3, <v1_3, t1> 

:

k_2, <v2_2, t2> 
k_3, <v2_3, t2> 
k_4, <v2_4, t2> 

지금,이 방출되는 레코드가 동일한 키를 사용하여 모든 레코드 그룹화 및 전송 된 셔플 위상 통과 T1 들어

감속기. 각 reduce 작업의 컨텍스트는 하나의 키와 해당 키에 해당하는 모든 값을 포함하는 목록입니다. 실제로, 하나의 감속기는 여러 개의 감속 작업을 수행합니다.위의 예에서

, 우리는 다음과 같은 그룹을 얻을 것입니다 :

여기
k_1, <<v1_1, t1>> 
k_2, <<v1_2, t1>, <v2_2, t2>> 
k_3, <<v1_3, t1>, <v2_3, t2>> 
k_4, <<v2_4, t2>> 

은 감속기에서 일어나는 것입니다. 값 목록의 각 값에 대해 값이 다른 테이블에 해당하면 감속기가 곱하기를 수행합니다.

k_1의 경우 t2의 값이없고 아무 것도 방출되지 않습니다.

k_2 들어, 값의 승산이 방출 - k_2, v1_2, v2_2 (각 표에서 하나 개의 값이 존재하기 때문에, 1 × 1 = 1)

k_3 들어, 값의 승산은 방사 - k_3, v1_3 , v2_3 (각 테이블마다 하나의 값이 있기 때문에 1x1 = 1)

k_4의 경우 t1의 값이없고 아무 것도 출력되지 않습니다. 따라서 내부 조인에서 예상 한 결과를 얻을 수 있습니다.

좋아, 그럼 어떻게해야합니까?

  1. 데이터에 왜곡이있을 수 있습니다. 즉, 감속기가 데이터를 가져 오는 경우 일부 키에 해당하는 값 목록이 매우 길어 오류가 발생합니다. 문제를 줄이려면 JVM에서 사용할 수있는 메모리를 늘려보십시오. href-site.xml에서 mapred.child.java.opts-Xmx512M과 같은 값으로 설정하면됩니다. Hive 셸에서 set mapred.child.java.opts;을 수행하여이 매개 변수의 현재 값을 쿼리 할 수 ​​있습니다.

  2. '정기'참여와 같은 대안을 사용해 볼 수 있습니다. 지도 조인. 위의 조인 설명은 일반 조인에 적용됩니다. 조인은 감속기에서 발생합니다. 사용중인 Hive 버전에 따라 Hive가 자동으로 일반 조인을지도 조인으로 변환 할 수 있습니다 (맵 조인에서 조인이 발생하기 때문에). 최적화를 사용하려면 hive.auto.convert.jointrue으로 설정하십시오. 이 속성은 truehive.auto.convert.join를 설정하는 것 외에도

  3. Hive 0.7에 도입 된, 당신은 또한 truehive.optimize.skewjoin를 설정할 수 있습니다. 이 문제는 1에 설명 된 데이터 문제의 비뚤어 짐을 해결합니다.