[BigData] (작성중) 데이터 과학자를 위한 Pyspark 튜토리얼
인-메모리 기반 분산 처리로 대용량 데이터를 빠르게 조작/분석할 수 있는 툴인 Pyspark에 대해 알아봅니다.
2억 줄짜리 테이블을, Pandas로 언제 분석해!
Contents
- 들어가며 - Pyspark과 친해지길 바라
- Pyspark 개요 - 따분하지만 중요한 밑그림
- Pyspark 전처리 1 - 간단한 DF 조작과 결측치 처리
- Pyspark 전처리 2 - Groupby 함수
- Pyspark MLlib으로 머신러닝 모델 학습하기
1. 들어가며 - Pyspark과 친해지길 바라
입사 전: Spark? 그걸 왜 쓰지 ㅋㅋ 그냥 Pandas로 뚝딱뚝딱 하면 되는데!
입사 후: 아니 로우가 2억개..? 한번 돌리는데 2시간..? 연산 끝나니 퇴근시간..?
현재 재직 중인 카드사에서는 다양하고 방대한 결제 정보 데이터가 축적되고 있습니다. 무슨 이런 데이터가 죄다 있지..? 싶을 정도로, 예전에는 생각하기 어려운 양의 데이터를 매일 만지고 있는데요.
입사 후에 가장 어려운 점이 이 대용량 데이터를 전처리하고 조작하는 작업을 위해 Pyspark를 배워야한다는 점이었습니다.
Pandas에 익숙해진 저와 동료들은 레거시 코드를 보면서 한참을 고통받았더랬죠. 이건 왜 이렇게 짜여 있는거지..? 이건 뭐하는 함수지? 그때마다 느꼈던 건.. Pandas는 정말로 친절한 친구였습니다.
하지만 조금씩 Pyspark이라는 친구를 알아가면서, 이 친구와 친해지면 얼마나 편해질 수 있는지 피부로 와닿기 시작했습니다. Pandas로 한참이 걸리던 연산이 Pyspark로 뿅! 하고 해결되는 것을 보고 너.. 생각보다 좋은 아이였구나? 하는 긍정적인 감정이 쌓이다 보니 이 친구를 더 알아가고 싶더라구요.
오늘은 저처럼 Pandas에 익숙한 분석가가 Pyspark를 쉽게 이해하고 다룰 수 있도록 설명하는 포스트를 준비해 보았습니다.
2. Pyspark 개요 - 따분하지만 중요한 밑그림, spark의 작동 방식
Pyspark의 핵심에는 Spark의 고유한 아키텍처가 있습니다. 이 아키텍처를 이해하는 것은 다소 까다롭기는 하지만 효율적인 전처리와 데이터 조작을 위해서 꼭 필요한 부분입니다. (저를 비롯한) 대부분의 데이터 사이언티스트들이 익숙하지 않은 종류의 이야기이기도 하구요.
1) Pyspark의 연산 workflow
Pyspark 아키텍처의 핵심 구성 요소
전체 흐름을 살피기 앞서, 스파크의 아키텍처를 구성하는 아래의 세 구성 요소를 살펴보겠습니다.
드라이버 노드(Driver Program): 메인 어플리케이션이 실행되는 곳입니다. 워커 노드에서 작업을 오케스트레이션(관현악단을 지휘하듯이 전체 프로세스를 관리) 및 실행하고 연산 결과를 반환하는 역할을 담당합니다.
워커 노드(Worker node): 이 노드는 스파크 연산 워크플로우에서 실제로 손발이 되어 일하는 주체입니다. 즉, 드라이버 노드가 뿌린 작업을 실제로 실행합니다. 각 워커 노드는 로컬 데이터로 작업하고 계산한 결과를 드라이버 노드에 전달합니다.
클러스터 관리자: 클러스터의 리소스 획득을 담당하는 외부 서비스입니다. Spark는 독립형, Mesos, YARN 등 여러 클러스터 관리자를 지원합니다.
스파크에서 연산이 일어나는 Workflow를 정리하면 아래와 같습니다.
1) 유저가 Spark 어플리케이션을 실행합니다. 즉, 파이스파크의 코드를 유저가 실행합니다.
2) 드라이버 프로그램이 클러스터 관리자와 협력하여 리소스를 할당합니다.
3) 리소스가 할당되면 작업은 실행을 위해 워커 노드로 전송됩니다.
4) 워커 노드는 로컬에서 데이터를 처리하고 결과를 다시 드라이버 노드로 전송합니다.
5) 모든 작업이 완료되면 결과가 사용자에게 반환됩니다.
2) 드라이버 프로그램의 파이썬 환경 구성
pyspark를 사용하다보면 UDF(user defined function), 즉 사용자 지정 함수를 사용하는 연산에서 흔히 문제가 발생합니다. 이를 해결하기 위해서는 파이썬 환경이 구성되는 과정을 이해하는 것이 필요한데요.
드라이버 프로그램: 스파크 애플리케이션을 제출하면 드라이버 프로그램이라는 프로세스가 시작됩니다. 이 프로그램은 주요 함수를 실행하고 SparkContext를 생성합니다. SparkContext는 작업을 조정하고 애플리케이션의 전체 상태를 추적합니다.
파이썬 환경 구성: 드라이버 프로그램은 또한 Spark용 Python 환경이 올바르게 구성되었는지 확인합니다. 이는 다음을 의미합니다:
사용할 Python 실행 파일을 지정하기 위해 PYSPARK_PYTHON과 같은 환경 변수를 설정합니다. Python 라이브러리 및 종속성이 모든 노드에 올바르게 설치되어 있고 사용 가능한지 확인합니다. 클러스터 전체에서 일관성을 보장하기 위해 필요한 Python 파일과 종속성을 워커 노드에 브로드캐스트합니다.
3) 스파크가 인메모리 컴퓨팅이라 불리는 이유
Hadoop의 MapReduce와 같은 기존의 빅 데이터 도구는 디스크에서 자주 읽고 쓰기를 반복하기 때문에 지연 시간이 길어집니다. 하지만 Spark는 메모리를 사용해 계산을 최적화합니다. Spark는 디스크에 자주 읽고 쓰는 대신 RAM에 데이터를 저장함으로써 데이터 처리 작업의 속도를 크게 높입니다. 이렇게 메모리를 활용하여 처리하는 방법을 “인메모리 컴퓨팅”이라고 합니다. 메모리가 부족할 경우 Spark는 디스크로 넘어갈 수 있지만, 기본 작동 모드는 인메모리이므로 성능 우위를 확보할 수 있습니다.
4) 스파크 속도의 비결
Spark의 빠른 데이터 처리 기능에는 몇 가지 이유가 있습니다:
인메모리 컴퓨팅: 앞서 언급했듯이 중간 데이터를 메모리(RAM)에 저장하면 I/O 작업에 걸리는 시간이 줄어듭니다.
최적화된 실행 계획: Spark는 카탈리스트 옵티마이저를 사용하여 작업 실행 방법을 지능적으로 계획하여 중복 작업을 최소화합니다.
지연 평가: Spark 작업은 느리게 평가되므로 변환이 즉시 실행되지 않습니다. 대신, Spark는 논리적 실행 계획을 수립하고 작업(예: count 또는 saveAsTextFile)이 호출될 때만 작동합니다. 이를 통해 Spark는 전체 워크플로를 최적화할 수 있습니다.
병렬 처리: Spark는 데이터를 여러 청크로 분할하고 여러 노드에서 동시에 이러한 청크를 처리합니다. 즉, 여러 작업을 동시에 실행할 수 있어 전체 처리 시간이 빨라집니다.
데이터 셔플링 감소: 데이터 셔플링(파티션 간에 데이터를 재분배하는 작업)은 비용이 많이 드는 작업입니다. Spark의 설계는 불필요한 셔플을 최소화하여 성능을 더욱 향상시킵니다.
본질적으로 Spark의 아키텍처와 설계 원칙은 일관되게 작동하여 효율적이고 신속하며 확장 가능한 데이터 처리를 보장합니다. 인메모리 컴퓨팅, 최적화된 계산, 병렬 처리 등 Spark 설계의 모든 측면이 선도적인 빅 데이터 처리 프레임워크로서의 위상에 기여합니다. 이러한 기초적인 이해를 바탕으로 다음 섹션에서는 Pyspark를 사용한 데이터 전처리에 대해 자세히 알아보겠습니다!
개선을 위한 여러분의 피드백과 제안을 코멘트로 공유해 주세요. 내용에 대한 지적, 혹은 질문을 환영합니다.
출처
Leave a comment