-
YARN 노드매니저(Node Manager)Data 2021. 1. 27. 21:28반응형
노드매니저는 하둡(Hadoop) 프로젝트의 YARN 모듈 중 하나의 컴포넌트로 Worker 역할을 하며 클러스터에 속한 노드들에서 컨테이너를 실행하고, 각 컨테이너의 리소스 사용량을 모니터링하고 그것의 상태를 리소스매니저에 report하는 역할을 담당합니다.
이 글에서는 노드매니저의 상세한 기능과 그 구현을 알아보겠습니다:
- 노드매니저의 주요 기능과 컴포넌트 오버뷰
- 노드매니저의 주요 컴포넌트들
관련글:
- 목적과 탄생배경
- YARN(하둡분산자원관리) 주요개념 및 아키텍쳐
- YARN(하둡분산자원관리) 실행 구조 및 흐름
- YARN 리소스매니저(Resource Manager)
- YARN 노드매니저(Node Manager) (이번글)
노드매니저의 주요 기능과 컴포넌트 오버뷰
노드매니저는 하둡 YARN 클러스터의 개별 컴퓨팅 노드를 관리하는 노드별 에이전트로 노드의 물리적 리소스를 사용해 YARN 애플리케이션이 요청한 컨테이너들을 실행합니다. 본질적으로 YARN의 Worker 데몬인 노드매니저는 아래와 같은 기능을 담당합니다:
- 리소스매니저와 지속적인 Sync
- 노드의 건강도 트래킹
- 컨테이너의 라이프 사이클 관리, 개별 컨테이너의 리소스 사용량 모니터링
- 분산 캐시 관리 (컨테이너가 사용하는 jars나 라이브러리 파일들의 로컬 파일 시스템 캐쉬)
- 컨테이너가 발생시키는 로그 관리
- YARN 애플리케이션이 사용하는 추가적인 서비스 제공
위 나열된 기능들 중 컨테이너 관리가 노드매니저의 핵심적인 역할입니다. 노드매니저는 애플리케이션마스터의 요청을 받아 컨테이너를 시작하거나 종료하고 컨테이너 토큰을 인증하고, 컨테이너가 사용하는 라이브러리를 관리하고, 컨테이너의 실행을 모니터링합니다.
실행자는 각 노드매니저를 옵션을 통해 설정합니다(CPU 갯수, 메모리 등). 리소스매니저에 등록된 이후에는, 노드매니저는 주기적으로 heartbeat을 현재 상태 정보와 같이 보내며 리소스매니저로부터의 요청이 있다면 받습니다. 스케쥴러가 노드의 heartbeat을 처리하면 컨테이너는 노드매니저에 할당되고 애플리케이션마스터가 리소스매니저에 heartbeat을 보낼 때 할당된 컨테이너 정보가 애플리케이션마스터에 전달됩니다.
YARN의 모든 컨테이너는 CLC(Container Launch Context)를 통해 메타정보를 가지고 있습니다. 이 요청객체는 환경변수, 라이브러리 디펜던시, 라이브러리 다운로드나 컨테이너가 직접 사용하는 security 토큰, 노드매니저 서비스를 위한 컨테이너-특정 payload, 그리고 프로세스를 생성하기 위한 커맨드 등을 포함합니다. 컨테이너 시작 요청을 인증한 후에, 노드매니저는 컨테이너를 위한 환경을 설정합니다.
실제로 컨테이너 런칭 전에, 노드매니저는 컨테이너에 필요한 모든 라이브러리(데이터 파일, executables, tarballs, jars 파일, 쉘 스크립트 등)를 로컬 파일 시스템에 복사합니다. 다운로드된 라이브러리들은 특정 애플리케이션의 컨테이너들 간에 로컬 애플리케이션-레벨 캐쉬를 통해 공유되거나, 같은 사용자에 의해 런칭된 컨테이너 간에 로컬 사용자-레벨 캐쉬를 통해 공유되거나, 심지어 CLC에 특정된대로 public 캐쉬를 통해 사용자 간에 공유될 수 있습니다. 이후에 노드매니저는 실행되는 컨테이너가 사용하지 않는 라이브러리는 가비지콜렉트합니다.
아래와 같은 경우에 노드매니저는 리소스매니저의 지시를 받아 컨테이너를 kill합니다:
- 리소스매니저가 애플리케이션이 종료되었다는 시그널을 보낼 때
- 스케쥴러가 다른 사용자나 앱을 위해 preempt하기로 하였을 때
- 노드매니저가 컨테이너가 컨테이너토큰에 특정된 리소스 제한을 넘는 것을 발견했을 때
컨테이너가 종료되면, 노드매니저는 로컬 저장소의 working 디렉토리를 정리합니다.
컨테이너 시작과 종료, 컨테이너 종료 이후 정리, 로컬 리소스 관리 이외에도 노드매니저는 다른 로컬 서비스를 제공합니다. 예로, log aggregation 서비스는 애플리케이션 컨테이너에 의해 쓰인 모든 로그를 업로드 합니다(컨테이너 종료 후).
노드매니저 실패 시, 리소스매니저는 이런 실패를 타임아웃을 통해 감지하고 모든 실행 중인 애플리케이션에 리포트합니다. 실패나 타임아웃을 일으킨 원인이 일시적인 것이라면 노드매니저는 다시 리소스매니저와 sync하고 작업을 진행합니다. 유사하게, 새로운 노드매니저가 클러스터에 추가되면, 리소스매니저는 모든 애플리케이션마스터에 컨테이너 생성에 사용할 새로운 리소스가 추가되었다는 사실을 알립니다.
노드매니저의 주요 컴포넌트들
노드매니저는 아래와 같은 컴포넌트로 구성되어 있습니다:
NodeStatusUpdater
시작 시에, 이 컴포넌트는 RM을 통해 등록되고 해당 노드 리소스에 대한 정보를 보내고 어떤 포트를 웹서버와 RPC 서버가 listen할지 식별합니다. 등록의 일환으로 리소스매니저는 추후 애플리케이션마스터의 요청 처리 시 사용할 노드매니저용 키를 노드매니저에 보냅니다. 이어지는 노드매니저-리소스매니저 커뮤니케이션은 애플리케이션마스터에 의한 새로운 컨테이너나 존재하는 컨테이너의 상태 변경 등에 대한 변경 정보를 전달합니다.
또한, 위에서 언급된 애플리케이션 종료 상황 때에도 리소스매니저는 이 컴포넌트를 통해 종료 시그널을 보내게 됩니다.
ContainerManager
이 컴포넌트는 노드매니저의 핵심 구성요소입니다. 아래와 같은 서브 컴포넌트로 구성되어 있으며, 노드에서 실행되는 컨테이너를 관리하는 데에 필요한 기능들의 일부를 각각 담당합니다:
RPC Server
RPC 서버를 통해 컨테이너매니저는 애플리케이션마스터로부터의 요청을 받아 새로운 컨테이너를 시작하거나 실행되는 컨테이너를 종료합니다. 또한, 컨테이너 매니저는 NMToken SecretManager나 ContainerToken SecretManager와 협업하여 모든 요청을 인증/인가를 담당합니다. 그리고 노드에서 실행되는 모든 컨테이너에서 실행되는 연산은 audit log에 기록되어 추후 security 도구를 통해 처리됩니다.
Resource Localization Service
리소스 로컬라이제이션은 사용자 애플리케이션에 제공되는 노드매니저의 중요한 서비스 중 하나입니다. 이 리소스 로컬라이제이션 서비스는 컨테이너가 필요로 하는 다양한 파일 리소스를 안전하게 다운로드하고 관리하는 역할을 합니다. 다운받은 파일들은 가용한 모든 디스크에 분산되어 저장되고, 파일들에 대한 접근과 사용량에 제한을 가합니다.
노드매니저 로컬라이제이션을 이해하기 위해서는 아래와 같은 용어에 대한 정의를 명확히 인지하고 있어야 합니다:
- Localization: 로컬라이제이션은 원격의 리소스를 로컬 파일 시스템으로 복사/다운로드하는 과정입니다. 항상 원격으로 리소스를 접근하는 대신, 해당 리소스를 로컬 기기로 복사하고 로컬에서 접근하는 것입니다.
- LocalResource: 로컬리소스는 하나의 컨테이너를 실행하는 데에 필요한 하나의 파일 또는 라이브러리를 말합니다. 각 로컬리소스에 대해 애플리케이션은 다음과 같은 정보를 기술합니다:
- URL: 로컬리소스가 얻어진 원격의 위치
- Size: 로컬리소스의 바이트 사이즈
- Creation timestamp: 원격 파일 시스템에서 리소스가 생성된 일시
- LocalResourceType: 노드매니저에 의해 로컬화된 리소스의 종류 (FILE, ARCHIVE or PATTERN)
- Pattern: archive에서 entries를 추출하는데 사용되는 패턴
- LocalResourceVisibility: 노드매니저에 의해 로컬화된 리소스의 visibility를 명시합니다: PUBLIC, PRIVATE, or APPLICATION.
- DeletionService: 노드매니저 안에서 실행되는 서비스로 요청에 의해 로컬 path를 삭제합니다.
- Localizer: 로컬라이제이션을 실행하는 프로세스나 쓰레드입니다. 2 종류의 로컬라이져가 존재합니다: PUBLIC 리소스를 위한 PublicLocalizer, PRIVATE과 APPLICATION 리소스를 위한 ContainerLocalizer
- LocalCache: 노드매니저는 다운로드 받은 모든 파일들의 로컬 캐쉬를 유지하거나 관리합니다. 그러한 리소스들은 파일 복사 시에 사용한 원격 URL을 통해 유니크하게 식별됩니다.
로컬라이제이션 프로세스
위에서 언급된 것과 같이 로컬리소스는 3가지 타입을 가집니다: PUBLIC, PRIVATE, APPLICATION. Security 이유로 노드매니저는 PRIVATE/APPLICATION과 PUBLIC 리소스 로컬라이제이션 시 다른 프로세스를 통해 진행됩니다:
PUBLIC 리소스 로컬라이제이션
PUBLIC 리소스의 로컬라이제이션은 PublicLocalizers라는 쓰레드 풀에 의해 처리됩니다. PublicLocalizers는 노드매니저 자체의 address space 안에서 실행됩니다. PublicLocalizer 쓰레드의 수큰 설정의 yarn.nodemanager.localizer.fetch.thread-count에 의해 조절되고 PUBLIC 리소스 다운로드 시 최대 parallelism을 설정합니다.
PUBLIC 리소스를 로컬로 다운 받으면서, 로컬라이져는 원격 파일 시스템에서 그 파일들이 PUBLIC인지 체크하고 만약 PUBLIC이 아니면 로컬라이제이션에서 제외됩니다. 각 PublicLocalizer는 CLC의 일부로 전달받은 credentials을 원격 파일 시스템에서 리소스를 다운 받을 때 사용합니다.
PRIVATE / APPLICATION 리소스 로컬라이제이션
PRIVATE / APPLICATION 리소스 로컬라이제이션은 노드매니저 안에서 처리되지 않기에 분산되어 진행됩니다. 그 프로세스는 대략적으로 아래와 같습니다:
- 이러한 리소스의 로컬라이제이션은 컨테이너로컬라이져(ContainerLocalizer)라는 분리된 프로세스 안에서 진행됩니다.
- 각 컨테이너로컬라이져 프로세스는 노드매니저의 로컬라이져러너(LocalizerRunner)라고 불리는 하나의 쓰레드를 통해 관리됩니다. 각 컨테이너는 아직 다운로드 받지 못한 리소스가 있으면 하나의 로컬라이져러너를 트리거합니다.
- 로컬리소스트래커(LocalResourcesTracker)는 유저 당 또는 애플리케이션 당 하나의 객체로 주어진 유저 또는 애플리케이션의 모든 로컬리소스를 트래킹합니다.
- 하나의 컨테이너가 하나의 PRIVATE / APPLICATION 로컬리소스를 처음 요청하고 만약 로컬리소스트래커에 그것이 존재하지 않으면 펜딩(pending) 리소스 리스트에 추가됩니다.
- 하나의 로컬라이져러너는 새로운 무언가를 다운로드 받아야 되는지 여부에 따라 생성됩니다.
- 로컬리소스는 로컬라이져러너의 펜딩 리소스 리스트에 추가됩니다.
- secure 모드인 노드매니저의 한 가지 필요사항은 위와 같은 리소스들은 yarn-사용자가 아니라 애플리케이션 submitter로 다운로드 받아야 하는 부분입니다. 그러므로, 로컬라이져러너는 LinuxContainerExecutor(LCE)를 시작합니다. 그 LCE는 애플리케이션 submitter로 실행되는 프로세스로 컨테이너로컬라이져를 실행합니다. 그러한 컨테이너로컬라이져는 아래와 같이 실행됩니다:
- 시작 후, 해당 컨테이너로컬라이져는 노드매니저 프로세스와 heartbeat을 시작합니다.
- 매 heartbeat마다, 그 로컬라이져러너는 컨테이너로컬라이져에게 한 번에 하나의 리소스를 할당하거나 종료되기를 요청합니다. 그 컨테이너로컬라이져는 로컬라이져러너에게 다운로드 상태를 보고합니다.
- 만약에 하나의 리소스 다운로드가 실패하면, 그러한 특정 리소스는 로컬리소스트래커에서 제거되고 컨테이너는 결국 실패로 마킹됩니다. 이러한 일이 발생하면, 그 로컬라이져러너는 컨테이너로컬라이져를 멈추고 그 자신도 종료합니다.
- 만약 성공적으로 다운로드되었다면, 그 로컬라이져러너는 컨테이너로컬라이져에 다른 리소스를 전달하여 모든 펜딩 리소스가 성공적으로 다운로드 될 때까지 반복합니다.
로컬리소스의 타깃 위치
각 노드매니저의 기기에서 로컬리소스들은 최종적으로 아래와 같은 타깃 디렉토리에 위치됩니다:
- PUBLIC: <local-dir>/filecache
- PRIVATE: <local-dir>/usercache/<username>/filecache
- APPLICATION: <local-dir>/usercache/<username>/appcache/<app-id>
애플리케이션 타입에 관련 없이 일단 리소스들이 다운로드되고 컨테이너가 실행되면, 그 컨테이너들은 노드매니저에 의해 각 컨테이너의 working directory에 생성된 symbolic 링크를 통해 이러한 리소스들에 로컬로 접근할 수 있습니다.
리소스 로컬라이제이션 관련 설정
관리자는 yarn-site.xml 파일의 다양한 설정 파라미터를 변경하여 노드매니저 시작 시 리소스 로컬라이제이션의 다양한 측면을 조절할 수 있습니다.
- yarn.nodemanager.local-dirs: 로컬라이제이션 시 파일 복사에 사용할 로컬 디렉토리의 comma-separated 리스트입니다. 여러 디렉토리 설정이 가능한 이면에는 로컬라이제이션에 여러 개의 디스크를 사용할 수 있도록 하여 fail-over와 로드밸런싱 기능을 제공하려는 의도가 있습니다.
- yarn.nodemanager.local-cache.max-files-per-directory: 각 로컬라이제이션 디렉토리에 위치한 최대 파일 숫자를 제한하는 설정입니다(각 리소스 타입별로). 디폴트 값은 8192로 일반적으로 이 숫자는 더 크게 설정되지 않아야 합니다.
- yarn.nodemanager.localizer.address: 리소스로컬라이제이션서비스가 다양한 로컬라이져로부터의 요청을 받기 위해 사용하는 네트워크 주소입니다.
- yarn.nodemanager.localizer.client.thread-count: 로컬라이져로부터의 요청을 처리하는 리소스로컬라이제이션서비스의 RPC 쓰레드 수를 제한합니다. 디폴트는 5로, 5개의 로컬라이져가 동시에 처리될 수 있고 다른 것은 RPC 큐에 쌓여있게 됩니다.
- yarn.nodemanager.localizer.fetch.thread-count: PUBLIC 리소스 로컬라이징에 사용되는 쓰레드 수를 설정합니다 (디폴트 4).
- yarn.nodemanager.localizer.delete.thread-count: 파일을 삭제하는 삭제서비스(DeletionService)에 사용되는 쓰레드 수를 조절합니다. 그러한 삭제서비스는 로그 파일이나 로컬 캐시 파일을 삭제하는 역할을 담당합니다 (디폴트 4).
- yarn.nodemanager.localizer.cache.target-size-mb: 리소스 로컬라이징에 사용되는 최대 디스크 사이즈를 결정합니다. 이 숫자를 넘으면 삭제서비스가 사용하지 않는 파일들을 찾아 삭제합니다.
- yarn.nodemanager.localizer.cache.cleanup.interval-ms: 이 설정의 기간이 지난 후에 리소스로컬라이제이션서비스는 총 캐시 사이즈가 최대 캐시 사이즈 제한을 넘었는지 체크하고 넘었다면 미사용 리소스를 찾아 삭제합니다. 컨테이너가 리소스를 요청하면, 그 컨테이너는 리소스 레퍼런스 리스트에 추가되고 컨테이너가 종료되기 전까지 존재합니다. 그러한 리스트를 미사용 리소스 확인 시 체크하여 사용하고 있는 리소스의 삭제를 방지합니다.
컨테이너 런쳐 (Launcher)
컨테이너 런쳐는 컨테이너를 가능한 빠르게 런칭할 수 있도록 쓰레드 풀을 유지합니다. 또한, 리소스매니저(NodeStatusUpdater를 통해)나 애플리케이션마스터(RPC 서버를 통해)가 cleanup 요청을 보내면 컨테이너 프로세스를 정리합니다. 그러한 컨테이너 런칭이나 클린업은 쓰레드 풀의 하나의 쓰레드에 의해 실행되어 해당되는 처리가 끝났을 때에만 쓰레드가 반납됩니다. 그로 인해, 한 컨테이너의 런칭이나 클린업은 다른 처리에 영향을 주지 않으며, 모든 컨테이너 처리는 노드매니저 프로세스 안의 독립된 환경에서 진행됩니다.
부가적인 (Auxiliary) 서비스
운영자는 플러그인 가능한 부가적인 서비스를 노드매니저에 설정할 수 있습니다. 노드매니저는 기능들을 확장할 수 있는 프레임웍을 제공하고 노드 당 커스텀이 가능하여 다른 노드매니저와 분리되어 하나의 노드매니저만 "sandbox" 형태로 설정할 수 있습니다. 이러한 서비스는 노드매니저가 시작하기 전에 설정되어야 합니다. 부가적인 서비스는 애플리케이션의 첫 컨테이너가 노드에서 시작할 때, 컨테이너가 시작하거나 종료되거나, 앱이 완료될 때 알림을 받습니다.
컨테이너의 로컬 스토리지는 컨테이너 종료 후 정리되는 반면, 그 결과물은 애플리케이션 종료 전까지 보존할 수 있습니다. 이러한 방식으로, 하나의 컨테이너는 컨테이너 라이프 사이클을 벗어나는 데이터를 생성할 수 있고, 그 데이터는 노드의 관리를 받습니다. 이러한 결과물 보존의 특성과 부가적인 서비스를 통해 더욱 뛰어난 기능을 추가할 수 있습니다.
그 한 가지 예로는 하둡 맵리듀스가 부가적인 서비스인 ShuffleHandler를 통해서 맵과 리듀스 간의 중간 데이터를 전달하는 것입니다. CLC를 통해 애플리케이션마스터가 부가적인 서비스에 payload의 위치를 알려주고, 맵리듀스는 이러한 채널을 통해서 셔플서비스에 리듀스 task를 인증하는 토큰을 넘겨줍니다.
컨테이너 시작 시에 부가적인 서비스를 위한 정보는 애플리케이션마스터에 제출되어 애플리케이션마스터가 다른 부가적인 서비스를 이용할 때 사용할 수 있도록 합니다. 예로, 맵리듀스 프레임웍은 셔플핸들러의 포트 정보를 맵 결과물 셔플링을 위한 리듀스 task에 넘겨주게 됩니다.
컨테이너 모니터
컨테이너 런칭 이후에, 이 컴포넌트는 컨테이너가 실행되는 동안의 리소스 사용량을 모니터링합니다. 메모리와 같은 리소스의 독립성과 fair sharing을 위해서 각 컨테이너는 리소스매니저에 의해 일정한 양의 리소스를 할당 받습니다. 컨테이너모니터는 각 컨테이너의 사용량을 지속적으로 모니터링하다가, 만약 컨테이너가 할당량을 초과하면 컨테이너가 kill되도록 시그널을 보냅니다.
로그 핸들러
로그핸들러는 플러거블한 컴포넌트로 컨테이너들의 로그를 로컬 디스크에 보관하거나 함께 압축하여 파일 시스템에 업로드하는 기능을 담당합니다.
컨테이너 엑서큐터
이 컴포넌트는 기반이 되는 운영시스템과 연동되어 컨테이너가 필요로 하는 파일이나 디렉토리들을 안전하게 위치시키고 컨테이너들과 관련된 프로세스를 런칭하거나 정리합니다.
노드 건강도 체커 서비스
NodeHealthCheckerService는 설정된 스크립트를 주기적으로 실행하여 노드의 상태를 체크하는 기능을 제공합니다. 또한, 주기적으로 디스크에 임시 파일을 생성하여 디스크의 상태도 체크합니다. 상태 변경 시, NodeStatusUpdated에 알림을 보내고 그 정보는 리소스매니저에게 전달됩니다.
Reference
[1] Apache Hadoop YARN: yet another resource negotiator[2] Apache Hadoop YARN: Moving beyond MapReduce and Batch Processing with Apache Hadoop 2
[3] https://data-flair.training/blogs/hadoop-yarn-node-manager-tutorial/
반응형'Data' 카테고리의 다른 글
"데이터 경제를 위한 비지니스 모델"을 읽고 (feat. 한국 데이터 기업) (0) 2021.02.02 주니어 데이터 엔지니어의 공부방법 (6) 2021.01.27 데이터 품질 (Data Quality) (0) 2021.01.27 [Hands On] 도커 기반 하둡 살펴보기 (HDFS, YARN, MapReduce, Hive) (0) 2021.01.27 Data-Driven UX란? (0) 2021.01.23 YARN 리소스매니저(Resource Manager) (0) 2021.01.23 YARN(하둡분산자원관리) 실행 구조 및 흐름 (0) 2021.01.23 YARN(하둡분산자원관리) 주요개념 및 아키텍쳐 (0) 2021.01.21