복붙노트

[HADOOP] 하이브에서 OutOfMemoryError를 피하는보다 효율적인 쿼리

HADOOP

하이브에서 OutOfMemoryError를 피하는보다 효율적인 쿼리

java.lang.OutOfMemoryError : GC 오버 헤드 한계가 Hive에서 초과되었습니다. 검색에서 나는 프로세스의 모든 CPU 시간 중 98 %가 가비지 수집 (그게 무엇을 의미하든간에) 할 것이기 때문에 그 사실을 발견했습니다. 내 질문의 핵심은 내 질문에 있습니까? 이런 종류의 문제를 피하기 위해 아래에 다른 방법으로 작성해야합니까?

나는 특정 전화 유형 중 얼마나 많은 사람들이 주어진 기간에 활성 '사용'을하는지 계산하려고 노력 중이다. 이 논리를 다르게 할 수있는 방법이 있습니까? 더 잘 돌아갈 수 있습니까?

select count(a.imei)
from
(Select distinct imei
from pingdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
and ((SUBSTR(imei,12,2) = "04") or (SUBSTR(imei,12,2) = "05")) ) a
join
(SELECT distinct imei
FROM eventdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
AND event = "Use" AND clientversion like '3.2%') b
on a.imei=b.imei

고맙습니다

해결법

  1. ==============================

    1.모든 것은 귀하의 데이터에 달려 있습니다. 데이터 세트에 imei가 같은 행이 너무 많으면 조인 전에 distinct를 적용하는 것이 조인 후에 count (distinct)를 적용하는 것보다 낫습니다 (이 경우에는 올바르게 작성했습니다). 그리고 그 반대의 경우 : 같은 imei를 가진 반복되는 행이 거의 없다면 먼저 그것들에 합류 할 수 있습니다. 데이터 세트에 합치기 전에 각 데이터 세트에 고유 한 것을 적용하면 데이터에 따라 속도가 느려질 수 있습니다. where_date (timestamp) 필드 (yyyy-mm-dd)를 사용하여 데이터 집합을 분할하여 where 절에 따라 파티션 정리 작업을 수행하도록 권장합니다 (작동 확인). 데이터 세트가 너무 크고 이벤트 <> '사용'인 많은 데이터를 포함하는 경우 이벤트 필드별로도 분할합니다.

    모든 것은 귀하의 데이터에 달려 있습니다. 데이터 세트에 imei가 같은 행이 너무 많으면 조인 전에 distinct를 적용하는 것이 조인 후에 count (distinct)를 적용하는 것보다 낫습니다 (이 경우에는 올바르게 작성했습니다). 그리고 그 반대의 경우 : 같은 imei를 가진 반복되는 행이 거의 없다면 먼저 그것들에 합류 할 수 있습니다. 데이터 세트에 합치기 전에 각 데이터 세트에 고유 한 것을 적용하면 데이터에 따라 속도가 느려질 수 있습니다. where_date (timestamp) 필드 (yyyy-mm-dd)를 사용하여 데이터 집합을 분할하여 where 절에 따라 파티션 정리 작업을 수행하도록 권장합니다 (작동 확인). 데이터 세트가 너무 크고 이벤트 <> '사용'인 많은 데이터를 포함하는 경우 이벤트 필드별로도 분할합니다.

    실패한 단계를 아는 것이 중요합니다. 예외도 연구하십시오. 맵퍼에서 오류가 발생하면 하위 쿼리를 최적화해야합니다 (위에서 설명한대로 파티션을 추가하십시오). 감속기 (조인)에 실패하면 어떻게 든 조인을 개선해야합니다 (감속기 당 바이트를 줄이기 위해 시도하십시오 :

    hive.exec.reducers.bytes.per.reducer = 67108864를 설정하십시오. (OrcWriter는 imei의 substr에 의해 Output 테이블에 파티션을 추가하고 질의 끝에 substr (imei ...)에 의해 배포하여 reducer의 압력을 줄이기 위해) 파티션에 추가하려고합니다.

    또는 무작위를 추가하여 더 많은 감속기 사이에 데이터를 균등하게 분배하십시오. substr (imei ...)로 배포, FLOOR (RAND () * 100.0) % 20

  2. ==============================

    2.성능을 향상 시키려면 쿼리를보고 하이브 테이블을 yyyy, mm, dd 또는 imei의 처음 두 자리로 분할하면 이러한 테이블과 양을 쿼리해야하는 필요성에 따라 변수를 결정해야합니다 데이터의. 하지만 저는 yyyy, mm, dd에 투표 할 것입니다. 그것은 성능 향상에 막대한 금액을 줄 것입니다. 개선 - 쿼리 - 성능 - 파티셔닝을 참조하십시오.

    성능을 향상 시키려면 쿼리를보고 하이브 테이블을 yyyy, mm, dd 또는 imei의 처음 두 자리로 분할하면 이러한 테이블과 양을 쿼리해야하는 필요성에 따라 변수를 결정해야합니다 데이터의. 하지만 저는 yyyy, mm, dd에 투표 할 것입니다. 그것은 성능 향상에 막대한 금액을 줄 것입니다. 개선 - 쿼리 - 성능 - 파티셔닝을 참조하십시오.

    그러나 지금은이 방법으로 몇 가지 개선 사항을 제공해야합니다.

    Select count(distinct(pd.imei))
    from pingdata pd join eventdata ed on pd.imei=ed.imei
    where 
    TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
    and pd.timestamp=ed.pd.timestamp
    and SUBSTR(pd.imei,12,2) in ('04','05') 
    and ed.event = 'Use' AND ed.clientversion like '3.2%';
    

    같은 날짜에 TO_DATE (타임 스탬프) 값이 삽입 된 경우, 즉 두 값이 모두 날짜와 같고 pd.timestamp = ed.pd.timestamp 조건을 제외해야하는 경우

    Select count(distinct(pd.imei))
    from pingdata pd join eventdata ed on pd.imei=ed.imei
    where 
    TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
    and SUBSTR(pd.imei,12,2) in ('04','05') 
    and ed.event = 'Use' AND ed.clientversion like '3.2%';
    

    두 쿼리를 모두 실행하고 결과를 비교해보십시오. 차이점을 알리고 도움이되는 경우 알려주십시오.

  3. from https://stackoverflow.com/questions/38468802/more-efficient-query-to-avoid-outofmemoryerror-in-hive by cc-by-sa and MIT license