[Spark] Spark Install Guide and Standalone mode start

Apache Spark Install Guide 

1. 스파크 다운로드 및 구성요소 

1. Apache-Spark 다운로드

http://spark.apache.org/downloads.html로 이동한다.

2. 다운로드 버젼 설정 

스파크 최신 버젼을 선택했다.

사전빌드(Pre-build)이고, 대부분의 하둡 배포판에서 이용할 수 있다고 한 두번째 항목은 선택했다.
필요한경우 이미 설치되어 있는 적합한 하둡 버젼을 다운받으면 된다. 

# 참고 : 하둡은 반드시 설치 되어 있지 않아도 된다.

3. 다운로드 받은 파일 압축 풀기. 

txr -xvf spark-1.6.1-bin-without-hadoop.tgz
ln -s spark-1.6.1-bin-without-hadoop spark
vim ~/.bash_profile
export SPARK_HOME=/Users/KIDO/Documents/00.TOOLS/spark
export PATH=$JAVA_HOME:$MYSQL_HOME:$ACTIVATOR_HOME:$SPARK_HOME/bin:$PATH
상기 항목을 입력하고 :wq로 빠져나온다.

source .bash_profile

4. 스파크 디렉토리 둘러보기


bin
  - 실행 명령이 들어있다.
conf
  - 스파크 설정을 위한 설정파일
  - 스파크 환경설정, log설정, docker관련 설정, slave관련 설정등 다양하다.
examples
  - 스파크를 사용한 다양한 예제를 살펴볼 수 있다.
lib
  - 스파크에 필요한 라이브러리들이 존재한다.
  - spark-yarn 셔플 라이브러리, 하둡 라이브러리등이 있다.
python
  - 파이선 스파크를 위한 다양한 라이브러리와 스크립트가 있다.
R
  - spark R을 위한 라이브러리
sbin
  - 스파크 마스터서버 및 슬레이브 서버 실행 명령

2. Spark Standalone Mode 

출처 : http://spark.apache.org/docs/latest/spark-standalone.html

스파크는 Mesos혹은 YARN 상에서 수행이 된다. 그러나 Standalone모드를 지원하고 있다.
스탠드 얼론 모드는 하나의 클러스터에서 마스터와 워커를 수동으로 실행 할 수 있도록 제공한다.

1. 클러스터 수동 실행 

1.1 마스터 서버 실행하기
./sbin/start-master.sh
마스터를 실행하면 스파크는 ://HOST:PORT의 형식으로 URL을 프린트한다.
이 정보를 이용하여 마스터 서버에 접근하거나 SparkContext로 해당 정보를 전달 할 수 있다.
또한 마스터의 WEB-UI는 http://localhost:8080으로 접근할 수 있다.

1.2 슬레이브 워커 실행하기.
./sbin/start-slave.sh <master-spark-URL>
슬레이브 워커를 수행하면 master WEB-UI에서 신규 노드가 접속되었음을 확인할 수 있다.
또한 CPU와 메모리 정보등을 직접 확인할 수 있다.

1.3 마스터와 슬레이브 설정 파라미터
ArgumentMeaning
-h HOST--host HOST리슨할 호스트명을 설정한다.
-i HOST--ip HOST리슨할 호스트 이름을 설정한다. (deprecated됨, -h나 --host이용)
-p PORT--port PORT리슨할 서비스의 포트번호 (기본 : 7077 마스터, worker은 랜덤)
--webui-port PORTweb UI를 위한 포트 (기본 마스터 : 8080, 워커 : 8081)
-c CORES--cores CORES스파크 어플리케이션이 사용할 CPU코어의 총 개수,
머신에 따라 다르게 설정될 수 있다. (기본 : all available)
이것은 worker에만 설정한다. 
-m MEM--memory MEM스파크 어플리케이션이 사용할 총 메모리 양,
머신에 따라 다르게 설정될 수 있다. (기본 : 머신 총 RAM - 1GB)
형식 : 1000M 혹은 2G 등으로 설정
이것은 worker에만 설정한다. 
-d DIR--work-dir DIR작업에 사용할 공간과 job가 출력할 로그를 저장할 디렉토리
(기본 : SPARK_HOME/work)이며 worker에만 설정한다. 
--properties-file FILE로드할 커스텀 Spark 프로퍼티 패스를 지정한다.
(기본 : conf/spark-defaults.conf)

