고급 구성
고급 구성 (Advanced Configuration)
Flink 배포판의 구조, Scala 버전, Table 의존성, Hadoop 의존성에 대해 설명해요. 클래스패스 구성과 플래너 선택을 이해하는 데 도움이 되는 내용이에요.
본문
Anatomy of the Flink distribution
Flink 자체는 Flink 런타임의 핵심을 형성하는 클래스와 의존성 집합으로 구성되며, Flink 애플리케이션이 시작될 때 반드시 존재해야 해요. 시스템을 실행하는 데 필요한 클래스와 의존성은 조정(coordination), 네트워킹, 체크포인팅, 장애 조치, API, 연산자(예: 윈도우 처리), 리소스 관리 등의 영역을 처리해요.
이 핵심 클래스와 의존성은 flink-dist.jar에 패키징되는데, 다운로드한 배포판의 /lib 폴더에 있고 기본 Flink 컨테이너 이미지의 일부예요. 이 의존성은 String·List 같은 클래스를 포함하는 Java의 핵심 라이브러리와 유사하다고 생각할 수 있어요.
핵심 의존성을 최대한 작게 유지하고 의존성 충돌을 피하기 위해, Flink Core Dependencies는 클래스패스에 과도한 기본 클래스·의존성 수가 생기는 것을 피하려고 커넥터나 라이브러리(즉 CEP, SQL, ML)를 포함하지 않아요.
Flink 배포판의 /lib 디렉토리는 Table 잡을 실행하는 데 필요한 모듈과 일부 커넥터·포맷 세트처럼 흔히 사용되는 모듈을 포함한 다양한 JAR을 추가로 담아요. 이들은 기본으로 로드되며 /lib 폴더에서 제거하기만 하면 클래스패스에서 제거할 수 있어요.
Flink는 /opt 폴더 아래에 추가 선택적 의존성도 제공하는데, JAR을 /lib 폴더로 이동하면 활성화돼요.
클래스로딩에 대한 자세한 내용은 Classloading in Flink 섹션을 참고하세요.
Scala Versions
서로 다른 Scala 버전은 서로 바이너리 호환되지 않아요. (전이적으로) Scala에 의존하는 모든 Flink 의존성은 빌드 대상인 Scala 버전이 접미사로 붙어요(즉 flink-table-api-scala-bridge_2.12).
Flink의 Java API만 사용한다면 어떤 Scala 버전도 사용할 수 있어요. Flink의 Scala API를 사용한다면 애플리케이션의 Scala 버전과 일치하는 Scala 버전을 선택해야 해요.
특정 Scala 버전으로 Flink를 빌드하는 방법은 build guide를 참고하세요.
2.12.8 이후의 Scala 버전은 이전 2.12.x 버전과 바이너리 호환되지 않아요. 이는 Flink 프로젝트가 2.12.x 빌드를 2.12.8 이상으로 업그레이드하는 것을 막아요. 더 나중의 Scala 버전을 위해 Flink를 로컬에서 빌드하려면 build guide를 따르세요. 이렇게 하려면 빌드 시 바이너리 호환성 검사를 건너뛰도록 -Djapicmp.skip을 추가해야 해요.
자세한 내용은 Scala 2.12.8 release notes를 참고하세요. 관련 섹션은 다음과 같아요:
The second fix is not binary compatible: the 2.12.8 compiler omits certain methods that are generated by earlier 2.12 compilers. However, we believe that these methods are never used and existing compiled code will continue to work. See the pull request description for more details.
Anatomy of Table Dependencies
Flink 배포판은 기본적으로 Flink SQL 잡을 실행하는 데 필요한 JAR(/lib 폴더에 있음)를 포함하며, 특히:
flink-table-api-java-uber-${flink.version}.jar→ 모든 Java API 포함flink-table-runtime-${flink.version}.jar→ table 런타임 포함flink-table-planner-loader-${flink.version}.jar→ 쿼리 플래너 포함
경고: 이전에는 이 JAR들이 모두
flink-table.jar에 패키징되었어요. Flink 1.15부터 사용자가flink-table-planner-loader-${flink.version}.jar를flink-table-planner_${scala.version}-${flink.version}.jar로 교체할 수 있도록 세 개의 JAR로 분리되었어요.
Table Java API 아티팩트는 배포판에 빌드되지만, Table Scala API 아티팩트는 기본적으로 포함되지 않아요. Flink Scala API에서 포맷·커넥터를 사용할 때는 이 JAR을 수동으로 다운로드해 배포판 /lib 폴더에 포함하거나(권장), Flink SQL 잡의 uber/fat JAR에 의존성으로 패키징해야 해요.
자세한 내용은 외부 시스템에 연결하는 방법을 확인하세요.
Table Planner and Table Planner Loader
Flink 1.15부터 배포판은 두 개의 플래너를 포함해요:
/opt의flink-table-planner_${scala.version}-${flink.version}.jar— 쿼리 플래너 포함- 기본으로
/lib에서 로드되는flink-table-planner-loader-${flink.version}.jar— 격리된 클래스패스 뒤에 숨겨진 쿼리 플래너 포함(io.apache.flink.table.planner을 직접 지정할 수 없어요)
두 플래너 JAR은 같은 코드를 포함하지만 패키징이 달라요. 첫 번째 경우에는 JAR과 같은 Scala 버전을 사용해야 해요. 두 번째 경우에는 Scala가 JAR 안에 숨겨져 있으므로 Scala에 대한 고려가 필요 없어요.
기본적으로 배포판은 flink-table-planner-loader를 사용해요. 쿼리 플래너의 내부에 접근해 사용해야 한다면(flink-table-planner_${scala.version}.jar를 배포판 /lib 폴더에 복사·붙여넣기) JAR을 교체할 수 있어요. 사용 중인 Flink 배포판의 Scala 버전으로 제한된다는 점에 유의하세요.
위험: 두 플래너는 동시에 클래스패스에 존재할 수 없어요. 둘 다
/lib에 로드하면 Table 잡이 실패해요.
경고: 곧 출시될 Flink 버전에서는 Flink 배포판에
flink-table-planner_${scala.version}아티팩트를 제공하는 것을 중단할 거예요. 잡과 커스텀 커넥터/포맷을 플래너 내부에 의존하지 않고 API 모듈과 함께 작동하도록 마이그레이션할 것을 강력히 권장해요. 플래너에서 현재 API 모듈을 통해 노출되지 않는 기능이 필요하면 커뮤니티와 논의하기 위해 티켓을 열어주세요.
Hadoop Dependencies
일반 규칙: 애플리케이션에 Hadoop 의존성을 직접 추가할 필요는 없어야 해요. Flink를 Hadoop과 함께 사용하려면 Hadoop을 애플리케이션 의존성으로 추가하는 것이 아니라 Hadoop 의존성을 포함하는 Flink 설정이 있어야 해요. 다시 말해 Hadoop은 애플리케이션을 포함한 사용자 코드가 아니라 Flink 시스템 자체의 의존성이어야 해요. Flink는 HADOOP_CLASSPATH 환경 변수로 지정된 Hadoop 의존성을 사용하며, 다음과 같이 설정할 수 있어요:
export HADOOP_CLASSPATH=`hadoop classpath`
이 설계에는 두 가지 주요 이유가 있어요:
-
일부 Hadoop 상호작용은 사용자 애플리케이션이 시작되기 전에 Flink의 코어에서 발생해요. 체크포인트용 HDFS 설정, Hadoop의 Kerberos 토큰 인증, YARN 배포가 포함돼요.
-
Flink의 역(inverted) 클래스로딩 접근 방식은 많은 전이 의존성을 코어 의존성에서 숨겨요. 이는 Flink 자신의 코어 의존성뿐만 아니라 설정에 있을 때의 Hadoop 의존성에도 적용돼요. 이렇게 함으로써 애플리케이션은 의존성 충돌 없이 같은 의존성의 다른 버전을 사용할 수 있어요. 이는 의존성 트리가 매우 커질 때 매우 유용해요.
IDE 안에서 개발·테스트 중(HDFS 접근 등)에 Hadoop 의존성이 필요하다면, 의존성의 스코프(test나 provided)와 유사하게 이 의존성을 구성해야 해요.