TaskManager 메모리 설정
TaskManager 메모리 설정 (Set up TaskManager Memory)
TaskManager는 Flink에서 사용자 코드를 실행합니다. 요구 사항에 맞게 메모리 사용량을 구성하면 Flink의 리소스 사용량을 크게 줄이고 Job 안정성을 향상시킬 수 있습니다.
출처: 문서
본문
TaskManager는 Flink에서 사용자 코드를 실행합니다. 필요에 맞게 메모리 사용량을 구성하면 Flink의 리소스 발자국(resource footprint)을 크게 줄이고 Job 안정성을 개선할 수 있습니다.
이후 설명하는 메모리 구성은 릴리스 버전 1.10부터 적용됩니다. 이전 버전에서 Flink를 업그레이드한다면 migration guide를 확인하세요. 1.10 릴리스에서 많은 변경 사항이 도입되었기 때문입니다.
이 메모리 설정 가이드는 TaskManager에만 적용됩니다! TaskManager 메모리 컴포넌트는 JobManager 프로세스의 메모리 모델과 비교해 유사하지만 더 정교한 구조를 가집니다.
총 메모리 구성 (Configure Total Memory)
Flink JVM 프로세스의 *총 프로세스 메모리(total process memory)*는 Flink 애플리케이션이 소비하는 메모리(total Flink memory)와 JVM이 프로세스 실행을 위해 소비하는 메모리로 구성됩니다. total Flink memory 소비는 JVM Heap, managed memory(Flink가 관리하는 메모리) 및 기타 직접(direct/native) 메모리 사용을 포함합니다.
클러스터를 만들지 않고 로컬로 Flink를 실행한다면(예: IDE에서), 메모리 구성 옵션의 일부만 관련됩니다. 자세한 내용은 local execution을 참고하세요.
그 외에는 TaskManager 메모리를 설정하는 가장 간단한 방법은 total memory를 구성하는 것입니다. 더 세분화된 접근 방식은 여기에 더 자세히 설명되어 있습니다.
나머지 메모리 컴포넌트는 기본값 또는 추가로 구성된 옵션에 따라 자동으로 조정됩니다. 다른 메모리 컴포넌트에 대한 자세한 내용은 다음 장을 참고하세요.
Heap과 Managed Memory 구성 (Configure Heap and Managed Memory)
total memory 설명에서 언급한 것처럼, Flink에서 메모리를 설정하는 또 다른 방법은 task heap과 managed memory를 둘 다 명시적으로 지정하는 것입니다. 이는 Flink의 태스크와 managed memory에 사용 가능한 JVM Heap을 더 잘 제어할 수 있게 합니다.
나머지 메모리 컴포넌트는 기본값 또는 추가로 구성된 옵션에 따라 자동으로 조정됩니다. 여기에 다른 메모리 컴포넌트에 대한 자세한 내용이 있습니다.
task heap과 managed memory를 명시적으로 구성했다면, total process memory와 total Flink memory를 모두 설정하지 않는 것이 좋습니다. 그렇지 않으면 메모리 구성 충돌이 쉽게 발생할 수 있습니다.
Task (Operator) Heap Memory
사용자 코드에 일정량의 JVM Heap이 보장되도록 하려면 task heap memory를 명시적으로 설정할 수 있습니다(taskmanager.memory.task.heap.size). 이는 JVM Heap 크기에 더해지며 사용자 코드를 실행하는 Flink의 operator에 전용으로 할당됩니다.
Managed Memory
managed memory는 Flink가 관리하며 네이티브 메모리(off-heap)로 할당됩니다. 다음 워크로드는 managed memory를 사용합니다:
- 스트리밍 job은 이를 RocksDB state backend에 사용할 수 있습니다.
- 스트리밍과 배치 job 모두 정렬(sorting), 해시 테이블, 중간 결과 캐싱에 사용할 수 있습니다.
- 스트리밍과 배치 job 모두 Python 프로세스에서의 User Defined Functions 실행에 사용할 수 있습니다.
managed memory의 크기는
taskmanager.memory.managed.size로 명시적으로 구성하거나taskmanager.memory.managed.fraction으로 total Flink memory의 분수로 계산할 수 있습니다.
둘 다 설정된 경우 size가 fraction을 덮어씁니다. size와 fraction 중 어느 것도 명시적으로 구성되지 않으면 기본 fraction이 사용됩니다.
state backend용 메모리 구성 방법과 batch jobs용 메모리 구성도 참고하세요.
소비자 가중치 (Consumer Weights)
job에 여러 유형의 managed memory 소비자가 포함되어 있다면 managed memory가 이러한 유형 간에 어떻게 공유되어야 하는지도 제어할 수 있습니다. taskmanager.memory.managed.consumer-weights 설정 옵션은 각 유형에 가중치를 설정할 수 있게 하며, Flink는 그에 비례하여 managed memory를 예약합니다. 유효한 소비자 유형은 다음과 같습니다:
OPERATOR: 내장 알고리즘용.STATE_BACKEND: 스트리밍에서 RocksDB state backend용.PYTHON: Python 프로세스용.
예를 들어 스트리밍 job이 RocksDB state backend와 Python UDF를 모두 사용하고 소비자 가중치가 STATE_BACKEND:70,PYTHON:30으로 구성되면, Flink는 총 managed memory의 70%를 RocksDB state backend에, 30%를 Python 프로세스에 예약합니다.
각 유형에 대해 Flink는 job에 해당 유형의 managed memory 소비자가 포함된 경우에만 managed memory를 예약합니다. 예를 들어 스트리밍 job이 heap state backend와 Python UDF를 사용하고 소비자 가중치가 STATE_BACKEND:70,PYTHON:30으로 구성되면, heap state backend는 managed memory를 사용하지 않으므로 Flink는 모든 managed memory를 Python 프로세스에 사용합니다.
Flink는 소비자 가중치에 포함되지 않은 소비자 유형에 대해서는 managed memory를 예약하지 않습니다. 누락된 유형이 실제로 job에 필요하면 메모리 할당 실패가 발생할 수 있습니다. 기본적으로 모든 소비자 유형이 포함됩니다. 이는 가중치가 명시적으로 구성/덮어쓰기될 때만 발생할 수 있습니다.
Off-heap 메모리 구성 (direct 또는 native) (Configure Off-heap Memory)
사용자 코드가 할당하는 off-heap 메모리는 task off-heap memory(taskmanager.memory.task.off-heap.size)로 계산되어야 합니다.
framework off-heap memory도 조정할 수 있습니다. Flink 프레임워크가 더 많은 메모리를 필요로 한다고 확신할 때만 이 값을 변경해야 합니다.
Flink는 framework off-heap memory와 task off-heap memory를 JVM의 direct memory 한도에 포함합니다. JVM parameters도 참고하세요.
네이티브 non-direct 메모리 사용은 framework off-heap memory 또는 task off-heap memory의 일부로 계산될 수 있지만, 이 경우 JVM의 direct memory 한도가 더 높아집니다.
network memory도 JVM direct memory의 일부이지만 Flink가 관리하며 구성된 크기를 절대 초과하지 않음이 보장됩니다. 따라서 이 상황에서는 network memory 크기를 조정해도 도움이 되지 않습니다.
상세 메모리 모델도 참고하세요.
상세 메모리 모델 (Detailed Memory Model)
다음 표는 위에서 설명한 모든 메모리 컴포넌트를 나열하고, 각 컴포넌트의 크기에 영향을 주는 Flink 구성 옵션을 참조합니다:
보시다시피 일부 메모리 컴포넌트의 크기는 해당 옵션으로 간단히 설정할 수 있습니다. 다른 컴포넌트는 여러 옵션으로 조정할 수 있습니다.
Framework Memory
정당한 이유 없이 framework heap memory와 framework off-heap memory를 변경해서는 안 됩니다. Flink가 일부 내부 데이터 구조나 연산에 더 많은 메모리가 필요하다고 확신할 때만 조정하세요. 이는 특정 배포 환경이나 높은 병렬도 같은 job 구조와 관련될 수 있습니다. 또한 Hadoop 같은 Flink 의존성은 특정 설정에서 더 많은 direct 또는 native 메모리를 소비할 수 있습니다.
Flink는 현재 framework와 task 메모리의 heap 및 off-heap 버전을 격리하지 않습니다. framework와 task 메모리의 분리는 향후 릴리스에서 추가 최적화에 사용될 수 있습니다.
로컬 실행 (Local Execution)
클러스터를 만들지 않고 머신에서 단일 java 프로그램으로 Flink를 로컬로 시작하면(예: IDE에서), 다음을 제외한 모든 컴포넌트가 무시됩니다:
| Memory component | Relevant options | Default value for the local execution |
|---|---|---|
| Task heap | taskmanager.memory.task.heap.size |
infinite |
| Task off-heap | taskmanager.memory.task.off-heap.size |
infinite |
| Managed memory | taskmanager.memory.managed.size |
128MB |
| Network memory | taskmanager.memory.network.min taskmanager.memory.network.max |
64MB |
위에 나열된 모든 컴포넌트는 로컬 실행을 위해 명시적으로 구성할 수 있지만 반드시 그럴 필요는 없습니다. 구성되지 않으면 기본값으로 설정됩니다. Task heap memory와 task off-heap memory는 무한(Long.MAX_VALUE bytes)으로 간주되며, managed memory는 로컬 실행 모드에서만 기본값 128MB를 가집니다.
이 경우 task heap 크기는 실제 heap 크기와 어떤 식으로도 관련되지 않습니다. 이는 다음 릴리스에서 제공될 미래 최적화에 관련될 수 있습니다. 시작된 로컬 프로세스의 실제 JVM Heap 크기는 Flink가 제어하지 않으며 프로세스를 어떻게 시작하느냐에 따라 달라집니다. JVM Heap 크기를 제어하려면 -Xmx, -Xms 같은 해당 JVM 인자를 명시적으로 전달해야 합니다.