2. 클러스터 런치 스크립트 

스파크를 스탠드 얼론 모드로 스크립트로 수행하기 위해서는, conf/slave 라고 불리는 파일을 생성해야한다. 이는 spark디렉토리 내부에 존재한다.
이 파일에는 스파크 워커가 실행할 모든 머신의 호스트 명이 기술 되어있어야 한다.
만약 conf/slave가 존재하지 않는다면  lunch script는 기본적으로 단일 머신에서 수행된다. (localhost)
이는 테스팅을 위해서 유용하게 사용된다.
마스터 머신은 각 워커 머신에 ssh를 이용하여 접근하는것이 일반적이다. 기본적으로는 ssh를 이용하며, 이를 이용하면 password없이 서버간 access가 가능하다.
만약 password-less설정을 하지 않았다면 SPARK_SSH_FOREGROUND 변수값에 각 워커를 위한 password를 설정할 수 있다.

설정을 완료하고 나면 launch나 stop를 다음 쉘 스크립트를 통해서 수행할 수 있다. 이 쉘들은 SPARK_HOME/sbin에 들어있다.
  • sbin/start-master.sh - 마스터 인스턴스를 실행한다. 
  • sbin/start-slaves.sh - conf/slaves 파일에 지정된 머신에 슬레이브를 실행한다. 
  • sbin/start-slave.sh - 머신내에 슬레이브 인스턴스를 실행한다. 
  • sbin/start-all.sh - 상단에 기술한 모든 마스터와 슬레이브를 실행한다. 
  • sbin/stop-master.sh - bin/start-master.sh스크립트를 통해 실행한 마스터 인스턴스를 종료한다. 
  • sbin/stop-slaves.sh - conf/slaves파일에 지정된 머신에서 슬레이브를 종료시킨다. 
  • sbin/stop-all.sh - 마스터와 슬레이브 모두 종료한다. 
주의할 것은 상기 스크립트는 마스터 노드에서 실행해야한다. 슬레이브 노드에서 각각 실행해서는 안된다.

클러스터의 설정은 conf/spark-env.sh에 있는 환경 변수에 값을 설정하여 선택적으로 수행할 수 있다.
이 파일은 conf/spark-env.sh.template를 복사하여 모든 워커 머신에 설정값을 지정하면 된다.

