CDH 배포판 전용 Hadoop 2.6.0 라이브러리 충돌 이슈와 Maven 의존성 해결 (HDFS Browser)
과거 당사 빅데이터 솔루션 빅데이터 모니터링 플랫폼에는 수많은 데이터 엔지니어와 분석가들의 편의를 위해 UI 화면상에서 클릭만으로 HDFS 파일을 탐색하고 업로드/다운로드할 수 있는 웹 기반 HDFS Browser 기능 모듈이 포함되어 있었습니다.
이 기능을 백엔드(Java/Spring)에서 구현할 때 필수적인 것이 바로 아파치 하둡의 공식 라이브러리인 hadoop-common 및 hadoop-hdfs Java API 의존성(Dependency)입니다. 빌드 시에는 너무나 당연하게 당시 안정화 버전이었던 Vanilla Apache Hadoop 2.6.0 버전의 Maven Repository 의존성을 잡고 솔루션을 개발/컴파일했습니다.
하지만, CDH (Cloudera Distribution) 환경을 구축한 고객사 클러스터에 이 플랫폼 버전을 배포하고 HDFS Browser를 실행시키는 순간, 끔찍한 NoSuchMethodError와 ClassNotFoundException이 로그 화면을 뒤덮었습니다.
1. 발생 이슈: API 시그니처(Signature) 불일치
장애 원인을 뜯어보니 놀랍게도 “버전 명칭의 속임수”에 있었습니다.
CDH 5.13 플랫폼 시스템 내부에서 구동되는 오픈소스 하둡 버전도 분명 ‘Hadoop 2.6.0’이라고 표기하고 있었습니다. 하지만 이 버전은 아파치 재단에서 배포되는 순수한 바닐라(Vanilla) 버전이 아니라, Cloudera 사 내부에 존재하는 자체 리포지토리에서 수십 가지의 보안 패치 및 버그 수정을 커스텀으로 끼워 넣고 재컴파일한 독자적인 브랜치 버전(Hadoop 2.6.0-cdh5.13.0)이었습니다.
- 메이저/마이너 넘버(2.6.0)는 동일하지만, Cloudera 버전에서는 내부 Java 클래스의 알고리즘 메서드 파라미터 개수나 반환(Return) 타입이 임의로 변경되어 있는 케이스가 많았습니다.
- 바닐라 라이브러리에 링크되어 릴리즈된 플랫폼 솔루션(Jar/War)이, 고객사 서버 런타임에 깔린 Cloudera Hadoop 라이브러리 JAR와 클래스 로더 단위에서 충돌(Method Signature Mismatch)을 일으킨 전형적인 의존성 헬(Dependency Hell) 이슈였습니다.
2. 해결 방법: Maven Profile과 Provided Scope 활용
고객사에 설치될 하둡 생태계가 Hortonworks(현재는 Cloudera 통합)일지, 순수 Apache Hadoop일지, Cloudera CDH일지 예측할 수 없는 상황에서 단일 빌드본으로 대응하는 것은 불가능해졌습니다. 이에 개발 파이프라인을 다각화하기로 결정했습니다.
① 빌드 시스템(Maven Profile) 분리 적용
pom.xml 구성 단계에서 Maven Profile 기능을 활용하여 타겟 플랫폼별 프로필 속성을 만들었습니다.
<profiles>
<!-- Vanilla Hadoop 환경용 -->
<profile>
<id>vanilla-hadoop</id>
<properties>
<hadoop.version>2.6.0</hadoop.version>
</properties>
</profile>
<!-- CDH 환경용 -->
<profile>
<id>cloudera-hadoop</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<!-- Cloudera 전용 레포지토리 강제 주입 -->
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<properties>
<hadoop.version>2.6.0-cdh5.13.0</hadoop.version>
</properties>
</profile>
</profiles>이렇게 구성하여 CI/CD 라인을 태울 때 mvn clean install -Pcloudera-hadoop 커맨드로 CDH 전용 설치 파일 패키지를 따로 찍어내어 배포하도록 프로세스를 분리했습니다.
② Provided 특성 활용 및 클래스 로딩 최적화
또한, 하둡 관련 의존성은 결국 구동 환경 서버에 설치된(/opt/cloudera/parcels/CDH/lib/...) .jar 파일들을 시스템 환경변수 $HADOOP_CLASSPATH로 참조하는 것이 가장 완벽하고 이상적입니다.
의존 라이브러리 용량을 수십 MB씩 포함시켜 덩치를 키우며 묶어 배포(Fat Jar / War)하기보단, 아래와 같이 스코프를 제공 상태(provided)로 둡니다.
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
<scope>provided</scope>
</dependency>이를 통해 플랫폼 소스 코드는 컴파일 단계까지만 API 구문을 체크할 때 사용하고, 실제 구동 환경에서는 배포판 네이티브 라이브러리를 동적으로 링크(호환성 확보)하도록 아키텍처를 교정했습니다.
빅데이터 상용 배포판 위주로 돌아가는 B2B 솔루션 시장에서는 오픈소스의 표면적 버전을 넘어 숨겨진 코드 벤더 접미사(Postfix)와 전용 리포지토리에 대한 고찰이 필수적이라는 큰 교훈을 안겨준 이슈였습니다.