0. 배경
이번에는 Spark Cluster를 docker swarm을 사용하여 구축했던 과정을 기록하려 합니다.
Spark Cluster를 왜 도커 스웜 위..? 🤔 라고 묻는다면... 난처하다!
이 환경을 구축하였을 때의 상황은,
Spark 도입이 필요함
(User): 운영자님! 지금 프로그램이 계속 에러가 납니다. 고쳐주세요!
(Me): (dmesg 로그 확인 후) 음... Out Of Memory Killer (OOM) 이 프로그램을 강제 종료하였네요 ! 파일이 200GB를 넘어가서 그러네요..
대용량의 데이터를 처리하는 프로그램이 있었는데, 처음에는 60GB 이내의 데이터를 처리할 것을 예상하고 개발을 하였었다.
하지만 데이터가 점점 커지면서 한대의 컴퓨터에서 multi-threading 혹은 processing으로 처리할 수 없는 지경에 이루었다.
결국 Spark의 입이 시급하였다.
Docker Swarm을 사용한 이유
(Me): 팀장님! 이 프로그램은 대용량의 데이터 처리가 필요합니다. Spark의 도입이 시급한 것 같습니다.
(팀장): 그러면, 지금 당장은 가용한 서버가 많지 않고, 개발용 피씨 4대 있으니까 한번 개발 해보고 P.O.C 를 좀 보자
(Me): 지금 개발용 피씨에 Kubernetes환경이 없을 뿐더러 A과장, B대리, 그리고 C대리도 사용중입니다 🤔
(팀장): 알아서 해봐!
하지만, 이런 저런 이유로 Kubernetes 도입이 당장은 어려웠다.
(시간도 부족했고, 원활한 kubernetes운용을 위한 storage class를 설치하기 위해서는 disk 포멧이 필요하기에 현재 개발용으로 열심히 돌아가는 컴퓨팅 노드들의 디스크를 포멧하기에는 어려움이 있었다.)
그래서!
지금 당장 쉽게 spark cluster를 개발용으로 테스트해보기 위해 docker swarm을 구성해 보기로 결정하였다.
spark가 그렇게 좋아? 어디 한번 빠르게 보여줘봐! 에 대응하기 위함 이었달까!
docker swarm에 스파크 클러스터를 구축하는 글은 인터넷에 거의 없었다.
하지만 앞서 docker-compose를 통하여 single node에서 구축했던 경험을 살려 예상보다 빠르게 (하루 종일) 구축에 성공하였다.
1. Docker Swarm 구축
마스터 노드에서,
docker swarm init --advertise-addr 10.12.168.78
위 명령어를 치면 token 값이 나온다.
만약 token 값을 까먹었다면, docker swarm join-token worker 명령어를 통해 획득할 수 있다.
워커 노드들에서,
docker swarm join --token SWMTKN-1-2vbvlj5q06s4q88leovc94v2l1jcxq0ms2v6aspjhyf69e1ewx-88bzmrt3kkslr1i69nhlwuw12 10.12.168.78:2377
마스터 노드에서 워커 노드들이 잘 붙었는지 확인해보자.
docker node ls
spark를 구동하기 위한 overlay 네트워크를 만들자
docker network create --driver=overlay --attachable spark-net
node에 label을 달아주자. (추후 runtime 시점에서 해당 node label에 따라 실행이 될 것이다)
docker node update --label-add type=sparkmaster ${master_hostname}
docker node update --label-add type=sparkworker ${worker_hostname}
2. Docker registry 구축
docker-swarm으로 묶인 노드들에게 이미지를 공유할 수 있도록 registry를 구축해보자.
docker-swarm 마스터 노드에서
docker service create --name registry -p 5000:5000 registry:2
https가 아닌 insecure한 도커 레지스트리이기 때문에 각 도커 데몬 설정에서 우리가 만든 레지스트리는 써도 괜찮아~를 해야한다.
모든 노드의 /etc/docker/daemon.json
여기서 10.12.168.78:5000은 마스터 노드의 아이피와 도커 레지스트리의 포트이다. 본인의 아이피와 포트에 맞게 변경하자
{
"insecure-registries": ["10.12.168.78:5000"]
}
3. Docker registry에 이미지 push
3-1. spark images build
전 포스팅을 참고하길 바란다. https://ampersandor.tistory.com/11
3-2. spark images push
private registry에 push를 하기 위하여 tag를 달아주자.
docker tag spark-master 10.12.168.78:5000/spark-master
docker tag spark-worker 10.12.168.78:5000/spark-worker
docker push 10.12.168.78:5000/spark-master
docker push 10.12.168.78:5000/spark-worker
4. Docker Stack Deploy
4-1. docker-compose.yml 작성
전 포스팅과 다르게 deploy와 networks 파트가 생겼다. deploy를 통해 어떤 레이블이 달린 node에서 실행이 될지 설정할 수 있으며 overlay network인 우리가 만든 spark-net을 통해 서로 통신이 될 수 있도록 하자.
version: "3.6"
volumes:
shared-workspace:
name: "hadoop-distributed-file-system"
driver: local
services:
jupyterlab:
image: jupyterlab
container_name: jupyterlab
ports:
- 8888:8888
volumes:
- shared-workspace:/opt/workspace
deploy:
replicas: 1
placement:
constraints: [node.labels.type==sparkmaster]
networks:
- spark-net
spark-master:
image: spark-master
container_name: spark-master
ports:
- 4040:8080
- 7077:7077
volumes:
- shared-workspace:/opt/workspace
deploy:
replicas: 1
placement:
constraints: [node.labels.type==sparkmaster]
networks:
- spark-net
spark-worker-1:
image: spark-worker
container_name: spark-worker-1
environment:
- SPARK_WORKER_CORES=1
- SPARK_WORKER_MEMORY=512m
ports:
- 4041:8081
volumes:
- shared-workspace:/opt/workspace
depends_on:
- spark-master
deploy:
replicas: 1
placement:
constraints: [node.labels.type==sparkworker]
networks:
- spark-net
4-2. deploy to docker swarm
on master node,
docker stack deploy --compose-file docker-compose.yml spark-cluster
docker stack services spark-cluster
5. Check
5-1. check status
## Service Check ##
docker stack services spark-cluster
docker service ls
docker service inspect spark-cluster_spark-master --pretty
docker service inspect spark-cluster_spark-worker --pretty
## Check Logs ##
docker service logs spark-cluster_spark-master
## Network Check ##
docker network ls
docker network inspect spark-cluster_spark-net
## Volume Check ##
docker volume ls
docker volume inspect hadoop-distributed-file-system
## Stack Remove ##
docker stack rm spark-cluster
5-2. scale
docker service scale spark-cluster_spark-worker=20
5-3. useful command
docker exec -it `docker ps --filter name=spark-worker --format "{{.ID}}"` /bin/bash
HDFS 구축
이 포스팅을 참고하여 hdfs를 구성해보자!
Spark Submit
export SPARK_LOCAL_IP=10.12.168.78
export SPARK_DRIVER_HOST=10.5.0.6
export SPARK_HOME=/opt/spark-3.0.0-bin-hadoop2.7
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin
$SPARK_HOME/bin/spark-submit --master spark://10.12.168.78:7077 /home/dhkim4/seecorona/test.py
'Data Engineer > spark' 카테고리의 다른 글
[Spark] 클러스터 구축 docker-compose, standalone (2/5) (0) | 2023.08.23 |
---|---|
[Spark] 로컬에서 돌려보기, standalone (1/5) (0) | 2022.12.27 |