환경변수 목록 : 
Environment VariableMeaning
SPARK_MASTER_IP특정 IP주소에 마스터를 바인딩한다. 
SPARK_MASTER_PORT다른 포트로 마스터를 실행한다. (기본 : 7077)
SPARK_MASTER_WEBUI_PORT마스터 web UI용 포트 (기본:8080)
SPARK_MASTER_OPTS마스터에 설정될 옵션들을 설정한다.
형식 : "-Dx=y" 의 형식으로 설정한다.
아래 가능한 옵션 참조. 
SPARK_LOCAL_DIRS스파크가 사용할 디렉토리를 지정한다. 이것은 map 출력파일, RDD 등을 저장한다. 성능을 위해서는 시스템 내의 로컬 디스크에 저장하는것이 좋다. 콤마를 이용하여 서로다른 디스크상의 디렉토리를 나열할 수 있다. 
SPARK_WORKER_CORES스파크 어플리케이션이 머신내에서 사용할 총 코어의 개수를 지정한다. (기본값 : all avaliable cores)
SPARK_WORKER_MEMORY스파크 어플리케이션이 머신내에서 사용할 총 메모리의 양을 지정한다.
형식 : 1000m, 2G (기본적으로 총 메모리 - 1G를 설정한다.)
각 어플리케이션들의 개별적인 메모리 설정은 spark.executor.memoryproperty를 이용하여 설정할 수 있다. 
SPARK_WORKER_PORT특정 포트로 스파크 워커를 실행한다. (기본값 : random)
SPARK_WORKER_WEBUI_PORT워커의 web UI를 수행할 포트를 지정한다. (기본값 : 8081)
SPARK_WORKER_INSTANCES각 머신에서 수행할 워커 인스턴스의 개수를 지정한다. (기본 : 1)
1 이상을 설정할 수 있으며, 매우 큰 머신에서 이용하거나, 복수개의 워커 프로세스를 두고자 할때 이 값을 증가 시킬 수 있다.
이 값을 변경한경우에는 SPARK_WORKER_CORES 를 함께 확인할 필요가 있다. 이것은 각 워커의 워커를 명시적으로 제한하기 때문이다.
혹은 각 워커는 모든 코어를 사용할 수 있다. 
SPARK_WORKER_DIR어플리케이션들을 수행할 디렉토리를 지정한다. 이곳에는 로그와 워커 작업 공간으로 이용된다. (기본 : SPARK_HOME/work)
SPARK_WORKER_OPTS워커에 대한 설정값을 지정하고자 할때 사용한다.
형식 : "-Dx=y"
아래 옵션을 참조하자. 
SPARK_DAEMON_MEMORY스파크 마스터와 워커 데몬 자체에 할당할 메모리를 지정한다. (기본 : 1g)
SPARK_DAEMON_JAVA_OPTSJVM옵션으로 스파크 마스터와 워커 데몬 자체에 설정하는 옵션값이다.
형식 : "-Dx=y"의 형태이다. 
SPARK_PUBLIC_DNSpublic DNS명을 지정한다. 
* 참고 : launch script는 window에서는 적용되지 않는다. 윈도우에서 실행하기 위해서는 수동으로 직접 설정해야한다.

SPARK_MASTER_OPTS 옵션 : 
Property NameDefaultMeaning
spark.deploy.retainedApplications200디스플레이할 완료된 어플리케이션의 총 개수를 지정한다. 오래된 어플리케이션은 UI에서 이 제한에 걸려 나타나지 않을 것이다. 
spark.deploy.retainedDrivers200디스프레이할 완료된 드라이버들의 최대 개수를 지정한다. 오래된 드라이버는 UI에서 이 제한에 걸려 나타나지 않을 것이다. 
spark.deploy.spreadOuttrue스탠드 얼론 클러스터 매니저는 노드들로 어플리케이션을 분산하게 될 것이다. 아니면 가능하면 몇개의 노드들로 통합해서 처리하게 된다. 분산 하는 작업은 보통 HDFS에서 더 낳은 데이터 로컬리티를 위해 이용된다. 그러나 통합 작업은 계산에 더 집중적인 작업을 위해서 효과적이다. 
spark.deploy.defaultCores(infinite)만약 spark.cores.max를 지정하지 않은경우라고 하면 스파크 스탠드 얼론에서 어플리케이션에 할당할 기본 코어수를 지정하도록 한다. 설정되지 않았다면 어플리케이션은 항상 모든 가능한 코어를 spark.cores.max에 할당한다. 공유된 클러스에 이 값을 낮게 지정하여 전체 클러스터를 사용자가 잡아버리는 것을 막기 위해 이용할 수 있다. 
spark.worker.timeout60만약 마스터가 허트비트를 수힌하지 못한경우 얼마의 시간이 지나면 워커가 유실 되었다는 것을 파악할지 지정하는 시간이다. (초단위)
SPARK_WORKER_OPTS 옵션 : 
Property NameDefaultMeaning
spark.worker.cleanup.enabledfalseworker의 /application 디렉토리를 주기적으로 클린업 할지 여부를 설정한다. 이것은 오직 standalone모드에서만 효과가 있는 설정값이다. WARN은 다르게 동작한다. 이것은 오직 정지된 어플리케이션의 디렉토리만을 클린업 하게 된다. 
spark.worker.cleanup.interval1800 (30 minutes)로컬머신에서 오래된 어플리케이션 작업의 디렉토리를 클린업 할 인터벌 시간을 나타낸다. 초단위이다. 
spark.worker.cleanup.appDataTtl7 * 24 * 3600 (7 days)각 워커에서 유지해야할 작업 디렉토리의 TTL을 지정한다. 초단위이며 이것은 Time To Live이며, 가능한 디스크의 용량에 의존하게 된다. 어플리케이션 로그와 jars들이 어플리케이션 워크 디렉토리에 다운로드 된다. 시간이 지나면 work dirs들은 빠르게 디스크 공간을 차지해 버리게 된다. 특히 job들을 매우 빈번하게 실행하면 말이다. 

