Hive 데이터 경사 총화

6793 단어
전송:http://www.tbdata.org/archives/2109
몇 가지 비교적 특별한 점 을 모두 언급 하 였 으 니 여러분 은 참고 하 셔 도 됩 니 다.
Shuffle 단계 의 최적화 과정 에서 데이터 경사 문제 에 부 딪 혀 일부 상황 에서 최적화 효과 가 현저 하지 않다.주로 Job 이 완 성 된 후에 얻 은 Counters 는 전체 Job 의 총화 이 고 최 적 화 는 이러한 Counters 를 바탕 으로 얻 은 평균 값 이 며 데이터 가 기울어 진 원인 으로 인해 map 처리 데이터 양의 차이 가 너무 커서 이러한 평균 값 이 대표 하 는 가 치 를 낮 출 수 있 기 때문이다.Hive 의 실행 은 단계별 입 니 다. map 처리 데이터 양의 차 이 는 이전 stage 의 reduce 출력 에 달 려 있 기 때문에 데 이 터 를 각 reduce 에 어떻게 골 고루 배분 하 는 지 하 는 것 이 데이터 의 기울 기 를 해결 하 는 근본 입 니 다.오 류 를 피 하 는 것 이 오 류 를 해결 하 는 것 보다 더 효율 적 이다.몇 가지 자 료 를 살 펴 본 후에 총 결 은 다음 과 같다.
1 데이터 가 기울어 진 원인
1.1 동작:
키워드
정황
결과
Join
그 중 하 나 는 시계 가 작 지만 키 는 집중 합 니 다.
어떤 하나 또는 몇 개의 Reduce 에 배 포 된 데 이 터 는 평균치 보다 훨씬 높다.
큰 표 와 큰 표 이지 만 통 의 판단 필드 0 값 이나 빈 값 이 너무 많 습 니 다.
이 빈 값 들 은 모두 reduce 로 처리 되 며, 회색 은 항상 느리다.
group by
group by 차원 이 너무 작고 특정한 값 의 수량 이 너무 많 습 니 다.
어떤 값 의 reduce 회색 을 처리 하 는 데 시간 이 오래 걸 립 니 다.
Count Distinct
어떤 특수 치가 너무 많다.
이 특수 값 의 reduce 를 처리 하 는 데 걸 리 는 시간
1.2 원인:
1) 키 분포 불 균형
2) 업무 데이터 자체 의 특성
3) 、 시 계 를 작성 할 때 주밀 하 게 고려 하지 않 는 다
4) 일부 SQL 문장 자체 에 데이터 경사 가 있 음
1.3 표현:
작업 진 도 는 99% (또는 100%) 로 장시간 유지 되 고 작업 모니터링 페이지 를 보면 소량의 (1 개 또는 몇 개) reduce 서브 작업 만 완성 되 지 않 았 음 을 발견 합 니 다.처리 한 데이터 양 과 다른 reduce 의 차이 가 너무 크기 때문이다.
단일 reduce 의 기록 수 와 평균 기록 수의 차이 가 너무 커서 보통 3 배, 심지어 더 많 을 수 있다.최 장 시간 은 평균 시간 보다 길다.
2 데이터 경사 해결 방안
2.1 매개 변수 조절:
hive.map.aggr = true
지도 단 부분 집합, Combiner 에 해당
hive.groupby.skewindata=true
데이터 가 기울 어 졌 을 때 부하 균형 을 맞 추고, 옵션 이 true 로 설정 되면 생 성 된 조회 계획 은 MR Job 2 개가 된다.첫 번 째 MR Job 에서 Map 의 출력 결과 집합 은 무 작위 로 Reduce 에 분포 되 고 각 Reduce 는 부분 적 인 취 합 작업 을 하 며 결 과 를 출력 한다. 이렇게 처리 한 결 과 는 같은 Group By Key 가 서로 다른 Reduce 에 배 포 돼 부하 균형의 목적 을 달성 할 수 있다.두 번 째 MR Job 은 미리 처 리 된 데이터 결과 에 따라 Group By Key 에 따라 Reduce 에 분포 한다 (이 과정 에서 같은 Group By Key 가 같은 Reduce 에 분포 되 는 것 을 보장 할 수 있다).
2.2 SQL 구문 조절:
어떻게 가입 합 니까:
구동 표 에 대한 선택 은 join key 분포 가 가장 고 른 시 계 를 구동 표 로 사용 합 니 다.
열 재단 과 filter 작업 을 잘 하여 두 표 가 join 을 할 때 데이터 양 이 상대 적 으로 작 아 지 는 효 과 를 얻 을 수 있 습 니 다.
크기 표 Join:
맵 join 을 사용 하여 작은 차원 표 (1000 개 이하 의 기록 항목 수) 를 선진 메모리 로 만 듭 니 다.맵 끝 에 reduce 를 완성 합 니 다.
큰 시계 Join 큰 시계:
빈 값 의 key 를 문자열 에 무 작위 수 를 더 하여 경사 진 데 이 터 를 서로 다른 reduce 에 나 누 었 습 니 다. null 값 이 연결 되 지 않 아 처리 후 최종 결과 에 영향 을 주지 않 습 니 다.
count distinct 대량 동일 특수 값
count distinct 시 값 이 비어 있 는 상황 을 단독으로 처리 합 니 다. count distinct 를 계산 하 는 경우 처리 하지 않 고 직접 여과 하여 마지막 결과 에 1 을 추가 할 수 있 습 니 다.다른 계산 이 있 으 면 group by 를 진행 해 야 합 니 다. 먼저 값 이 비어 있 는 기록 을 따로 처리 한 다음 다른 계산 결과 와 유 니 온 을 진행 할 수 있 습 니 다.
group by 차원 이 너무 작 음:
sum () group by 방식 으로 count (distinct) 를 교체 하여 계산 을 완성 합 니 다.
특수 상황 특수 처리:
업무 논리 최적화 효과 가 크 지 않 은 상황 에서 어떤 때 는 기울어 진 데 이 터 를 단독으로 꺼 내 처리 할 수 있다.마지막 으로 유 니 온 돌아 가.
3 전형 적 인 업무 장면
3.1 빈 값 이 발생 하 는 데이터 경사
장면: 예 를 들 어 로그 에서 정 보 를 잃 어 버 리 는 문제 가 자주 있 습 니 다. 예 를 들 어 로그 의 userid, 그 중의 user 를 가 져 오 면id 와 사용자 테이블 의 userid 관련, 데이터 경사 문제 에 부 딪 힐 수 있 습 니 다.
해결 방법 1: user_id 가 비어 있 으 면 연결 에 참여 하지 않 습 니 다 (빨간색 글꼴 은 수정 후)
select * from log a
  join users b
  on a.user_id is not null
  and a.user_id = b.user_id
