![[Spark] CPU 및 메모리 사용량 설정하기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbizHu%2FbtsCw78KFmO%2FUnfs6xApufsKo8AtPdBOw1%2Fimg.png)
🧐 개요
특별한 설정을 추가하지 않으면, Apache Spark는 작업을 수행하는 과정에서 컴퓨터의 CPU 및 메모리 리소스를 전부 사용하도록 설정되어 있습니다. 따라서 무거운 작업을 반복적으로 구동하는 경우, 컴퓨터의 리소스 범위를 초과하게 되어 에러가 발생하거나 시스템 리소스가 다운되는 경우가 발생하게 됩니다(저 역시도 로컬 머신에서 360억 row의 parquet 데이터를 읽는 도중 시스템이 멈추는 상황이 발생하였습니다).
다행히도 Spark에서는 작업 수행 과정에서 사용할 리소스 양을 설정하는 환경 설정을 기능적으로 제공하고 있습니다. 방법이 어렵지 않기 때문에 오늘은 CPU 및 메모리 사용량을 설정하는 방법을 다루겠습니다.
📙 공식 가이드 확인하기
spark-env.sh 스크립트에 Apache 제단에서 작성한 가이던스가 주석으로 기재되어 있습니다. 먼저 해당 내용을 확인해 보겠습니다.
# Options for the daemons used in the standalone deploy mode
# - SPARK_MASTER_HOST, to bind the master to a different IP address or hostname
# - SPARK_MASTER_PORT / SPARK_MASTER_WEBUI_PORT, to use non-default ports for the master
# - SPARK_MASTER_OPTS, to set config properties only for the master (e.g. "-Dx=y")
# - **SPARK_WORKER_CORES**, to set the number of cores to use on this machine
# - **SPARK_WORKER_MEMORY**, to set how much total memory workers have to give executors (e.g. 1000m, 2g)
# - SPARK_WORKER_PORT / SPARK_WORKER_WEBUI_PORT, to use non-default ports for the worker
# - SPARK_WORKER_DIR, to set the working directory of worker processes
# - SPARK_WORKER_OPTS, to set config properties only for the worker (e.g. "-Dx=y")
# - SPARK_DAEMON_MEMORY, to allocate to the master, worker and history server themselves (default: 1g).
# - SPARK_HISTORY_OPTS, to set config properties only for the history server (e.g. "-Dx=y")
# - SPARK_SHUFFLE_OPTS, to set config properties only for the external shuffle service (e.g. "-Dx=y")
# - SPARK_DAEMON_JAVA_OPTS, to set config properties for all daemons (e.g. "-Dx=y")
# - SPARK_DAEMON_CLASSPATH, to set the classpath for all daemons
# - SPARK_PUBLIC_DNS, to set the public dns name of the master or workers
SPARK_WORKER 관련 설정들을 확인할 수 있습니다.
참고해야 할 부분은, WORKER의 사양 정보는 디폴트 값이 지정되어 있지 않다는 것입니다.
즉 시스템 리소스의 사용량을 고려한다면, 각 SPARK_WORKER가 사용할 CPU 코어 수와 메모리 용량을 지정해주어야 합니다.
해당 설정은 모든 SPARK_WORKER 클러스터에 동일하게 작용됩니다.
# Options read in any mode
# - SPARK_CONF_DIR, Alternate conf dir. (Default: ${SPARK_HOME}/conf)
# - **SPARK_EXECUTOR_CORES**, Number of cores for the executors (Default: 1).
# - **SPARK_EXECUTOR_MEMORY**, Memory per Executor (e.g. 1000M, 2G) (Default: 1G)
# - SPARK_DRIVER_MEMORY, Memory for Driver (e.g. 1000M, 2G) (Default: 1G)
SPARK_WORKER 내에서 실질적인 작업을 수행하는 SPARK_EXECUTOR 관련 설정들이 보입니다.
SPARK_EXECUTOR은 지정된 SPARK_WORKER의 리소스를 나누어 가집니다.
마찬가지로 사용할 리소스의 양을 지정해줄 수 있습니다.
SPARK_WORKER 설정과는 다르게, SPARK_EXECUTOR 리소스 사용량은 디폴트 값이 사전 정의되어 있습니다. 따라서 왠만하면 해당 부분을 수정할 필요가 없으나, 간혹 리소스 문제로 스크립트가 동작하지 않을 경우 각 익스큐터의 체급을 조정해 문제를 해결할 수 있을 것입니다.
특정 버전 이후부터, SPARK_EXECUTOR_INSTANCE 설정이 동작하지 않습니다.
공식 가이드에 ‘동작하지 않을 수 있다’라고 구체적으로 명시되어 있으므로,
SPARK_EXECUTOR_INSTANCE 수를 직접 조정하는 대신, SPARK_WORKER가 사용할 리소스 양을 지정해주는 것이 좋습니다.
Configuration - Spark 3.5.0 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
🖍️ 환경 설정 스크립트 작성하기
앞에서 학습한 내용들을 참고하여 Spark 관련 환경설정을 수행해보도록 하겠습니다.
export SPARK_EXECUTOR_CORES=2
export SPARK_EXECUTOR_MEMORY=3G
export SPARK_WORKER_CORES=20
export SPARK_WORKER_MEMORY=30G
spark-env.sh 설정의 예시
해당 설정에선 각 SPARK_EXECUTOR가 2코어 3GB 메모리를 사용하도록 설정하고, SPARK_WORKER에 총 20코어 30GB 메모리를 할당하였습니다. 정상적으로 동작한다면 총 10개의 익스큐터가 생성되어야 할 것입니다.

정상적으로 20코어 30GB 메모리가 할당된 것을 확인할 수 있습니다.

익스큐터는 설정한 크기에 맞추어 정확히 10개가 생성되었습니다.
📝 마치며
데이터 아키텍처를 구성하다 보면 예상보다 더 많은 양의 리소스를 사용하는 경우가 종종 발생합니다. 이러한 상황이 지속적으로 발생할 경우 시스템의 안전성이 낮아질 수 있습니다. 지속적인 관리와 모니터링을 통해 문제를 해결해야겠지만, 이런 식으로 각 구성요소가 사용할 리소스의 양을 제한함으로서 근본적인 문제 해결을 도입할 수도 있을 것입니다.
'데이터 이모저모 > Spark' 카테고리의 다른 글
[Spark] Kafka Streaming - 인코딩 된 JSON 데이터 가공하기 (1) | 2024.01.06 |
---|---|
[Spark] PySpark의 기본 데이터 가공 프로세스 (1) | 2024.01.03 |
[Spark] Spark Streaming(PySpark) - Kafka 메세지 가공 및 parquet 파일 저장하기 (1) | 2023.12.26 |
[Spark] Spark Streaming(PySpark) - '배치 함수'를 작성하여 작업 경과 시간을 기록하고 Kafka로 발행하기 (0) | 2023.12.24 |
[Spark] Spark Streaming(PySpark)으로 Kafka 메세지 수신하기 (0) | 2023.12.24 |
발자취를 로그처럼 남기고자 하는 초보 개발자의 블로그