3. 어플리케이션에서 Cluster로 커넥팅 하기

스파크 클러스터에서 어플리케이션을 수행하는 것은 단순히 spark://IP:PORT 를 SparkContext constructor에 전달하는 것으로 가능하다.
스파크 쉘이 클러스터와 상호 인터렉션 하는 것은 다음 커맨드로 가능하다.

./bin/spark-shell --master spark://IP:PORT
또한 옵션을 전달 할 수 있으며 --total-executor-cores <numCores> 를 지정하여 스파크 쉘이 클러스터에서 사용할 코어의 개수를 설정하게 할 수 있다.

4. Spark Application들 런칭하기. 

spark-submit 스크립트는 직관적으로 컴파일된 스파크 어플리케이션을 클러스터로 서밋 하게 할 수 있다.
standalone 클러스터들에서는 현재 제공되는 2가지 모드가 있다. client모드에서 드라이버는 동일한 프로세스에서 런치 되며, 클라이언트 어플리케이션에서 서밋이 된다. cluster모드에서 드라이버는 클러스터내의 하나의 워커 프로세스들의 하나로 부터 런치되며, 클라이언트 프로세스는 바로 어플리케이션의 서밋 작업에 대한 응답을 수행한다. 이는 어플리케이션이 종료되기 까지 대기하지 않고 수행된다.

만약 어플리케이션이 Spark 서밋을 통해서 런치되며 어플리케이션 jar는 자동적으로 모든 워커 노드로 배포된다. 어플리케이션에 의존된 다른 jar들은 --jars옵션에 콤마로 분리하여 (ex --jars jar1,jar2) 참조 가능하다.
어플리케이션의 설정 혹은 실행 환경을 컨트롤 하는 것은 Spark Configuration을 참조하자.

추가적으로 스탠드 얼론 클러스터 모드는 0이 아닌 값으로 종료 되었을때 자동으로 재 시작 하는 모드를 제공한다. 이러한 기능을 이용하기 위해서는 --supervise플래스에서 spark-submit를 전달하면 되며, 이는 어플리케이션 실행시에 전달된다. 그리고 반복되는 실패때문에 어플리케이션을 종료하고자 한다면 다음과 같이 수행하면 된다.

./bin/spark-class org.apache.spark.deploy.client kill <master url> <driver ID>
드라이버 아이디는 http://<master url>:8080에서 web UI를 이용하여 해당 아이디를 찾을 수 있다.

5. Resource Scheduling 

standalone 클러스터 모드에서는 현재 단순 FIFO 스케줄러만을 제공하고 있다.
그러나 복수의 동시 이용자를 허용하기 위해서 각 어플리케이션 이 사용할 최대 리소스의 개수를 조정할 수 있다. 기본적으로 이것은 클러스터 내의 모든 코어를 필요로 하게 되지만 한번에 하나의 어플리케이션만을 실행할때에만 유효하다. 이 설정은 spark.cores.max 를 SparkConf내에서 지정해줄 수 있다.

예제 )
val conf = new SparkConf()
            .setMaster(...)
            .setAppName(...)
            .set("spark.cores.max", "10")
val sc = new SparkContext(conf)
추가적으로 spark.deploy.defaultCores를 클러스터 마스터 프로세스에서 설정할 수 있다.
이 설정은 conf/spark-env.sh에서 다음과 같이 설정할 수 있다.
export SPARK_MASTER_OPTS="-Dspark.deploy.defaultCores=<value>"
이것은 공유 클러스터 상에서 유용하다. 사용자가 개인적으로 최대수의 cores를 지정하지는 않을때 말이다.

6. Monitoring and Logging

