windows 운영체제의 intellij에 scala spark app 개발환경 구축 및 spark app jar 파일 만들어보기

2020-11-16

.

Data_Engineering_TIL(20201116)

[학습 시 참고한 자료]

  • 블로그글 ‘IntelliJ + Maven + Scala 으로 Jar 파일 만들기’

https://alphahackerhan.tistory.com/10?category=644422

  • 블로그글 ‘아파치 스파크 개발 환경 구축 및 예제 실습 - IntelliJ + Maven + Scala + Mac’

https://alphahackerhan.tistory.com/8?category=644422

[실습목표]

windows local 환경에 scala spark application 개발환경을 구성해 간단한 application을 개발하고 scala spark .jar를 만들어보자

[실습내용]

step 1) intellij 다운로드 및 설치

https://www.jetbrains.com/ko-kr/idea/download/#section=windows 링크에서 community 용으로 intellij를 다운받아서 설치한다.

step 2) open jdk 1.8 install

https://github.com/ojdkbuild/ojdkbuild 에서 Downloads for Windows x86_64 메뉴에서 java-1.8.0-openjdk-1.8.0.275-1.b01.ojdkbuild.windows.x86_64.msi 를 다운로드 받는다.

그런 다음에 다운로드 받은 설치파일을 실행해서 설치한다.

step 2) scala plugin 설치

아래 그림과 같이 scala plugin을 설치해준다.

1

step 3) scala project 생성

2

위에 pom.xml을 아래와 같은 pom.xml 으로 replace 해주고 새로고침 버튼을 누르면 해당 의존성들을 다운받게 된다.

** 나의 scala spark app 버전정보 : spark 3.0.0, scala 2.12.12

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ScalaLast</artifactId>
    <version>1.0</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>3.0.0</version>
        </dependency>
    </dependencies>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>scala-maven-plugin</artifactId>
                    <version>3.2.1</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.0.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

step 4) 생성한 프로젝트에 scala jdk를 아래와 같이 설정해준다.

3

그런 다음에 intellij(프로젝트)를 껐다가 다시 실행해서 해당 프로젝트 화면으로 돌아와준다.

그런 다음에 아래와 같이 scala script가 들어갈 object를 생성해준다.

4

step 5) 나의 scala spark application 작성

아래 코드처럼 object 부분을 수정해준다.

그런 다음에 아래 코드와 같이 수정하고 좌측 메뉴에서 object 파일명도 똑같이 TestApp으로 변경해준다.

또한 참고로 windows 로컬피시에서 테스트하려면 winutils라는게 필요한데

https://github.com/steveloughran/winutils 에서 스팍버전에 맞는 winutils를 다운로드 받아서

winutils.exe is copied to C:\winutil\bin\ 또는 아무폴더에서 bin/winutils.exe로 넣어주고 아래와 같이 경로를 잡아줘야 한다.

  • my_scala_app_for_windows_local
import org.apache.spark.sql.SparkSession

object TestApp {

  def main(args: Array[String]): Unit = {
    System.setProperty("hadoop.home.dir", "C:\\Users\\User\\Downloads")

    val spark = SparkSession.builder.master("local").appName("my_app").getOrCreate()
    
    val rdd = spark.read.textFile("C:\\Users\\User\\Downloads\\README.txt")

    rdd.write.format("parquet").save("C:\\Users\\User\\Downloads\\test_folder")

    println("Job done")
    spark.stop()

    System.exit(0)

  }
}

위의 코드를 실행하면 아래와 같이 실행결과를 확인할 수 있다.

5

application 실행 output으로 지정된 폴더로 이동하면 파일이 생성된 것을 확인할 수 있을것이다.

그러면 이렇게 작동이 잘 되는 코드를 EMR에서도 실행할 수 있도록 코드를 아래와 같이 변경하고 이거를 .jar 파일로 만들어서 EMR에서 실행시켜보자

먼저 아래와 같이 코드를 변경한다.

  • my_scala_app_for_emr
import org.apache.spark.sql.SparkSession

object TestApp {

  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder.master("yarn").appName("my_app").getOrCreate()
    
    val rdd = spark.read.textFile("s3://pms-bucket-test/README.txt")

    rdd.write.format("parquet").save("s3://pms-bucket-test/test_folder")

    println("Job done")
    spark.stop()

    System.exit(0)

  }
}

그런 다음에 아래 그림과 같이 maven 을 이용하여 pakage 생성(.jar 파일 생성)한다. 그래서 아래 그림과 같이 클래스 파일과 jar 파일이 잘 생성되는지 확인한다 그리고 이 파일을 원하는 s3 버킷에 업로드 시킨다.

6

step 8) EMR에서 spark-submit 해보기

임의의 EMR 생성후 마스터 노드에 위에서 생성한 프로젝트 폴더를 업로드하고 아래와 같이 정상적으로 우리가 만든 application이 실행되는지 확인해본다.

application 실행후 output으로 지정된 버킷의 폴더로 이동하면 파일이 생성된 것을 확인할 수 있을것이다.

[hadoop@ip-10-0-1-72 target]$ pwd
/home/hadoop/ScalaLast/target

[hadoop@ip-10-0-1-72 target]$ ls
classes  classes.-1055002700.timestamp  maven-archiver  ScalaLast-1.0.jar

[hadoop@ip-10-0-1-72 target]$ spark-submit --class TestApp ScalaLast-1.0.jar
20/11/16 13:45:05 INFO SparkContext: Running Spark version 3.0.0-amzn-0
20/11/16 13:45:05 INFO ResourceUtils: ==============================================================
20/11/16 13:45:05 INFO ResourceUtils: Resources for spark.driver:

20/11/16 13:45:05 INFO ResourceUtils: ==============================================================
20/11/16 13:45:05 INFO SparkContext: Submitted application: my_app
20/11/16 13:45:06 INFO SecurityManager: Changing view acls to: hadoop
20/11/16 13:45:06 INFO SecurityManager: Changing modify acls to: hadoop
20/11/16 13:45:06 INFO SecurityManager: Changing view acls groups to:
20/11/16 13:45:06 INFO SecurityManager: Changing modify acls groups to:
20/11/16 13:45:06 INFO SecurityManager: SecurityManager: authentication disabled; ui acls disabled; users  with view permissions: Set(hadoop); groups with view permissions: Set(); users  with modify permissions: Set(hadoop); groups with modify permissions: Set()
20/11/16 13:45:06 INFO Utils: Successfully started service 'sparkDriver' on port 41551.


...

20/11/16 13:45:22 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
20/11/16 13:45:22 INFO SparkContext: Successfully stopped SparkContext
20/11/16 13:45:22 INFO ShutdownHookManager: Shutdown hook called
20/11/16 13:45:22 INFO ShutdownHookManager: Deleting directory /mnt/tmp/spark-f463f845-337d-43e5-a7df-5980fda7e788
20/11/16 13:45:22 INFO ShutdownHookManager: Deleting directory /mnt/tmp/spark-2f664e04-a245-469f-9ce3-d703f02ac9eb