spark를 local mode로 테스트해보면서 잠깐 혼돈되는 지식이 있어 정리하고자 한다. 우선 내 스파크 세션의 설정은 다음과 같다. 처음에 master에 "local[*]" 로 설정했다가, 이후 web ui를 보았다. 이상한 점을 발견하게 되었다.
분명 스파크 세션을 만들 때, master로 "local[*]" 을 줬고, 내 컴퓨터의 cpu 개수는 아래와 같이 16 코어이다. 그런데 왜 Executor Reqs의 cores가 1로 나오는 지 궁금했다. local[*]은 분명 로컬 컴퓨터의 모든 CPU 자원을 이용하는 것으로 들었는 데, 이것만으로 실제 executor에서 모든 자원을 사용하지 않는 걸까? 또한 excutor와 task에 대한 개념을 조금 더 세밀하게 알아야 더 최적화를 시킬 수 있겠다는 생각으로 다시 정리해보았다.
참고로, spark session의 config로 spark.driver.cores를 설정 할 수 있지만 이는 cluster mode에만 의미 있다고 한다.
https://spark.apache.org/docs/latest/configuration.html
Configuration - Spark 3.4.1 Documentation
Spark Configuration Spark provides three locations to configure the system: Spark properties control most application parameters and can be set by using a SparkConf object, or through Java system properties. Environment variables can be used to set per-mac
spark.apache.org
먼저 배포모드가 local mode에서의 Overview이다. 보다시피, local mode에서는 driver, excutor가 단일 머신에서 돌아간다. 그래.. 여기까지는 너무 당연한 말이다. 그렇다면 첫번째 의문은 driver와 executor가 cluster mode에서처럼 독립적인 프로세스로 구동 되는 가이다.
내 대답은 No이다. 그 모습을 직접 보려면, jupyter에서 쉘을 순서대로 실행하면 된다. 먼저 SparkSession 객체만 생성하는 코드를 담은 cell을 실행했고 실행 후에 jps(java process status)를 쳐보면 SparkSubmit 프로세스가 생긴다. 다만 SparkSubmit 프로세스는 spark job을 제출하는 entry point이지만, driver나 executor는 아니다. 그럼 세션 생성 이후, DAG 작업의 action function을 call하면 driver와 excutor 프로세스가 생기는 지 확인 가능할 것이다.
action 호출하기 전 Linux에서 top 명령어로 프로세스가 생기지는 유무를 확인하였다. 현재 머신에서는 CPU를 점유하고 있는 큰 프로세스는 없기에 Local[*]로 설정한 스파크 프로세스가 CPU 작업을 독점할 것이다. 그리고 예상대로 정확한 명칭은 알 수 없었지만 java라는 커맨드로 프로세스가 하나 생겼다. 본래 spark는 JVM위에서 구동되는 프로세스이기 때문에 해당 프로세스가 CPU를 많이 사용한다는 점과 jupyter에서 수행된 시간의 생명주기를 비교하였을 때 spark 프로세스임을 분명히 확인 할 수 있었다. 결과적으로 local 모드에서는 JVM 위의 driver와 executor가 통합된 하나의 프로세스가 형성되는 것이다.
그렇기 때문에 local mode로 spark를 실행할 때는 spark executor core, executor memory, task cpus 와 같은 다른 config를 수정할 필요는 없다. 혹시나 몰라 다음과 같이 여러 config를 바꾸고 대용량 데이터를 전처리 해보았지만 속도에 큰 차이가 없었다. local 모드로 구동할 때는 "spark.driver.memory" 만 신경쓰면 된다.
"spark.driver.memory" 를 신경쓰는 이유는 하나의 process에서 driver와 executor를 모두 수행하기 때문이다. cluster mode 때처럼 여러 노드에 분산하여 처리하는 Multi-Processing 방식은 아니지만, Multi-Threading 방식을 사용하기 때문이다. master로 local[*]을 지정하면 단일 머신의 논리 코어를 모두 사용하여 처리하게 되고, 동시 작업에 대한 결과를 할당받은 한 개의 메모리 영역에 함께 공유하여 쓴다. 때문에 다른 플랫폼의 서비스 수준 관리(SLA: Service Level Agreement)에 영향을 주지 않는다면 단일 머신에서 스파크를 구동할 때 driver memroy를 충분히 높게 주는 것이 좋다.
'Data Engineering > PySpark' 카테고리의 다른 글
[Spark] 분산 파일 시스템에서의 데이터 지역성 (0) | 2023.07.05 |
---|---|
[PySpark] Dataset (0) | 2023.06.24 |