Spark - Docker로 Spark Cluster + Jupyterlab 구성

2021. 7. 21. 11:44Spark

빅데이터를 공부하고 이쪽으로 직업을 가지길 원한다면 한번쯤 들어봤을 Spark를 Docker를 이용하여 쉽고 빠르게 구성해 보도록 하겠다. 만약 Spark에 대해서 알지 못하는 분이라면 아래 링크를 통해 가볍게 Spark가 무엇인지 알아보고 시작하자.

 

Apache Spark 란..

 

설치할 Spark와 Jupyterlab의 버전은 아래와 같다.

 

  1. Spark : 3.1.1
  2. Simulated HDFS : 3.2
  3. Jupyterlab : 2.1.5

자 시작하기 앞서 이들을 구성하는 구성도를 한번 살펴 보자.

 

1. Spark 구성도

 

Spark Cluster 구성

먼저 Spark Master를 생성해 주고 이를 Localhost에 8080 Port에 얹어 준다. 그 다음 두개의 Worker를 구성하여 각각 8081 / 8082 Port에 얹어 준다. 

 

그리고 Spark Code를 원활하게 실행할 JupyterLab을 8888포트에 올려 준비한다. 

 

여기서 질문. 그렇다면 Jupyter는 과연 어떻게 Spark Cluster와 연결하는가 이것은 마지막 예제를 통해 알 수 있으니 끝가지 정독 해보기를 바란다..

 

2. Docker 구성도

Docker 이미지 구성

3. Docker File 구성 

1. cluster-base

ARG debian_buster_image_tag=8-jre-slim
FROM openjdk:${debian_buster_image_tag}

# -- Layer: OS + Python 3.7

ARG shared_workspace=/opt/workspace

