-
Spark JAR에 대해 연구해보자... 너는 무엇을 하는 아이니[IT] 공부하는 개발자/Data - ALL 2024. 12. 12. 15:02
저는 스프링 백엔드 개발자로 커리어를 시작해서 6년차에 MLOps 엔지니어로 커리어 체인지를 했습니다. 그리고 8년차에는 데이터 플랫폼 엔지니어로 이직을 했습니다.
하........ 옮겨다닐때마다 아가가 되는 기분... 특히 요즘은 부족함을 매일 매일 느껴요....ㅠ
응애응애
하루에 한 개씩 배우다보면 저도 언젠간....... 잘하게 되겠죠..?!
배우는것에서 멈추지 않고 포스팅 기록으로 남겨서 잊어버리지 않게 합시다!
오늘은 Spark JAR 관련 트러블슈팅한 것을 계기로 Spark JAR에 대한 포스팅을 작성합니다.
Spark JAR는 Apache Spark 애플리케이션을 실행하기 위해 필요한 자바 아카이브(Java Archive) 파일입니다. Spark 애플리케이션의 코드를 배포하고 실행 환경에 필요한 의존성을 포함하거나 연결하는 데 사용됩니다.
1. Spark JAR의 역할과 필요성
(1) Spark 애플리케이션 코드 배포
- Spark JAR는 Spark 애플리케이션의 코드를 포함하며, Spark 클러스터의 Driver와 Executor 노드에 코드를 전달하는 데 사용됩니다.
- 예를 들어, Scala 또는 Java로 작성한 Spark 애플리케이션은 컴파일 후 JAR 파일로 패키징하여 배포됩니다.
(2) Spark 의존성 관리
- 애플리케이션 실행 시 필요한 라이브러리나 외부 의존성을 포함.
- 예: HDFS, Kafka, JDBC 드라이버 등 의존성 포함
- 필요한 의존성을 포함하지 않으면 실행 중 ClassNotFoundException과 같은 에러가 발생할 수 있습니다.
- 애플리케이션에서 Kafka 라이브러리를 사용해서 코드를 짰는데.... Kafka jar를 안 넣었다고오?~~!?
(3) 애플리케이션 실행 제어
- 애플리케이션 코드
- Spark 작업(Transformation, Action 등)을 정의한 로직을 전달하여 클러스터에서 실행.
- 클러스터 환경에서 애플리케이션이 올바르게 동작하도록 필요한 리소스를 제공.
(4) 코드와 데이터의 분리
- 데이터는 클러스터(HDFS, S3 등)에 저장되고, JAR은 데이터에 접근,처리하는 로직을 제공.
2. Spark JAR 파일 생성 및 사용
(1) JAR 파일 생성
- Spark 애플리케이션은 일반적으로 Scala나 Java로 작성됩니다.
- 코드를 컴파일하고 JAR 파일로 패키징:
- ex) super-blogger-1.0.jar (웹 데이터를 긁어와서 요약 포스팅을 만드는 슈퍼 블로거 앱을 개발해서 빌드했다..!)
(2) Spark JAR 파일 실행
- Spark 애플리케이션을 실행할 때 spark-submit 명령어로 JAR 파일을 제출: (옵션들은 다음 소제목에서 자세히 살펴봅니다)
bash spark-submit \ --class com.example.MainClass \ --master yarn \ --deploy-mode cluster \ --jars external-lib.jar \ super-blogger-1.0.jar
슈퍼 블로거 앱을 스파크에 제출했다아!!!!!
3. Spark JAR 관련 주요 옵션
(1) --class
- JAR 파일에 포함된 **메인 클래스(main class)**를 지정.
- 예: --class com.example.MainClass
(2) --jars
- 실행 시 필요한 추가 JAR 파일을 지정.
- 여러 JAR 파일을 쉼표로 구분:
- 예: --jars hdfs:///libs/lib1.jar,hdfs:///libs/lib2.jar
(3) --packages
- Maven Central Repository에서 의존성을 자동으로 다운로드
- 예) --packages org.apache.spark:spark-sql-kafka-0-10_2.12:3.3.0
(4) --files
- 실행 중에 필요한 설정 파일이나 데이터 파일 추가:
- 예) --files config.json
4. Spark JAR을 사용하는 이유
(1) 클러스터에서 코드 전달
- 일을 시켜야겠죠..? 말하자면 요건 정의서
- Spark는 애플리케이션 코드를 Driver와 Executor에 전달해야 합니다.
- JAR 파일은 이 코드를 포함하며, Spark가 이를 클러스터 노드에 배포합니다.
(2) 외부 라이브러리 포함
- Spark는 특정 작업에 대해 추가 라이브러리가 필요합니다.
- 예: Kafka를 사용한 데이터 스트리밍 작업에는 spark-sql-kafka 의존성이 필요.
- JAR 파일에 이러한 라이브러리를 포함하여 애플리케이션과 함께 배포.
(3) 실행 환경 표준화
- JAR 파일은 모든 의존성을 포함하도록 설정할 수 있어 실행 환경 간의 불일치를 최소화.
- "작성한 코드가 내 로컬에서는 실행되지만 클러스터에서는 실행되지 않는 문제"를 방지
5. Spark JAR과 의존성 관리
Spark JAR은 두 가지 형태로 의존성을 포함할 수 있습니다:
(1) Fat JAR (Uber JAR)
- 애플리케이션 코드와 모든 의존성을 하나의 JAR 파일로 패키징.
- Maven의 shade 플러그인 또는 SBT의 assembly 플러그인을 사용.
" 팻 자르 " => 실무에서 많이 쓰는 용어! (소근소근)
(2) Thin JAR
- 애플리케이션 코드만 포함하며, 의존성은 별도로 제공.
- 실행 시 --jars나 --packages 옵션으로 필요한 의존성을 전달.
6. Spark JAR을 통한 작업 흐름
- 애플리케이션 작성:
- Scala, Java, 또는 Python으로 Spark 애플리케이션 작성.
- Scala, Java, 또는 Python으로 Spark 애플리케이션 작성.
- JAR 파일 생성:
- 작성한 코드를 컴파일하고 JAR로 패키징.
- 작성한 코드를 컴파일하고 JAR로 패키징.
- Spark 클러스터에 JAR 파일 제출:
- spark-submit 명령어를 사용하여 JAR 파일을 클러스터로 전달.
- spark-submit 명령어를 사용하여 JAR 파일을 클러스터로 전달.
- Driver와 Executor 실행:
- Driver가 JAR 파일의 코드를 사용해 작업을 스케줄링.
- Executor가 작업을 실행하며 필요한 코드를 JAR 파일에서 로드.
7. 결론
Spark JAR은 Spark 애플리케이션 배포의 핵심 요소로, 코드와 의존성을 포함하여 클러스터에서 실행됩니다. 이를 통해 작업 흐름이 표준화되고, 데이터 처리 로직이 클러스터 노드에 원활히 전달됩니다. 적절한 JAR 파일 관리와 설정으로 애플리케이션의 안정성과 확장성을 높일 수 있습니다
8. 트러블슈팅 경험
문제 상황
스파크에 job submit 후, NoSuchMethodError 메소드 에러가 발생
해석
1. jar안에 디펜던시가 아예 없다
2. jar안에 다른 버전을 사용하는 동일한 디펜던시 여러개가 포함되어 충돌하고 있다
해결
이 문제를 해결하기 위해서는 도대체 스파크가 무슨 JAR을 보고 있는지를 알아야 했다.
Yarn resource manager UI에 들어가서, environments 메뉴에서, 스파크가 로드한 System classpath를 확인하였다.
=> 아니 내가 제출한 jar가 아닌것 같은데?! 왜 이것을 보고 있니?
답은 모드에 있었다.
스파크 실행 모드가 cluster모드가 아니라 client모드여서 hdfs의 archive JAR을 읽어오지 않고 local JAR을 참조하고 있었음.
스파크 실행 모드를 cluster모드로 바꾸자, 스파크는 내가 제출한(의도한) JAR을 참조하여 Driver와 Executor에 잘 나눠주었다.
'[IT] 공부하는 개발자 > Data - ALL' 카테고리의 다른 글
데이터 레이크하우스 아키텍처 (3) 2024.12.10 [Kafka] 카프카의 실전 서비스 운영 (1) 2024.09.18 [Hive] 하이브 핵심정리 (1) 2023.10.19 Zeppelin 과 Notebook 비교, 어떤 것을 고를까? (1) 2023.05.18 [Streamlit] 설치 단계에서 발생한 이슈와 해결방법 정리 (0) 2023.04.16