반박시 님이 맞음. 다름이 아니라 틀림. 불통임. 비겁함.
.....
맵리듀스 또는 무슨무슨 빅데이터 처리 프레임웤에서 키뭉침은 흔하게 발생하는 일이다. 리듀스(콜렉트) 작업이 필요할 때 키뭉침은 노는 SCV를 유발한다. 1000코어를 쓰는데 999코어가 1분만에 일을 끝냈으나 1코어가 1시간이 걸리면 소요 시간은 1시간이 된다. 뭉친키 처리한다고 1코어를 쓴다.
키뭉침은 데이터 불균형 때문에 발생하기도 하지만 널값 표시자, 0, 1, 0000... 인 uuid 등 특수 값들이 필터링 되지 않고 혼입되는 경우에도 의도하지 않은 키뭉침이 발생한다.
키뭉침을 회피하는 기술은 다양하나 흔히 세컨더리 키를 쓰는 방법을 쓰는 것 같다. 나는 랜덤 키를 새로 부여해서 쓰는 편이다. 키값에 아예 랜덤키를 넣어서 1차 처리를 한 후, 2차 처리를 다시 하는 것이다. 하이브나 스파크 쿼리에서도 가능하고 distribute by 등 잘 쓰까서 노나놓고 도로 합칠 수 있다.
간단한 예를 보자.
카운트를 하는데 있어서 키 A가 1억개, 키 B가 1개인 상황이다. 나는 생각이라는 것을 모르니까 파티셔너는 해시 파티셔너 디폴트에 맡기고 당연히 리듀서 1000개 썼는데 998개가 논다. 키가 두 개 뿐이라 그렇다. 그리고 키 B를 담당하는 리듀서는 1초만에 끝나고 키 A를 담당하는 리듀서는 안 끝난다. 1억 루핑 돌고 있다. 주 120시간 일하라고 ㅆ ...
랜덤 키를 새로 부여하면 어떻게 되나. 1000개 리듀서에 골고루 배분된다. 키 A는 각 리듀서마다 대략 100,000 카운트에 끝난다. 1억을 1000으로 붐빠이하니까 그렇다.
이제 2차 처리로 다시 이전 결과 파일 1000개를 처리하여 더한다. 이때는 키 A에 대한 연산이 리듀서 1개로 몰빵될 것이다. 그러나 1차 처리에서 1억 1회의 레코드 처리를 했다면 이번엔 1000개의 레코드 처리만 하면 된다. 앞에서 1차 계산을 했으므로 1000개의 각 파일 안에는 레코드가 1개 뿐이다. (정확히는 999개의 파일에 레코드가 1개, 1개의 파일에는 키A와 키B의 값 레코드 2개)
결과는 어떻게 계산되나.
개선 전 : O(1억회)
개선 후 : O(100,000) + O(1,000)
성능향상 = 대충 990배 빠르다.
물론 실제로는 이렇게 드라마틱 하진 않다. ㅎㅎ
사실은 이 문제가 하이브에서 일빠로 지적하는 쿼리 문제인 select count (distinct 모모모) 문제와 결이 같다.