2020년 10월 18일 일요일

Apache Hive [2] - CDH Hive (using Spark) 환경설정 최적화


[ 사전 준비 ]

1. 모든 설정은 CDH->Yarn / Hive->구성에서 값을 수정한다.

2. spark executor는 하나의 yarn container가지며, spark task는 하나의 core(yarn vcore)에서 실행된다. 하나의 spark executor가 여러개의 spark task를 동시에 부릴 수 있다.














3. 하이브 엔진으로 spark를 사용하기 위해선 위 설정을 해주어야 한다. Default는 MapReduce이다.






[ 예제 환경 ]

예시로 실행되는 환경은 40개의 host가 있는 YARN클러스터이며, 각 호스트는 32개의 Core와 120GB메모리가 할당되어있다고 가정한다.



[ YARN Configuration ]

1. yarn.nodemanager.resource.cpu-vcores

일반적으로 Yarn NodeManager과 HDFS DataNode에서 Core를 하나씩 할당하고, OS사용을 위해 코어 2개를 추가로 할당하여, 최대 28개의 코어를 Yarn에서 사용할 수 있다.


2. yarn.nodemanager.resource.memory-mb

각 호스트의 메모리가 120GB이므로 여유있게 100GB로 설정한다.



[ Spark Configuration ]

- 고려사항

executor메모리를 설정할 때 메모리가 크면 쿼리,조인 성능이 좋아지지만, 가비지 수집으로 오버헤드가 증가할 수 있다. 

executor 코어 또한 높게 설정하면 성능이 좋지만, 너무 많이 설정하면 코어와 메모리가 할당  될때까지 spark job이 실행이 안되거나(Race condition) 다른 어플리케이션 성능이 떨어진다.


1. spark.executor.cores

사용하지 않는 코어 수를 최소화하기 위해 YARN에 할당된 코어 수에 따라 3, 4,5,6으로 설정할 것을 권장한다. 예시를 든 YARN Core(28개) 일때 4로 설정해야 사용하지 않는 코어가 남지 않는다. 28 % 4 =0


2. spark.executor.memory

spark.executor.cores가 4로 설정된 경우 호스트에서 동시에 실행할 수 있는 executor의 최대 수는 7개(28/4)이다. 따라서 각 실행기는 100GB / 7, 약 14GB 메모리를 할당 될 수 있다.


3. spark.executor.memoryOverhead

executor.memoryOverhead는 VM오버헤드, 문자열 및 기타 오버헤드에 사용된다.

executor에 할당된 총 메모리에는 오버헤드 메모리도 포함된다. 

즉 executor memory = spark.executor.memory + spark.executor.memoryOverhead

spark.executor.memoryOverhead 기본값은 executor메모리 * 0.1이며 최소 384(MB)이다.


따라서 각 실행기는 14GB 메모리가 할당시

spark.executor.memory = 12GB

spark.executor.memoryOverhead = 2G

로 설정할 수 있다.


또한 spark.executor.memory + spark.executor.memoryOverhead의 합계가 yarn.scheduler.maximum-allocation-mb보다 작아야한다.



[ Spark Driver Memory Configuring ]

스파크 드라이버 메모리 또한 설정해야 하는데 관련 설정값은 아래와 같다.

spark.driver.memory : 하이브가 스파크에서 실행 중일 때 스파크 드라이버에 할당된 최대 자바 힙 메모리 크기.

spark.yarn.memoryOverhead : 드라이버당 YARN에 요청할 수 있는 추가 off-힙메모리


yarn.nodemanager.resource.memory-mb = x, spark driver 메모리 = y라 가정하면

  • x가 50GB보다 큰경우 y=12GB
  • x가 12GB ~ 50GB 일 경우 y=4GB
  • x가 1GB ~ 12GB 일 경우 y=1GB
  • x가 1GB 미만일 때 y=256MB

yarn.nodemanager.resource.memory-mb = 100GB이므로 spark driver 메모리 = 12GB이다.  그 결과, 

spark.driver.memory=10.5GB, 

spark.yarn.memoryOverhead=1.5GB (spark driver 총 메모리의 10-15%로 설정) 

로 설정 할 수 있다.



[ Executor 수 선택 ]

클러스터 executor수는 각 호스트의 executor수와 각 호스트의 woker에 의해 결정된다. 클러스터에 40개의 worker 호스트가 있는경우 executor의 최대 수는 160개 (40 * 4(코어수)) 이다. 드라이버가 코어 1개와 메모리 12GB를 사용하기 때문에 최대치는 이보다 작다.

하이브 성능은 쿼리를 실행하는데 사용되는 executor수와 직접적인 관련이 있다. 따라서 최대 실행자 수의 절반정도로 설정한다.

spark.executor.instance=80

그러나 spark.executor.instance를 최적화 값으로 하면 성능이 극대화되지만, 여러 사용자가 하이브쿼리를 실행하는 운영환경인 경우 기능저하가 온다. 따라서 클라우데라에서는 spark.executor.instance값을 동적으로 할당할 것은 권장한다. ( spark.executor.instance의 기본값은 동적할당 )



참조

: https://docs.cloudera.com/documentation/enterprise/latest/topics/admin_hos_tuning.html

: https://clouderatemp.wpengine.com/blog/2014/05/apache-spark-resource-management-and-yarn-app-models/

: https://blog.cloudera.com/how-to-tune-your-apache-spark-jobs-part-2/

댓글 없음:

댓글 쓰기