Data Skew란 무엇인가
Data Skew(데이터 스큐)는 분산 처리 시스템에서 데이터가 여러 노드나 파티션에 고르게 분배되지 않고 특정 노드에 몰리는 현상을 말합니다. Spark, Hadoop, Kafka처럼 데이터를 나눠서 병렬로 처리하는 시스템은 각 노드가 비슷한 양의 작업을 처리한다는 전제 하에 성능이 최적화됩니다. 하지만 실제 데이터는 균등하지 않은 경우가 많아서, 특정 키나 값에 데이터가 집중되면 그 키를 처리하는 노드만 과부하가 걸리고 나머지 노드는 놀게 됩니다.
왜 발생하고 어떤 문제를 일으키나
예를 들어 전국 배달 주문 데이터를 지역별로 나눠서 분산 처리한다고 가정해봅시다. 서울에 주문이 70%, 나머지 지역에 30%가 분산되어 있다면, ‘서울’ 파티션을 담당하는 노드는 계속 바쁘고 다른 노드는 일찍 작업을 끝내고 기다리게 됩니다. 전체 작업 시간은 가장 늦게 끝나는 노드, 즉 서울 데이터를 처리하는 노드의 속도에 의해 결정됩니다. 이를 실무에서는 ‘long tail’ 문제라고도 부르는데, 나머지 90%의 노드가 일찍 끝나도 하나의 노드 때문에 전체 파이프라인이 지연되는 것입니다.
Spark에서는 groupByKey, join 같은 연산에서 특정 key에 데이터가 몰리면 해당 key를 처리하는 task 하나가 다른 task보다 훨씬 오래 걸리는 형태로 스큐가 나타납니다. 이 경우 executor의 메모리 부족(OOM)이나 GC 지연, 심하면 작업 실패로 이어지기도 합니다.
실무에서의 해결 방법
데이터 스큐를 완화하는 대표적인 방법은 다음과 같습니다.
- Salting: 몰리는 키에 임의의 접미사를 붙여 여러 파티션으로 인위적으로 분산시키는 기법입니다. 예를 들어 ‘서울’을 ‘서울_1’, ‘서울_2’처럼 쪼개 처리한 뒤 다시 합칩니다.
- Broadcast Join: 한쪽 데이터가 충분히 작다면 셔플 없이 각 노드에 복제해서 join 비용 자체를 없애는 방법입니다.
- 파티션 키 재설계: 스큐를 유발하는 컬럼 대신 고르게 분포된 컬럼을 파티션 기준으로 선택합니다.
- 사전 샘플링: 실제 처리 전에 데이터 분포를 미리 확인해 스큐 여부를 파악하는 것도 중요합니다.
결국 분산 처리의 성능은 ‘가장 느린 노드’가 좌우하기 때문에, 데이터 스큐를 사전에 진단하고 균형을 맞추는 작업은 대규모 데이터 파이프라인을 설계할 때 반드시 고려해야 할 요소입니다.