스파크(Spark)란 무엇인가?
아파치 스파크(Apache Spark)는 클러스터 환경 내에서 병렬 데이터 처리를 위해 설계된 일련의 라이브러리와 함께하는 통합 컴퓨팅 엔진입니다. 병렬 처리를 위한 가장 활발하게 개발되는 오픈소스 엔진으로서, 스파크는 빅 데이터 작업에 참여하는 개발자들과 데이터 과학자들 사이에서 표준 도구로 빠르게 부상하고 있습니다. 스파크는 파이썬, 자바, 스칼라, R과 같은 인기 있는 프로그래밍 언어와 호환되며, SQL부터 스트리밍, 머신러닝에 이르기까지 다양한 기능을 다루는 광범위한 라이브러리를 제공합니다. 스파크는 다양하게 활용될 수 있으며, 단일 노트북에서부터 수천 대의 서버로 구성된 광대한 클러스터에 이르기까지 다양한 환경에서 운영될 수 있습니다. 이러한 기능을 활용함으로써 사용자는 쉽게 빅 데이터 처리를 시작하고, 작은 설정부터 광대한 클러스터까지 원활하게 작업을 확장할 수 있습니다.
스파크 최적화 방법
1. 불필요한 셔플링(Shuffling) 줄이기
셔플링은 데이터 이동 및 노드 간 조정을 포함하기 때문에 시간과 네트워크 대역폭 측면에서 비용이 많이 드는 작업이 될 수 있습니다. 셔플링을 최소화하는 것은 스파크 애플리케이션 개발 시 성능 최적화의 주요 목표 중 하나입니다. 적절한 파티셔닝 방법을 선택하는 것, 브로드캐스트 변수 사용, 실행 계획 최적화와 같은 전략은 스파크 작업의 전반적인 성능에 대한 셔플링의 영향을 완화하는 데 도움이 될 수 있습니다.
셔플링이란?
셔플링은 분산 데이터 처리의 맥락에서 중요한 작업이며, 클러스터 내 여러 노드에 걸쳐 분산된 대규모 데이터셋을 처리할 때 아파치 스파크에서 중요한 역할을 합니다. 셔플링은 데이터를 클러스터 전체에 걸쳐 재분배하고 재구성하는 과정을 포함하는데, 이는 보통 데이터를 이전에는 그렇지 않았던 방식으로 그룹화하거나 집계해야 하는 변환 또는 작업의 결과로 발생합니다.
셔플링은 클러스터 내의 다양한 노드 간에 데이터를 이동시켜야 하기 때문에, 네트워크 대역폭과 처리 시간을 상당히 소모할 수 있으며, 이로 인해 성능 저하가 발생할 수 있습니다. 따라서, 스파크 작업을 설계하고 최적화할 때, 가능한 한 셔플링을 최소화하려는 노력이 중요합니다. 셔플링은 불가피한 경우에는 효율적으로 관리되어야 하며, 데이터 파티셔닝 전략, 캐싱, 적절한 변환 선택 등을 통해 성능 영향을 최소화할 수 있습니다.
문제를 reduceByKey를 사용하여 해결할 수 있는 경우에는 항상 reduceByKey를 사용해야 합니다. groupByKey를 사용할 때는 불가피하게 스파크의 모든 노드에 걸쳐 가장 바람직하지 않은 (하지만 가끔 피할 수 없는) 데이터 셔플링을 유발합니다. reduceByKey를 사용할 때도 데이터 셔플링이 발생하지만, 두 함수 사이의 중요한 차이점은 reduceByKey가 셔플링 전에 reduce 연산을 수행하여 네트워크를 통해 전송되는 데이터 양을 크게 줄인다는 점에 있습니다. 따라서, 셔플링 전에 데이터 크기를 줄이는 함수인 reduceByKey나 aggregateByKey와 같은 함수를 가능한 경우에 고려하는 것이 좋습니다. 같은 넓은 변환 함수라도 성능에서 상당한 차이가 있을 수 있습니다.
'groupByKey'와 'reduceByKey'의 성능을 비교하는 예는 다음과 같습니다:
DAG groupByKey vs reduceByKey:
처리 시간 비교:
2. 파티셔닝(Partitioning)
스파크 클러스터와 같은 병렬 환경에서 데이터를 적절히 파티셔닝하는 것은 매우 중요합니다. 이를 통해 각 실행기 노드가 활성 상태를 유지하고 생산적으로 작업할 수 있습니다. 잘못 파티셔닝된 데이터를 처리하는 경우, 특정 노드가 과도한 작업 부하를 지게 되는 상황이 발생할 수 있습니다. 이를 데이터 스큐라고 합니다. 프로그래머가 제어할 수 있는 상황에서는 'coalesce'나 'repartition'과 같은 함수를 사용하여 파티션 수를 조정할 수 있습니다. 그러나, 'join'과 같이 셔플링을 수반하는 작업 동안에는 프로그래머의 제어를 벗어난 시나리오가 발생할 수 있습니다. 이러한 경우, 파티션 수는 스파크 구성 파라미터 'spark.sql.shuffle.partitions'에 의해 결정됩니다. 따라서, 자주 'join' 연산을 수행하는 작업의 경우, 이 구성 값을 사전에 조정함으로써 적절한 파티션 수를 유지하는 것이 도움이 됩니다.
'coalesce'와 'repartition' 사이의 차이점을 이해하는 것이 중요합니다. 'repartition'은 전체 데이터셋을 노드 간에 균등하게 재분배하기 때문에 셔플링을 유발합니다. 이는 노드 간에 균일한 분포를 달성하기 위한 repartitioning의 본질이기 때문에 불가피합니다. 반면, 'coalesce' 함수를 사용하면 셔플링을 유발하지 않고 데이터 분포를 조정할 수 있지만, 파티션 수를 증가시킬 수는 없다는 제약이 따릅니다.
3. 올바른 데이터 구조 사용하기
스파크 2.x부터는 Dataset API 사용이 권장됩니다. Dataset의 기본 구조는 여전히 RDD이지만, Spark Catalyst 최적화와 같은 다양한 최적화를 포함하고 있으며, 훨씬 더 강력한 인터페이스를 제공합니다. 예를 들어, 고급 API를 사용하여 시간이 많이 걸리는 join 연산을 수행할 때, 최적화는 가능한 셔플링을 최소화하면서 Broadcast join과 같은 기술로 자동 전환할 수 있습니다. 따라서 가능한 한 Datasets이나 DataFrames을 사용하려고 노력하는 것이 좋습니다.
브로드캐스트 변수 사용하기 아파치 스파크에서 브로드캐스트 변수는 읽기 전용 변수를 스파크 클러스터의 노드 간에 효율적으로 공유하기 위해 사용됩니다. 각 작업에 변수의 복사본을 보내는 것은 자원 집약적이고 비효율적일 수 있기 때문에, 브로드캐스트 변수는 변수를 각 기계에 캐시하여 해당 기계에서 실행되는 작업 간에 공유할 수 있게 합니다. 이는 네트워크를 통해 전송해야 하는 데이터 양을 줄여 특정 스파크 작업의 성능을 크게 향상시킬 수 있습니다.
다음은 두 개의 데이터프레임을 조인하는 예시입니다. 첫 번째는 브로드캐스트를 사용하지 않는 경우이고, 두 번째는 브로드캐스트를 사용하는 경우입니다.
![](https://blog.kakaocdn.net/dn/winiQ/btsF0b7nHAz/opK7sOzqq23ZhACWJksOhK/img.png)
![](https://blog.kakaocdn.net/dn/ceTnKe/btsFXHtgF2C/Ipt4kxMZUTBgXaI7eQuGD1/img.png)
두 예제를 실행했을 때, 가장 큰 차이점은 브로드캐스트를 사용하는 경우 셔플링이 발생하지 않는다는 것입니다. 스파크에서 셔플링은 비용이 많이 드는 작업입니다. 브로드캐스트를 사용함으로써 불필요한 셔플링을 피해 네트워크 사용을 줄일 수 있습니다. 대규모 데이터를 처리하는 스파크에서 이러한 불필요한 네트워크 사용을 최소화하는 것은 성능을 크게 향상시킬 수 있습니다.
4. Persist Intermediate Data
아파치 스파크에서 persist()와 cache() 메소드는 DataFrame, RDD(Resilient Distributed Dataset), 또는 Dataset을 메모리나 디스크에 영속화하거나 캐시하는 데 사용됩니다. 이러한 메소드는 데이터에 접근할 때마다 데이터를 다시 계산할 필요를 피함으로써 반복적이거나 상호작용적인 스파크 작업의 성능을 개선하는 데 특히 유용합니다.
특히, 스파크의 MLlib에 흔한 반복적인 머신러닝 알고리즘은 캐싱 또는 영속화에서 큰 이점을 얻습니다. 이러한 알고리즘은 반복 동안 동일한 데이터에 반복적으로 접근하고 업데이트하기 때문에, 효율성을 위해 캐싱이 필수적입니다.
또한, 데이터가 영속화될 때, 스파크는 데이터를 내고장성을 갖도록 저장합니다. 이는 계산 중에 노드 실패가 발생하는 경우, 손실된 데이터를 원본 소스나 중간 단계에서 다시 계산할 수 있게 하여 데이터 무결성을 유지합니다.
이 예시에서는 persist() 메소드를 사용하여 DataFrame을 메모리에 캐시합니다. DataFrame에 대한 후속 작업은 캐시된 데이터의 이점을 누릴 수 있어 성능이 개선됩니다. 특정 사용 사례와 사용 가능한 리소스를 기반으로 적절한 저장 수준을 선택해야 한다는 점을 기억하세요.
'IT > Big Data' 카테고리의 다른 글
HDFS 하둡 분산 파일 시스템 (0) | 2018.09.24 |
---|---|
하둡(Hadoop) 이란? (0) | 2018.04.16 |
빅데이터란? (0) | 2018.02.25 |