오늘의 인기 글
최근 글
최근 댓글
Today
Total
12-31 00:05
관리 메뉴

우노

[Spark] Spark Executor 설정 본문

Data/Spark

[Spark] Spark Executor 설정

운호(Noah) 2020. 10. 4. 21:20

Spark Property

  • Spark 는 Spark Application 실행과 관련된 자원을 설정할 수 있다.
    • SparkConf, spark-shell, spark-submit, spark-defaults.conf 을 수정함으로써 설정 가능하다.
    • property 적용 순서는 SparkConf, spark-shell, spark-submit, spark-defaults.conf 이다.
  • 자주 사용되는 자원 설정 예
    • --num-executors : 전체 executor 개수
    • --executor-cores : 각 executor 당 core 개수
    • --executor-memory : 각 executor 당 memory 용량

Core, Memory 관련 설정

  • spark job 을 실행시킬 때, 우리가 컨트롤 할 수 있는 설정은, 크게 CoreMemory 두 가지이다.
    • 그 외 요인들, 이를테면 네트워크 I/0 나 Disk 등의 성능은, Spark 나 YARN 에게 요청할 수 없기 때문이다.
  • 우리는 Spark 의 ExecutorCore 설정을, 우리가 가진 서버 Node 개수Core 개수에 맞춰 설정해야 한다.
    • 따라서, (Spark Executor 수) X (Spark Core 수) < (서버 Node 개수) X (서버 Core 개수) 이어야 한다.
    • ≤ 가 아니라 < 인 이유는 시스템 자체적으로 OS나 NodeManager등을 위해서 Idle한 CPU를 남겨둬야하기 때문이다.

전체 Executor 개수 설정

  • --num-executors / spark.executor.instances
    • Executor 를 총 몇 개 사용할 것인지를 나타낸다.
    • --num-executors 은 spark-shell 이나 spark-submit 으로 명령을 날릴 때 사용하는 방식이고
    • spark.executor.instances 는 spark-defaults.conf 파일을 설정할 때 사용하는 방식이다.

Executor 당 Core 개수 설정

  • --executor-cores / spark.executor.cores
    • 각각의 executor 가 사용할 수 있는 Core 개수를 의미한다.
    • 하나의 executor 는 여러개의 Core 를 동시 사용 가능하다.
      • 한 executor 당 core 개수를 5 보다 작게 설정 할 때, 가장 성능이 좋다고 한다.

Executor 당 Memory 크기 설정

  • --executor-memory / spark.executor.memory
    • 각각의 Executor 가 가질 수 있는 Memory 의 크기를 의미한다.
    • 전체 서버가 가진 물리 메모리 크기를, 하나의 서버가 책임질 것으로 예상되는 Executor 의 수로 나눈 뒤, 해당 값을 Executor 당 Memory 크기로 설정하면 된다.
      • 즉, 각 서버의 Memory 를 Executor가 나눠 가진다는 뜻이다.
      • 이 문장이 잘 이해가 안갈 수 있는데, Executor 라는 것은 RM(resource manager)이 관리하는 논리적인 단위이기 때문에, 나눠서 사용 가능하다.
      • CPU 와 마찬가지로, Executor 에게 메모리를 할당 할 때에도 시스템을 위한 물리 메모리 1GB 이상을 늘 남겨두어야 한다.

예제

  • 6대의 서버총 96 cores총 378GB Memory 를 가지고 있다고 가정해보자.
    • 6대의 서버 ( node 가 6개 )
    • 각 서버가 가진 Core 는 16개 → 6 * 16 → 96
    • 각 서버가 가진 Memory 는 64GB → 6 * 63 → 378
  • 이제 서버의 물리적인 자원을 논리적으로 나눠보자.
  • Bad case
    • --num-executors 6 --executor-cores 15 --executor-memory 63G
      • executor 는 총 6개
      • 각 executor 마다 15개의 core 사용
      • 각 executor 마다 63GB Memory 사용
    • Bad case인 이유
      • 각 서버의 메모리가 64GB 인 시스템에서, OS 나 NodeMagager 가 사용해야하는 메모리 여유분이 있어야 하기 때문에,
      • 하나의 executor 가 메모리를 63GB까지 사용하는 것은 힘들다.
      • 한 executor 에 15개의 core 를 사용하면 HDFS I/O throughput 이 낮아지는 등, 성능 저하를 유발할 수 있다.
      • executor core 의 수는 1 보다는 크게, 5 보다는 작게 설정하는 것이 좋다
  • Good case
    • --num-executors 18 --executor-cores 5 --executor-memory 19GB
      • executor는 총 18개
      • 각 executor 마다 5개의 core 사용
      • 각 executor 마다 19GB Memory 사용
    • Good case인 이유
      • 노드마다 대략 3개의 executor 가 수행될 수 있고
      • 각 executor는 5개의 core 를 갖게 된다.
        • 18 * 5 = 90 은, 전체 서버 Core 수인 6 * 16 = 96 보다 작아야 한다는 점을 기억하자.
      • --executor-memory 계산하는 방법
        • (서버 1개의 메모리 / 서버 1개의 할당하려는 Executor 수) -2 == (63.0 / 3) - 2 = 19

계산 순서

  • 서버의 전체 Core, Memory 값을 구한다.
  • --executor-cores 의 개수를 0~5 사이값으로 정한다.
  • 사용할 수 있는 전체 Executor 개수를 구한다. (--num-executors)
    • (--num-executors ) x (--executor-cores) < 서버 전체 Core 수
  • 서버 1개당 할당할 수 있는 Executor 개수를 구한다.
    • --num-executors / 전체 서버 개수 == 서버 1개당 Executor 개수
  • Executor 1개에 할당할 메모리를 구한다. (--executor-memory)
    • 서버 1개의 Memory / 서버 1개의 Executor 개수 == --executor-memory

참고

Comments