::: 데이터 분석 :::

Spark Application 패키지 작성하기 (1) - 전체 구조와 기본 설정

곰탱이푸우 2023. 9. 4. 08:20
기본적인 Scala 개발환경이 구축되고 나면 목표로 했던 Spark Application을 작성한다.
 
앞서 테스트에 사용한 Spark Application은 main 함수에 기능을 구현한 단순한 예제 프로그램이다.
기존에 Hadoop 기반의 Spark 클러스터를 구축했으므로, Spark Application은 해당 환경에서 실행할 수 있는 형태로 작성해야 한다.
 
따라서 Spark Application 작성을 위한 기본 형태 (Skeleton) 제공을 위한 예제 프로그램을 재작성한다.
참고로 예전에 실무에서 활용했던 Spark Application 코드에서 재사용 또는 공개가 가능한 코드만 활용하여 정리하였다.
 
전체적인 내용은 아래 문서를 참고하고, 변경 사항을 중심으로 정리한다.
전체 내용은 아래와 같은 순서로 작성한다.
  • 전체 구조와 기본 설정
  • 헬퍼 (Helper) 기능 작성
  • 데이터 처리 로직 작성
  • 비즈니스 로직 작성
  • 테스트 작성과 빌드, 배포

 

 

프로젝트 전체 구조

Spark Application을 위한 Scala 프로젝트의 전체 구조는 다음과 같다.
root
├─ .gitignore    # git commit에 제외할 목록 관리
├─ README.md    # Application 저장소의 이해를 돕기 위한 설명 파일
├─ build.sbt    # Application의 메타 정보, 의존성, 빌드, 배포 설정 관리
├─ project
│  └─ build.properties    # Application의 sbt 설정 관리
└─ src
  ├─ main    # Application의 기능 코드
  │  └─ scala    # 사용 언어
  │    └─ com/bearpooh/bdp/example/sparkexample    # 패키지 경로
  │        ├─ SparkExampleApp.scala
  │        ├─ application    # 요구 사항의 비즈니스 로직 정의
  │        │  └─ SparkExample.scala    #  실제 비즈니스 로직 구현
  │        ├─ util    # Application에 필요한 부가 기능 정의
  │        │  ├─ AppUtil.scala    # 로깅, 실행인자 처리 기능 정의
  │        │  ├─ ExampleUDF.scala (TDB)    # 필요시 User Define Function 정의
  │        │  └─ FileSystemHelper.scala    # Hadoop 파일 관리 기능 정의
  │        └─ models (TBD)    # Application에서 사용하는 데이터 스키마 정의
  │          └─ LogSchema.scala
  └─ test    # Application의 테스트 코드
      ├─ resources/data/log    # 테스트에 필요한 설정 파일 또는 데이터 파일
      │  └─ log.json
      └─ scala    # 사용 언어
        └─ com/bearpooh/bdp/example/sparkexample/application    # 패키지 경로
            └─ SparkExampleTest.scala    # SparkExample.scala의 테스트 코드​
 
models 폴더는 Application에서 사용하는 데이터의 스키마를 정의하는 파일을 저장하는 경로이다.
예제 코드에서는 단순한 파일을 사용해서 생성하지 않았다.
데이터 구조가 복잡해지거나 별도로 스키마를 정의하고 관리해야 하는 경우 해당 경로에 파일을 생성한다.
 
또한 ExampleUDF.scala 파일은 사용자 정의 함수 (User Define Function)를 정의할 때 사용한다.
예제 코드에서는 사용하지 않아서 생성하지 않았다.
간단한 UDF 코드는 비즈니스 로직에 포함하면 된다.
그러나 구조가 복잡하거나 양이 많아지면 별도 파일로 관리하는 것이 좋다.
 
기존에 작성했던 간단한 Spark Application 예제 구조에서 추가되거나 위치가 변경 된 사항은 다음과 같다.
구분
항목
내용
main/scala
application/SparkExample.scala
요구 사항의 비즈니스 로직 정의
main/scala
util/AppUtil.scala
로깅, 실행인자 처리 기능 정의
main/scala
util/FileSystemHelper.scala
Hadoop 파일 관리 기능 정의
test/resources
data/log/log.json
테스트에 사용할 미니 데이터 파일
test/scala
application/SparkExampleTest.scala
SparkExample.scala의 테스트 코드
 
기존에 작성했던 간단한 Spark Application 예제 구조에서 내용이 추가되거나 변경된 사항은 다음과 같다.
구분
항목
내용
root
build.sbt
Application의 메타 정보, 의존성, 빌드, 배포 설정 관리
main/scala
SparkExampleApp.scala
실행 인자 처리, 예외 처리, 비즈니스로직 호출
 
이후 내용들은 추가되거나 변경 된 파일들의 상세 내용을 중심으로 정리한다.
 
 

프로젝트 기본 설정

.gitignore와 README.md

.gitignore 작성