Spark 스탠드얼론 모드는 웹 기반의 사용자 인터페이스를 제공하여 클러스터 모니터링을 수행할 수 있도록 한다. 마스터와 각 워커들은 각자의 web UI를 가지고 있으며 각 클러스터와 잡들을 볼수 있다. 기본적으로 웹 UI에 8080을 통해서 접근할 수 있다. 포트는 설정 파일에서 변경하거나, 수행시 파라미터를 통해서 설정이 가능하다.
추가적으로 각 잡의 상세 로그는 각 슬레이브 노드의 워크 디렉토리에 저장된다. 기본적으로 SPARK_HOME/work디렉토리에 저장된다. 또한 잡들에 대해서 2개의 파일이 존재하며 stdout과 stderr로 저장이 된다.

7. Running Alongside Hadoop

존재하는 하둡을 이용하고자 하는 경우에는 단순히 동일한 머신에서 분리된 서비스로 이용하면 된다. Hadoop 데이터를 스파크에서 엑세스 하기 위해서는 hdfs://URL (보통 : hdfs://<namenode>:9000/path 이다. ) 반대로 완젼 다른 서버에서 하둡과 연동할 수 있다. 이때에는 네트워크를 통해서 접속할 수 있으며, 로컬 위치의 데이터 엑세스에 비해서 성능은 떨어진다.

8. Configuring Ports for Network Security

 스파크는 네트워크 트래픽을 많이 발생 시킨다. 또한 어떠한 시스템에서는 파이어월 설정을 이용하기 위해서 제한된 요구사항을 가지기도 한다. 이러한 설정을 확인하려면 다음 경로를 찾아가자. http://spark.apache.org/docs/latest/security.html#configuring-ports-for-network-security


9. High Availability

기본적으로 스탠드얼론 스케줄링 클러스터는 Worker의 실패들에 대해서 회복력이 있다. 그러나 스케줄러는 Master를 이용하여 스케줄링 결정을 내린다. 그리고 기본적으로 이것은 단일 실패지점 (SPOF)가 된다. 만약 마스터가 크래쉬되면, 어떠한 새로운 어플리케이션도 생성되지 않는다. 이러한 문제를 극복하기 이ㅜ해서 2개의 high availability 스키마를 아래와 같이 구성한다.

10. Standby Masters with ZooKeeper

Overview
zookeeper의 주 용도는 리더의 선출과 상태를 저장하는 것이다. 사용자는 복수개의 마스터를 클러스터에 설정하여 동일한 ZooKeeper인스턴스에 연결할 수 있다. 한대는 "leader"로 선출되고 나머지는 standby mode로 마스터를 구성한다. 만약 현재 leader가 죽으면, 다른것이 Master가 된다. 그리고 마스터의 상태를 복구하게 되고 동일한 스케줄링을 다시 수행하게 된다.
전체 복구 프로세스는 아마도 처음 마스터가 죽고 나서 부터 약 1 ~ 2분 정도 소요된다.
이 딜레이는 새로운 어플리케이션 스케줄링에만 영향을 준다. 어플리케이션들은 마스터 failover를 수행하는 동안 계속해서 수행되고 있는 상태가 된다.

Zookeeper에 대해서 더 많은 것을 보려면 http://zookeeper.apache.org/doc/trunk/zookeeperStarted.html 을 참조하자.

Configuration
스파크 복구 모드는 다음과 같이 spark-env스크립트 내에 SPARK_DAEMON_JAVA_OPTS 에 설정할 수 있다.
System propertyMeaning
spark.deploy.recoveryModezookeeper를 standby 모드로 설정하도록 한다. (기본 : NONE)
spark.deploy.zookeeper.urlZooKeeper 클러스터 url을 설정한다.
예) 192.168.1.100:2181,168.1.101:2181
spark.deploy.zookeeper.dirThe directory in ZooKeeper to store recovery state (default: /spark).
멀티플 마스터를 가지고 있는 상태에서 마스터가 주키퍼를 이용하는 설정에 실패를 하게 되면 마스터는 서로를 확인하는 작업에 실패하게 되며, 모든 마스터들이 리더라고 생각하게 된다. 이때에는 올바른 클러스터 상태를 이용하기 어렵게 된다. (모든 마스터들은 독립적으로 스케줄링 하게 된다.)

