위에서 언급 한 매개 변수를 어디에서 조정하기 시작합니까? 실행기 메모리로 시작하여 실행기 수를 얻거나 코어로 시작하여 실행기 번호를 얻습니까? 나는 링크를 따랐다 . 그러나 높은 수준의 아이디어를 얻었지만 어떻게 시작하고 최종 결론에 도달해야할지 아직 확실하지 않습니다.
답변:
다음 답변은 제목에 언급 된 세 가지 주요 측면 (실행기 수, 실행기 메모리 및 코어 수)을 다룹니다. 이 답변에서 다루지 않았지만 가까운 장래에 추가하고 싶은 드라이버 메모리 및 기타 매개 변수와 같은 다른 매개 변수가있을 수 있습니다.
사례 1 하드웨어-6 개 노드, 각 노드 16 개 코어, 64GB RAM
각 실행기는 JVM 인스턴스입니다. 따라서 단일 노드에 여러 실행기를 가질 수 있습니다.
OS 및 Hadoop 데몬에는 처음 1 개 코어와 1GB가 필요하므로 각 노드에 대해 15 개 코어, 63GB RAM을 사용할 수 있습니다.
코어 수를 선택하는 방법부터 시작하십시오 .
Number of cores = Concurrent tasks as executor can run
So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.
This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.
집행자 수 :
Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to
3 executors per node.
So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors
This 17 is the number we give to spark using --num-executors while running from spark-submit shell command
각 실행기에 대한 메모리 :
From above step, we have 3 executors per node. And available RAM is 63 GB
So memory for each executor is 63/3 = 21GB.
However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)
Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
= 1.47
Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB
So executor memory - 19 GB
최종 번호-실행자-17, 코어 5, 실행자 메모리-19GB
케이스 2 하드웨어 : 동일 6 노드, 32 코어, 64GB
5는 좋은 동시성을 위해 동일합니다.
각 노드의 실행기 수 = 32/5 ~ 6
따라서 총 실행자 = 6 * 6 노드 = 36. 그러면 최종 수는 AM = 35 일 때 36-1입니다.
실행기 메모리는 각 노드에 대해 6 개의 실행기입니다. 63/6 ~ 10. 오버 헤드는 .07 * 10 = 700MB입니다. 따라서 머리 위로 1GB로 반올림하면 10-1 = 9GB가됩니다.
최종 번호-실행자-35, 코어 5, 실행자 메모리-9GB
사례 3
위의 시나리오는 코어 수를 고정 된 것으로 받아들이고 실행기 및 메모리 수로 이동하는 것으로 시작합니다.
이제 첫 번째 경우 19GB가 필요하지 않고 10GB만으로 충분하다고 생각하면 다음과 같은 숫자가 있습니다.
코어 5 각 노드에 대한 실행기 수 = 3
이 단계에서 이것은 첫 번째 계산에 따라 21과 19로 이어질 것입니다. 그러나 우리는 10이 괜찮다고 생각했기 때문에 (약간 오버 헤드를 가정), 노드 당 실행기 수를 6 (63/10과 같이)으로 전환 할 수 없습니다. 노드 당 실행기가 6 개이고 코어가 5 개인 경우 코어가 16 개 뿐인 경우 노드 당 30 개 코어로 줄어 듭니다. 따라서 각 실행기의 코어 수도 변경해야합니다.
다시 계산하면
매직 넘버 5는 3이됩니다 (5보다 작거나 같은 숫자). 따라서 3 개의 코어와 15 개의 사용 가능한 코어로 노드 당 5 개의 실행기를 얻습니다. 따라서 (5 * 6 -1) = 29 명의 집행자
따라서 메모리는 63/5 ~ 12입니다. 오버 헤드는 12 * .07 = .84이므로 실행기 메모리는 12-1GB = 11GB입니다.
최종 숫자는 29 개의 실행기, 3 개의 코어, 실행기 메모리는 11GB입니다.
동적 할당 :
참고 : 동적 할당이 활성화 된 경우 실행기 수의 상한입니다. 따라서 이것은 스파크 애플리케이션이 필요한 경우 모든 리소스를 먹을 수 있음을 의미합니다. 따라서 다른 응용 프로그램이 실행 중이고 작업을 실행하기 위해 코어가 필요한 클러스터에서는 클러스터 수준에서 수행해야합니다. 사용자 액세스를 기반으로 YARN에 특정 수의 코어를 할당 할 수 있습니다. 따라서 spark_user를 만든 다음 해당 사용자에 대한 코어 (최소 / 최대)를 제공 할 수 있습니다. 이러한 제한은 Spark와 YARN에서 실행되는 다른 애플리케이션 간의 공유를위한 것입니다.
spark.dynamicAllocation.enabled-이것이 true로 설정된 경우-실행자를 언급 할 필요가 없습니다. 그 이유는 다음과 같습니다.
spark-submit에서 제공하는 정적 매개 변수 번호는 전체 작업 기간 동안입니다. 그러나 동적 할당이 그림에 나타나면 다음과 같은 다른 단계가있을 것입니다.
무엇으로 시작해야할까요?
시작할 초기 실행기 수 ( spark.dynamicAllocation.initialExecutors )
얼마나 :
그런 다음로드 (보류중인 작업)에 따라 얼마나 많은 것을 요청할 수 있는지. 이것은 결국 우리가 정적 인 방식으로 spark-submit에서주는 숫자가 될 것입니다. 따라서 초기 실행기 번호가 설정되면 최소 ( spark.dynamicAllocation.minExecutors ) 및 최대 ( spark.dynamicAllocation.maxExecutors ) 번호로 이동합니다.
요청 또는 제공시기 :
새 실행기를 언제 요청합니까 ( spark.dynamicAllocation.schedulerBacklogTimeout )-이 기간 동안 보류중인 작업이있었습니다. 그래서 요청하십시오. 각 라운드에서 요청 된 집행자 수는 이전 라운드에서 기하 급수적으로 증가합니다. 예를 들어, 응용 프로그램은 첫 번째 라운드에서 실행자를 1 명 추가 한 다음 후속 라운드에서 실행자를 2, 4, 8 등으로 추가합니다. 특정 지점에서 위의 최대 값이 그림에 나타납니다.
언제 우리는 실행자를 포기합니까 ( spark.dynamicAllocation.executorIdleTimeout )-
내가 놓친 것이 있으면 정정하십시오. 위의 내용은 내가 질문 한 블로그와 일부 온라인 리소스를 기반으로 이해 한 것입니다. 감사합니다.
참조 :
spark.executor.cores
모두 사용하므로 기본적으로 사용 가능한 모든 코어를 사용할 수 있습니다.
또한 사용 사례에 따라 중요한 구성 매개 변수는 다음과 같습니다.
spark.memory.fraction
(실행 및 저장에 사용되는 (힙 공간-300MB)의 비율) http://spark.apache.org/docs/latest/configuration.html#memory-management .
캐시 / 지속성을 사용하지 않는 경우 0.1로 설정하여 프로그램에 대한 모든 메모리를 확보하십시오.
캐시 / 지속성을 사용하는 경우 다음에서 사용하는 메모리를 확인할 수 있습니다.
sc.getExecutorMemoryStatus.map(a => (a._2._1 - a._2._2)/(1024.0*1024*1024)).sum
HDFS 또는 HTTP에서 데이터를 읽습니까?
다시 말하지만 튜닝은 사용 사례에 따라 다릅니다.
spark.memory.storageFraction=0.1
했습니까? AFAIK spark.memory.fraction
는 실행 및 저장 (이미 언급 했음) Spark
모두에 사용되는 메모리 양을 결정하고 메모리 (저장 + 실행에 사용할 수 있음) 만 캐시 제거에서 제외 됩니다 . 이 링크를 참조하십시오spark.memory.storageFraction