gitlab이나 github, bitbucket 같이 git 기반의 형상 관리에서 소스코드를 Commit 할때 불필요한 파일을 제외하는데 사용한다.
  • 최초 Skeleton (프로젝트 기본 구조)을 생성할 때 넣어주면 불필요한 파일을 초기부터 제외할 수 있다.
  • IDE (통합개발환경) 도구 관련 파일, 테스트 결과 파일, 빌드 과정 중 생성 된 파일들을 제외한다.
  • 작성하는 프로젝트 최상단 경로에 작성한다.
 
이미 불필요한 파일들이 Commit 된 경우
주의할 점은 불필요한 파일들이 이미 Commit 된 경우에는 제외되지 않는다.
이미 Commit 된 경우에는 불필요한 파일들을 모두 삭제하고 다시 Commit 해야 한다.
 
IntelliJ로 Spark Application을 작성할 때 필요한 .gitignore 파일은 다음과 같다.
IntelliJ의 프로젝트 설정 정보 폴더이거나, 프로젝트를 빌드할 때 생성되는 폴더이다.
/.bsp/
/.idea/
/project/project/
/project/target/
/target/

 

.gitignore 관련 문법과 사용법은 다음 사이트를 참고한다.
아래 사이트에서는 다양한 개발 언어의 .gitignore 템플릿을 참고할 수 있다.

README.md 작성

설치 방법, 사용법, 라이선스, 소스 코드 설명, 추가 설명 사항 등을 간단하게 기록하는 파일이다.
git 기반의 형상 관리 시스템에서 해당 프로젝트를 소개하는데 사용한다.
 
Markdown 언어를 사용하며 관련 내용은 아래 포스팅을 참고한다.
예전 개발 부서에 있을 때에는 주로 내부에서 사용하는 인하우스 프로그램을 작성해서 주로 다음 내용을 중심으로 생성했다.
# 프로그램 이름

### 개요
프로그램에 대한 간단한 소개

### 설치 방법
해당 프로그램을 설치하는 방법에 대한 소개

### 실행 방법
해당 프로그램의 각 기능별 사용 방법 소개
실행 예시와 결과도 포함하면 더 좋음

### 참고 사항
해당 프로그램 관한 참고 사항
- 개발 관련 문서 URL
- 외부 참고 문서 URL
- 향후 일정 관련 내용
- 오류 관련 Known-issue
 
위의 양식을 참고하여 필요한 사항을 중심으로 작성한다.

 

 

build.sbt와 build.properties

build.sbt

파이썬의 setup.py와 같이 어플리케이션의 기본 정보와 사용하는 라이브러리 정보들을 입력한다.
아래 정보들을 포함한다.
  • 해당 어플리케이션 프로젝트의 메타 정보 (이름, 버전, 조직, Scala 버전 등)
  • 의존성 라이브러리 버전 관리
  • 빌드와 배포 설정 정보
 
build.sbt에 대한 상세 정보는 아래 문서를 참고한다.
자세한 내용은 아래 주석을 참고한다.
import Keys._    // settings의 인자 부분의 설정 항목을 정의한 객체 사용 (sbt.SettingKey[String])

val sparkVersion = "3.2.3"    // 사용하는 Spark 버전

lazy val root = (project in file("."))    // 현재 경로를 기준으로 sbt 프로젝트 생성
  .settings(
    name := "sparkexample",    // Scala 프로젝트 이름
    version := "1.0.0.2-SNAPSHOT",    // Scala 프로젝트 버전
    versionScheme := Some("semver-spec"),    // 사용하는 버전 체계 (Semantic)
    organization := "com.bearpooh.bdp",    // 소속 조직 정보 입력
    scalaVersion := "2.12.18",    // 사용하는 Scala 버전
    libraryDependencies ++= Seq(    // 라이브러리 의존성 설정
      // Provided는 런타임에서 종속성 제공 (사용)
      // 이 프로젝트의 JAR 파일에 포함할 필요가 없음
      "org.apache.spark" %% "spark-core" % sparkVersion % Provided,    
      "org.apache.spark" %% "spark-sql" % sparkVersion % Provided,    
      "com.twitter" %% "util-app" % "22.12.0",   
      "org.scalatest" %% "scalatest" % "3.2.16" % "test"
    ),
    publishMavenStyle := true    // Java의 Maven 형식으로 배포
  )
 
versionScheme 항목에 대한 자세한 설명은 아래 항목을 참고한다.
libraryDependencies 항목에는 다음 라이브러리들을 설정했다.
  • spark-core, spark-sql (apache) - Spark의 기본 라이브러리 (필수)
  • util-app (twitter) - Scala Application의 실행 인자를 처리하는 라이브러리 (선택)
  • scalatest의 test (scalatest) - Scala Application의 테스트를 위한 라이브러리 (필수)
 
마지막으로 publishMavenStyle 옵션을 true로 설정해야 Nexus에 설정한 Maven 저장소에 배포할 수 있다.
저장소 설정 방법은 아래 문서를 참고한다.

build.properties

sbt 프로젝트에서 사용할 sbt의 버전을 지정한다.
 
다음과 같이 1.9.0 버전을 사용한다.
sbt.version = 1.9.0
 

헬퍼 기능 작성

헬퍼 (Helper) 기능 작성은 다음 문서를 참고한다.