Details
주키퍼 설정을 완료하고 나면 high availability를 기동할 수 있다. 단순히 복수개의 마스터를 서로다른 노드에서 실행하고 동일한 주키퍼 설정을 가지고 있으면 된다. (ZooKeeper URL과 디렉토리 설정). 마스터들을 언제든지 추가나 제거 할 수 있다.
새로운 어플리케이션을 스케줄 하거나 클러스터에 worker를 추가할때에는 현재 Master의 IP를 알아야 한다. 이것은 단순히 마스터 리스트에서 하나에다가 전달 하는 것으로 가능하다. 예를 들어 SparkContext를 다음과 같이 마스터의 위치를 포인트 할 수 있다. spark://host1:port1,host2:port2 로 지정하는 것이다.
이렇게 하면 SparkContext는 두개의 마스터에 접근을 시도한다. host1이 내려가 있으면 이 설정은 새로운 리더를 찾을 것이며 이것이 host2가 됨을 알려 줄 것이다.

"registering with a Master"과 normal operation사이에는 중요한 구별 되는 점이 있다. 어플리케이션이나 워커가 실행될때 현재의 마스터를 찾거나 등록하는 작업이 필요하다. 이 작업이 한번 성공적으로 수행되고 나면 이 내용을 Zookeeper에 저장한다. 만약 failover가 발생하면 새로운 리더가 모든 등록된 어플리케이션들과 Workers에 접근을 시도하며, 이후 모든 클러스터에게 새로운 리더를 알린다.

이러한 속성으로 인해서 새로운 마스터는 언제든지 생성될 수 있다, 고민해야할 것은 오직 새로운 어플리케이션과 워커들이 새로운 리더를 찾고, 이를 등록하는 작업만 하면 된다. 한번 등록하면 언제든지 이용할 수 있다.

11. Single-Node Recovery with Local File System

Overview
주키퍼는 high availability를 위한 가장 좋은 방법을 제공한다. 그러나 마스터가 다운되었을때 단지 리스타트를 하기를 원할 수 있다. FILESYSTEM모드는 이러한 작업을 할 수 있다. 어플리케이션과 워커가 등록될때 제공된 디렉토리에 상태를 저장하고, 이것은 마스터 프로세스가 리스타트 될때 이용 할 수 있다.

Configuration
복구 모드를 기동하기 위해서는 spark-env 설정파일의 SPARK_DAEMON_JAVA_OPTS에 지정할 수 있다.
System propertyMeaning
spark.deploy.recoveryModeFILESYSTEM을 설정하여 단일 노드 복구 모드를 실행할지 지정한다.
(기본 :  ㅜNONE)
spark.deploy.recoveryDirectorySpark가 복구 상태를 저장하고 접근할수있는 상태를 저장할 디렉토리를 지정한다. 
Detail 
  • This solution can be used in tandem with a process monitor/manager like monit, or just to enable manual recovery via restart.
  • While filesystem recovery seems straightforwardly better than not doing any recovery at all, this mode may be suboptimal for certain development or experimental purposes. In particular, killing a master via stop-master.sh does not clean up its recovery state, so whenever you start a new Master, it will enter recovery mode. This could increase the startup time by up to 1 minute if it needs to wait for all previously-registered Workers/clients to timeout.
  • While it’s not officially supported, you could mount an NFS directory as the recovery directory. If the original Master node dies completely, you could then start a Master on a different node, which would correctly recover all previously registered Workers/applications (equivalent to ZooKeeper recovery). Future applications will have to be able to find the new Master, however, in order to register.






Share this

Related Posts

Previous
Next Post »

1 개의 댓글:

Write 개의 댓글
2016년 11월 17일 오후 11:18 delete

설명해주신대로 따라했는데 클러스터 수동 실행 시
아래와 같이 noClassDefFound 에러가 납니다.
혹시 동일증상 없으셨나요?

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Logger
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

Reply
avatar