union all
select * from log a
  where a.user_id is null;
 
해결 방법 2: 빈 값 을 새로운 key 값 으로 나 눕 니 다.
select *
  from log a
  left outer join users b
  on case when a.user_id is null then concat(‘hive’,rand() ) else a.user_id end = b.user_id;
 
결론: 방법 2 는 방법 1 보다 효율 이 좋 고 io 가 적 을 뿐만 아니 라 작업 수도 적다.해결 방법 1 에서 log 를 두 번 읽 고 jobs 는 2 입 니 다.해결 방법 2 job 수 는 1.이 최 적 화 는 무효 id (예 를 들 어 - 99, ', null 등) 가 발생 하 는 경사 문제 에 적합 합 니 다.빈 값 의 key 를 문자열 에 무 작위 수 를 더 하면 경사 진 데 이 터 를 서로 다른 reduce 에 나 누 어 데이터 경사 문 제 를 해결 할 수 있 습 니 다.
3.2 서로 다른 데이터 유형 관련 데이터 경사 발생
필드: 사용자 테이블 의 userid 필드 는 int, log 표 의 userid 필드 는 string 형식 도 있 고 int 형식 도 있 습 니 다.userid 가 두 표 의 Join 작업 을 진행 할 때 기본 Hash 작업 은 int 형의 id 에 따라 분 배 됩 니 다. 그러면 모든 string 형식의 id 기록 이 하나의 Reducer 에 분 배 됩 니 다.
해결 방법: 숫자 형식 을 문자열 형식 으로 변환 합 니 다.
select * from users a
  left outer join logs b
  on a.usr_id = cast(b.user_id as string)
 
3.3 작은 시계 가 작 지 않 고 크 지 않 은 데 map join 으로 경사 문 제 를 어떻게 해결 합 니까?
맵 join 을 사용 하여 작은 표 (기록 수가 적 음) 와 관련 된 큰 표 의 데이터 경사 문 제 를 해결 합 니 다. 이 방법 은 사용 빈도 가 매우 높 지만 작은 표 가 크 면 맵 join 에 bug 나 이상 이 생 길 수 있 으 므 로 특별한 처리 가 필요 합 니 다. 다음 예:
select * from log a
  left outer join users b
  on a.user_id = b.user_id;
 
users 표 는 600 w + 의 기록 이 있 고 users 를 모든 map 에 나 누 어 주 는 것 도 적지 않 은 비용 이 며 map join 은 이렇게 큰 시 계 를 지원 하지 않 습 니 다.일반적인 join 을 사용 하면 데이터 가 기울어 지 는 문제 에 부 딪 힐 수 있다.
해결 방법:
select /*+mapjoin(x)*/* from log a
  left outer join (
    select  /*+mapjoin(c)*/d.*
      from ( select distinct user_id from log ) c
      join users d
      on c.user_id = d.user_id
    ) x
  on a.user_id = b.user_id;
 
만약, log 에 userid 가 수백 만 개 에 달 하 는데 이것 은 다시 원래 의 맵 join 문제 로 돌아간다.다행히 매일 회원 uv 가 많 지 않 고 거래 하 는 회원 이 많 지 않 으 며 클릭 하 는 회원 이 많 지 않 고 커미션 이 있 는 회원 이 많 지 않 습 니 다.그래서 이 방법 은 많은 장면 에서 데이터 경사 문 제 를 해결 할 수 있다.
총화
맵 의 출력 데 이 터 를 reduce 에 고 르 게 분포 시 키 는 것 이 우리 의 최종 목표 입 니 다.Hash 알고리즘 의 한계 로 인해 key Hash 를 누 르 면 데이터 가 많 거나 적 게 기울어 집 니 다.대량의 경험 은 데이터 가 기울어 진 원인 이 인위적인 건축 표 소홀 이나 업무 논리 가 피 할 수 있 기 때 문 임 을 나타 낸다.일반적인 절 차 를 보 여 줍 니 다:
1. 샘플링 로그 시트, 어떤 userid 가 비교적 기울어져 결과 표 tmp 1 을 얻 었 습 니 다.계산 구조 에 있어 모든 데 이 터 를 오 면 그 는 데이터 분포 상황 을 모 르 기 때문에 샘플링 이 적지 않다.
2. 데이터 의 분 포 는 사회학 통계 규칙 에 부합 되 고 빈부 가 고 르 지 않다.기울어 진 키 는 많 지 않 아 요. 한 사회의 부자 가 많 지 않 고 특이 한 사람 이 많 지 않 은 것 처럼.그래서 tmp 1 기록 수가 적 을 겁 니 다.tmp 1 과 users 를 map join 으로 만 들 고 tmp 2 를 distribute file cache 에 읽 습 니 다.이것 은 맵 과정 이다.
3. map 는 users 와 log 를 읽 고 log 에서 기록 하면 user 를 검사 합 니 다.id 가 tmp 2 에 있 는 지 여부 입 니 다. 만약, 로 컬 파일 a 로 출력 하지 않 으 면 < user 생 성id, value > 의 key, value 쌍, member 에서 기록 하면 < user 생 성id, value > 의 key, value 쌍, reduce 단계 에 들 어 갑 니 다.
4. 마지막 으로 a 파일 을 Stage 3 reduce 단계 에서 출력 한 파일 을 합 쳐 hdfs 에 씁 니 다.
 
만약 에 업무 가 이렇게 기울어 진 논리 가 필요 하 다 는 것 을 확인 하면 다음 과 같은 최적화 방안 을 고려한다.
1. join 에 대해 작은 표 가 1G 보다 크 지 않다 고 판단 할 때 map join 을 사용 합 니 다.
2. group by 또는 distinct 에 대해 설정 hive.groupby.skewindata=true
3. 상기 SQL 문 구 를 사용 하여 최적화

좋은 웹페이지 즐겨찾기