RUN mkdir -p ${shared_workspace} && \
    apt-get update -y && \
    apt-get install -y python3 && \
    apt-get install -y python3-pip && \
    ln -s /usr/bin/python3 /usr/bin/python && \
    rm -rf /var/lib/apt/lists/*

ENV SHARED_WORKSPACE=${shared_workspace}

# -- Runtime

VOLUME ${shared_workspace}
CMD ["bash"]

 

Docker file로 설치가 되다보니 필수요소가 굉장히 많이 누락되어 있다. 예를들면 wget같은.. 그런경우 중간 RUN을 활용하여 설치 명령어를 넣어주면 Image생성후 귀찮음을 덜어낼 수 있다. 

 

PIP가 아니라 PIP3로 설치가 된걸 확인할 수 있다. 만약 나중에 추가적으로 라이브러리를 설치하려 한다면 pip3를 이용하도록 하자.

 

2. spark-base

FROM cluster-base

# -- Layer: Apache Spark

ARG spark_version=3.1.1
ARG hadoop_version=3.2

RUN apt-get update -y && \
    pip3 install --upgrade pip setuptools wheel &&\
    pip3 install pandas &&\
    pip3 install scikit-learn==0.22.1 &&\
    pip3 install tensorflow &&\
    pip3 install torch &&\
    apt-get install -y curl && \
    curl https://archive.apache.org/dist/spark/spark-${spark_version}/spark-${spark_version}-bin-hadoop${hadoop_version}.tgz -o spark.tgz && \
    tar -xf spark.tgz && \
    mv spark-${spark_version}-bin-hadoop${hadoop_version} /usr/bin/ && \
    mkdir /usr/bin/spark-${spark_version}-bin-hadoop${hadoop_version}/logs && \
    rm spark.tgz

ENV SPARK_HOME /usr/bin/spark-${spark_version}-bin-hadoop${hadoop_version}
ENV SPARK_MASTER_HOST spark-master
ENV SPARK_MASTER_PORT 7077
ENV PYSPARK_PYTHON python3

# -- Runtime

WORKDIR ${SPARK_HOME}

기본적으로 많이 활용하는 Scikit-Learn / Tensorflow / Pytorch 등을 추가로 설치했는데 만약 필요없다면 

pip3 install부분을 빼서 진행해도 된다...

 

3. spark-master

FROM spark-base

# -- Runtime

ARG spark_master_web_ui=8080

EXPOSE ${spark_master_web_ui} ${SPARK_MASTER_PORT}
CMD bin/spark-class org.apache.spark.deploy.master.Master >> logs/spark-master.out

별거 없다 쭉넘어가자

Spark ui Port설정 및 spark cluster 배포 로그 설정 등이 포함되어 있다. 

 

4. spark-worker

FROM spark-base

# -- Runtime

ARG spark_worker_web_ui=8081

EXPOSE ${spark_worker_web_ui}
CMD bin/spark-class org.apache.spark.deploy.worker.Worker spark://${SPARK_MASTER_HOST}:${SPARK_MASTER_PORT} >> logs/spark-worker.out

마찬가지로 거의 비슷하다. 

Spark ui Port설정 및 Spark Master 연동 Port 설정, spark cluster 배포 로그 설정 등이 포함되어 있다. 

 

여기서는 8081로 만들고 차후 Docker-compose로 엮어 생성 할때는 Worker별로 Port를 변경하여 사용한다.

 

5. jupyterlab

FROM cluster-base

# -- Layer: JupyterLab

ARG spark_version=3.1.1
ARG jupyterlab_version=2.1.5

RUN apt-get update -y && \
    apt-get install -y python3-pip && \
    pip3 install --upgrade pip setuptools wheel &&\
    pip3 install pandas &&\
    pip3 install scikit-learn==0.22.1 &&\
    pip3 install tensorflow &&\
    pip3 install torch &&\
    pip3 install wget pyspark==${spark_version} jupyterlab==${jupyterlab_version}

# -- Runtime

EXPOSE 8888
WORKDIR ${SHARED_WORKSPACE}
CMD jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --NotebookApp.token=

여기도 마찬가지로 

기본적으로 많이 활용하는 Scikit-Learn / Tensorflow / Pytorch 등을 추가로 설치했는데 만약 필요없다면

pip3 install부분을 빼서 진행해도 된다...

 

Jupyter를 활용하기 위한 Port설정과 Spark / HDFS 설정 및 접속시 Token 설정등이 들어있다.

 

3. Docker Image 생성 

# -- Building the Images

docker build \
  -f cluster-base.Dockerfile \
  -t cluster-base .

docker build \
  --build-arg spark_version="3.1.1" \
  --build-arg hadoop_version="3.2" \
  -f spark-base.Dockerfile \
  -t spark-base .

docker build \
  -f spark-master.Dockerfile \
  -t spark-master .

docker build \
  -f spark-worker.Dockerfile \
  -t spark-worker .

docker build \
  --build-arg spark_version="3.1.1" \
  --build-arg jupyterlab_version="2.1.5" \
  -f jupyterlab.Dockerfile \
  -t jupyterlab .

만일 다른 버전을 원한다면 Dockerfile 및 생성 명령어의 버전을 수정해주면 된다. 

 

4. Docker-compose 구성 

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
  spark-master:
    image: spark-master
    container_name: spark-master
    ports:
      - 8080:8080
      - 7077:7077
    volumes:
      - shared-workspace:/opt/workspace
  spark-worker-1:
    image: spark-worker
    container_name: spark-worker-1
    environment:
      SPARK_WORKER_CORES: "1"
      SPARK_WORKER_MEMORY: "1024m"
    ports:
      - 8081:8081
    volumes:
      - shared-workspace:/opt/workspace
    depends_on:
      - spark-master
  spark-worker-2:
    image: spark-worker
    container_name: spark-worker-2
    environment:
      SPARK_WORKER_CORES: "1"
      SPARK_WORKER_MEMORY: "1024m"
    ports:
      - 8082:8081
    volumes:
      - shared-workspace:/opt/workspace
    depends_on:
      - spark-master

 

이렇게 Docker-compose를 구성하고

 

docker-compose up -d로 해당 파일을 실행하면 대간의 설치가 끝난다.

 

이후 내부 설정이나 필요한 Jar file들은 구성해야 하겠지만 기본적인 설치는 여기가 마지막이다. 이제 예제 코드를 실행해 보자..

 

5. 예제 코드 실행

from pyspark.sql import SparkSession

spark = SparkSession.\
        builder.\
        appName("pyspark-notebook").\
        master("spark://spark-master:7077").\
        config("spark.executor.memory", "512m").\
        getOrCreate

여기서 보면  Master를 지정하여 해당 Spark Session의 위치를 정해주고 생성을 하게된다. 

Master에 우리가 Compose file을 생성할때 지정해준 Spark Master의 7077 Port를 통해서 Session을 생성하고 관리한다.

 

해당 Session이 사용할 메모리용량 등을 설정하고 

import wget

url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
wget.download(url)

예제 CSV를 받아온다.

data = spark.read.csv("iris.data")
data.show(n=5)

Spark Dataset을 생성하고 Show를 이용하여 확인하면 끝!

 

 

 

유용하게 활용하기를 바라며 글 마칩니다.

 

참고 : https://www.kdnuggets.com/2020/07/apache-spark-cluster-docker.html