詳細検索

행동, 좁은 변환, 넓은 변환

아바타
글쓴이 Chen Ziyu
4분 읽기

행동, 좁은 변환, 넓은 변환
English에서 번역 • 원문 보기

안녕하세요! 제 이름은 쯔위 첸입니다. 저는 Colorkrew에서 풀스택 엔지니어로 일하고 있습니다. 데이터 엔지니어링에 대해 배우고 글을 쓰는 것을 좋아합니다.

오늘은 Spark에서의 전환과 행동에 대해 논의하고자 합니다. 물론, Spark의 세계에 뛰어들어 ETL 프로세스를 수행할 수 있지만, 서로 어떻게 다른지 모른 채 진행할 수 있습니다. 하지만 기존 ETL 프로세스를 최적화하거나 새로 구축하는 일을 맡게 되면, 그 차이를 이해하지 못하면 당신이 만든 ETL 프로세스의 효율성이 저해될 수 있습니다. 결국, 평범하게 설계된 비효율적인 ETL 프로세스는 조직의 운영 비용을 오히려 증가시킬 수도 있습니다. 따라서 Spark를 사용해 고성능 ETL 프로세스를 구축하고자 한다면, 전환과 행동의 본질을 철저히 이해하는 것이 필수적입니다.

먼저 변환과 액션에 대해 간단히 소개해 보겠습니다. 트랜스포메이션은 DataFrame, Datasets, 또는 RDD를 반환하는 Spark 연산으로, 이는 실제 데이터를 표현할 뿐입니다. 변환은 데이터 표현만 생성하므로 계산 자원이 적습니다. 반면, 액션은 데이터를 로드하거나 외부 저장소에 저장하는 Spark 연산입니다. 액션은 실제 데이터를 추출하고 불러오는 작업을 포함하여, 변환보다 더 많은 연산 집약적입니다. 따라서 가능한 한 액션 사용을 피하는 것이 좋습니다.

다음으로 몇 가지 예를 살펴보겠습니다. map(), filter(), intersection() 같은 메서드는 변환입니다. Map은 원래 DataFrame의 행을 변환하여 동일한 행 수를 가진 새로운 DataFrame을 반환합니다. 필터는 기준에 맞는 행을 포함하는 새로운 DataFrame을 반환합니다. Intersection은 두 DataFrame을 결합하여 두 소스 DataFrame에 모두 존재하는 행을 포함하는 새로운 DataFrame을 반환합니다. 기능상의 차이에도 불구하고, 동일한 반환 유형인 DataFrame을 공유합니다.

행동의 예로는 count(), collect(), write(와 같은 예시가 있습니다). count는 데이터프레임의 행 수를 가져옵니다. collect는 데이터프레임 내 모든 데이터를 반환합니다. write는 데이터프레임으로 표현된 데이터를 저장합니다. 이들은 모두 실제 데이터를 가져오는 과정을 포함하여, 표현보다 더 많은 시간과 연산 집약성을 가져옵니다.

img1

변환은 좁은 변환과 넓은 변환 두 가지 범주로 나눌 수 있습니다. 좁은 변환에서는 출력 데이터의 동일한 파티션 내 행을 계산하는 데 필요한 모든 행(출력 데이터프레임으로 표현됨)이 입력 데이터의 동일한 파티션(입력 데이터프레임으로 표현됨)에서 옵니다. 즉, 입력 데이터의 한 파티션에 있는 레코드는 출력 데이터의 한 파티션에만 기여합니다. 따라서 출력 데이터프레임에서 파티션 생성을 용이하게 하기 위해 데이터를 이동시킬 필요가 없으며, 이는 좁은 변환이 일반적으로 빠릅니다. 좁은 변환의 예로는 map()과 filter()가 있습니다.

하지만 와이드 변환에서는 출력 데이터의 동일한 파티션(출력 데이터프레임으로 표현됨)의 행을 계산하는 데 필요한 행들이 입력 데이터의 서로 다른 파티션(입력 데이터프레임으로 표현됨)에서 나올 수 있습니다. 즉, 입력 데이터의 한 파티션에 있는 레코드가 출력 데이터의 여러 파티션에 기여할 수 있습니다. 따라서 출력 데이터프레임에서 파티션을 생성하기 위해 Spark는 출력 데이터프레임을 생성할 때 서로 다른 노드에서 데이터를 셔플해야 할 수 있습니다. 이러한 데이터 셔플은 변환 과정에서 요구되는 추가 연산 자원을 필요로 하며, 특히 데이터 크기가 클 경우 전체 ETL 과정을 느리게 할 수 있습니다. 따라서 가능한 한 넓은 변환을 피하는 것이 최선입니다. 가장 일반적으로 사용되는 와이드 변환 중 일부는 groupByKey()와 aggregateByKey()입니다.

img2

요약하자면, 고성능 ETL 프로세스를 설계하려면 액션과 변환, 좁은 변환과 넓은 변환의 차이를 완전히 이해하는 것이 매우 중요합니다. 행동은 실제 데이터를 추출하고 로드하는 반면, 변환은 실제 데이터의 표현만 생성합니다. 따라서 행동은 변환보다 더 많은 계산 집약적이며, 필요할 때만 ETL 프로세스에 포함되어야 합니다. 좁은 변환은 데이터 셔플을 포함하지 않지만, 넓은 변환은 필요합니다. 따라서 넓은 변환을 과도하게 사용하면 ETL 프로세스의 성능이 저하될 수 있으므로 가능한 한 피해야 합니다.

ETL 프로세스를 구축할 때 이러한 차이점을 염두에 두면, 완전히 최적화된 ETL 프로세스는 더 이상 먼 꿈이 아닙니다. 이 글을 읽어주셔서 감사하며, Spark 여정에 도움이 되길 바랍니다.

Related Articles