HDFS 라우터 기반 페더레이션

HDFS 라우터 기반 페더레이션 (Router-based Federation)

소개 (Introduction)

NameNode는 inode(파일과 디렉터리) 및 파일 블록의 메타데이터 오버헤드, Datanode 하트비트 수, HDFS RPC 클라이언트 요청 수 때문에 확장성 한계가 있습니다. 보편적인 해결책은 파일시스템을 더 작은 하위 클러스터인 HDFS Federation으로 나누고 ViewFs로 페더레이션된 뷰를 제공하는 것입니다. 문제는 하위 클러스터의 분할(예: 네임스페이스 파티션)을 어떻게 유지하느냐입니다. 이는 사용자가 여러 하위 클러스터에 연결하고 폴더/파일의 할당을 관리하도록 강제하기 때문입니다.

출처: HDFS Router-based Federation

아키텍처

이 분할된 페더레이션의 자연스러운 확장은 네임스페이스를 페더레이션하는 소프트웨어 레이어를 추가하는 것입니다. 이 추가 레이어는 사용자가 어떤 하위 클러스터든 투명하게 접근할 수 있게 하고, 하위 클러스터가 자신의 블록 풀을 독립적으로 관리할 수 있게 하며, 추후 하위 클러스터 간 데이터 리밸런싱을 지원합니다 (HDFS-13123 참고). RBF의 하위 클러스터는 독립 HDFS 클러스터일 필요가 없습니다. 일반 페더레이션 클러스터(여러 블록 풀) 또는 페더레이션과 독립 클러스터가 혼합된 클러스터도 허용됩니다. 이러한 목표를 달성하기 위해 페더레이션 레이어는 블록 접근을 올바른 하위 클러스터로 지시하고, 네임스페이스 상태를 유지하며, 데이터 리밸런싱 메커니즘을 제공합니다. 이 레이어는 확장 가능하고, 고가용이며, 장애 허용이 가능해야 합니다.

이 페더레이션 레이어는 여러 구성요소로 구성됩니다. Router 구성요소는 NameNode와 동일한 인터페이스를 가지며, State Store의 실측 정보(ground-truth information)에 기반해 클라이언트 요청을 올바른 하위 클러스터로 전달합니다. State Store는 원격 마운트 테이블(ViewFs 스타일이지만 클라이언트 간 공유)과 하위 클러스터의 활용(부하/용량) 정보를 결합합니다. 이 접근 방식은 YARN 페더레이션과 동일한 아키텍처입니다.

예시 흐름 (Example flow)

가장 간단한 구성은 각 NameNode 머신에 Router를 배포하는 것입니다. Router는 로컬 NameNode와 그 상태를 모니터링하고 State Store에 하트비트를 보냅니다. 일반 DFS 클라이언트가 페더레이션 파일시스템의 파일에 접근하기 위해 어떤 Router에든 접촉하면, Router는 State Store(즉 로컬 캐시)의 Mount Table을 확인해 어느 하위 클러스터에 파일이 있는지 찾습니다. 그런 다음 State Store(즉 로컬 캐시)의 Membership 테이블에서 그 하위 클러스터를 담당하는 NameNode를 확인합니다. 올바른 NameNode를 식별한 후 Router는 요청을 프록시합니다. 클라이언트는 Datanode에 직접 접근합니다.

Router

시스템에는 소프트 상태를 가진 여러 Router가 있을 수 있습니다. 각 Router는 두 가지 역할을 가집니다.

  • 페더레이션 인터페이스(Federated interface): 클라이언트에 단일 전역 NameNode 인터페이스를 노출하고 요청을 올바른 하위 클러스터의 active NameNode로 전달합니다.
  • NameNode 하트비트: State Store에서 NameNode에 대한 정보를 유지합니다.

페더레이션 인터페이스

Router는 클라이언트 요청을 받고, State Store에서 올바른 하위 클러스터를 확인해 그 하위 클러스터의 active NameNode로 요청을 전달합니다. NameNode의 응답은 반대 방향으로 흐릅니다. Router는 무상태(stateless)이며 로드 밸런서 뒤에 둘 수 있습니다. 상태 확인을 위해 /isActive 엔드포인트를 상태 프로브로 사용할 수 있습니다(예: http://ROUTER_HOSTNAME:ROUTER_PORT/isActive). 성능을 위해 Router는 원격 마운트 테이블 항목과 하위 클러스터 상태도 캐시합니다. 변경이 모든 Router에 전파되었는지 확인하기 위해 각 Router는 자신의 상태를 State Store에 하트비트합니다.

Router와 State Store 사이의 통신은 캐시됩니다(신선도를 위한 시간 만료 포함). 이는 시스템의 성능을 향상시킵니다.

Router 하트비트

Router는 주기적으로 자신의 상태를 State Store에 하트비트합니다.

NameNode 하트비트

이 역할을 위해 Router는 주기적으로 NameNode(보통 같은 서버)의 상태를 확인하고 그 고가용성(HA) 상태와 부하/공간 상태를 State Store에 보고합니다. 참고로 이는 선택적 역할입니다. Router는 어떤 하위 클러스터와도 독립적일 수 있기 때문입니다. NameNode HA와의 성능을 위해 Router는 State Store의 HA 상태 정보를 사용해 active일 가능성이 가장 높은 NameNode로 요청을 전달합니다. 참고로 이 서비스는 운영을 단순화하기 위해 NameNode 자체에 내장될 수 있습니다.

가용성과 장애 허용

Router는 여러 수준의 실패로 작동합니다.

페더레이션 인터페이스 HA: Router는 무상태이고 메타데이터 연산은 NameNode에서 원자적입니다. Router가 사용 불가능해지면 어떤 Router든 대신할 수 있습니다. 클라이언트는 페더레이션의 모든 Router를 엔드포인트로 DFS HA 클라이언트(예: ConfiguredFailoverProvider 또는 RequestHedgingProxyProvider)를 구성합니다.

State Store 사용 불가: Router가 State Store에 접촉할 수 없으면 Safe Mode 상태로 들어가 요청 서빙을 허용하지 않습니다. 클라이언트는 Safe Mode의 Router를 Standby NameNode인 것처럼 취급하고 다른 Router를 시도합니다. Router의 Safe Mode를 관리하는 수동 방법이 있습니다.

Safe Mode 상태는 다음 명령으로 관리할 수 있습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -safemode enter | leave | get

NameNode 하트비트 HA: 고가용성과 유연성을 위해 여러 Router가 같은 NameNode를 모니터링하고 그 정보를 State Store에 하트비트할 수 있습니다. 이는 Router가 실패할 경우 클라이언트의 낡은 정보에 대한 회복력을 높입니다. State Store의 충돌하는 NameNode 정보는 각 Router가 쿼럼을 통해 해결합니다.

NameNode 사용 불가: Router가 active NameNode에 접촉할 수 없으면 하위 클러스터의 다른 NameNode를 시도합니다. 먼저 standby로 보고된 NameNode를 시도한 다음 사용 불가능한 NameNode를 시도합니다. Router가 어떤 NameNode에도 도달할 수 없으면 예외를 던집니다.

NameNode 만료: 하트비트 간격의 배수 동안 NameNode 하트비트가 State Store에 기록되지 않으면, 모니터링 Router가 NameNode가 만료되었음을 기록하고 어떤 Router도 그 NameNode에 접근하려 하지 않습니다. 이후 NameNode에 대한 갱신된 하트비트가 기록되면 모니터링 Router가 NameNode를 만료 상태에서 복원합니다.

인터페이스

사용자와 관리자와 상호작용하기 위해 Router는 여러 인터페이스를 노출합니다.

  • RPC: Router RPC는 클라이언트가 HDFS와 상호작용하는 데 사용하는 가장 일반적인 인터페이스를 구현합니다. 현재 구현은 일반 MapReduce, Spark, Hive(Tez, Spark, MapReduce 위)로 작성된 분석 워크로드로 테스트되었습니다. 스냅샷, 암호화, 계층 저장 같은 고급 기능은 향후 버전을 위해 남깁니다. 구현되지 않은 모든 함수는 예외를 던집니다.
  • Admin(관리): 관리자는 RPC를 통해 클러스터에서 정보를 조회하고 마운트 테이블에서 항목을 추가/제거할 수 있습니다. 이 인터페이스는 페더레이션의 정보를 얻고 수정하는 명령줄로도 노출됩니다.
  • Web UI: Router는 현재 NameNode UI를 모방해 페더레이션 상태를 시각화하는 Web UI를 노출합니다. 마운트 테이블 정보, 각 하위 클러스터의 멤버십 정보, Router 상태를 표시합니다.
  • WebHDFS: Router는 RPC 외에도 HDFS REST 인터페이스(WebHDFS)를 제공합니다.
  • JMX: NameNode를 모방해 JMX를 통해 메트릭을 노출합니다. 이는 Web UI가 클러스터 상태를 얻는 데 사용합니다.

Router 기반 페더레이션에서 사용할 수 없는 일부 연산이 있습니다. Router는 이에 대해 예외를 던집니다. 사용자가 접할 수 있는 예는 다음과 같습니다.

  • 두 개의 서로 다른 nameservice에서 파일/폴더 이름 바꾸기.
  • 두 개의 서로 다른 nameservice에서 파일/폴더 복사.
  • 리밸런싱 중인 파일/폴더에 쓰기.

할당량 관리 (Quota management)

페더레이션은 마운트 테이블 수준에서 **전역 할당량(global quota)**을 지원하고 제어합니다. 성능상의 이유로 Router는 할당량 사용량을 캐시하고 주기적으로 갱신합니다. 이 할당량 사용량 값은 RouterRPCSever에서 호출되는 각 WRITE RPC 동안 할당량 검증에 사용됩니다. 할당량 상세는 HDFS Quotas Guide를 참고하세요.

참고: 전역 할당량이 활성화되면 하위 클러스터의 할당량을 직접 설정하거나 해제하는 것은 권장되지 않습니다. Router Admin 서버가 하위 클러스터의 할당량을 전역 할당량으로 덮어쓰기 때문입니다.

State Store

(논리적으로 중앙화되지만 물리적으로 분산된) State Store는 다음을 유지합니다.

  • 블록 접근 부하, 사용 가능한 디스크 공간, HA 상태 등의 측면에서 하위 클러스터의 상태.
  • 폴더/파일과 하위 클러스터 사이의 매핑, 즉 원격 마운트 테이블.

State Store의 백엔드는 플러그형입니다. 우리는 백엔드 구현의 장애 허용을 활용합니다. State Store에 저장되는 주요 정보와 그 구현:

Membership(멤버십): 멤버십 정보는 페더레이션의 NameNode 상태를 인코딩합니다. 이는 저장 용량과 노드 수 같은 하위 클러스터에 대한 정보를 포함합니다. Router는 하나 이상의 NameNode에 대한 이 정보를 주기적으로 하트비트합니다. 여러 Router가 단일 NameNode를 모니터링할 수 있으므로 모든 Router의 하트비트가 저장됩니다. Router는 State Store에서 이 정보를 조회할 때 데이터의 쿼럼을 적용합니다. Router는 특정 임계값(예: 10개의 Router 하트비트 기간)보다 오래된 항목을 버립니다.

Mount Table: 이 테이블은 폴더와 하위 클러스터 사이의 매핑을 호스팅합니다. ViewFs의 마운트 테이블과 유사하며, 페더레이션된 폴더, 대상 하위 클러스터, 그 폴더의 경로를 지정합니다.

보안 (Security)

Router는 현재 HDFS 보안 모델과 유사한 보안을 지원합니다. 이 기능은 RPC 및 Web 기반 호출 모두에 사용할 수 있습니다. 기본 보안 HDFS 클러스터로 프록시할 수 있는 능력이 있습니다.

Namenode와 유사하게 라우터에 연결하는 클라이언트에 대한 kerberos 및 토큰 기반 인증 모두 지원이 있습니다. Router는 이 기능을 지원하기 위해 core-site.xml과 hdfs-site.xml의 기존 보안 관련 구성에 내부적으로 의존합니다. 그 외에도 라우터는 자체 키탭(keytab)과 프린시펄(principal)로 구성되어야 합니다.

토큰 기반 인증의 경우 router는 다운스트림 namenode와 통신하지 않고 업스트림 클라이언트에 위임 토큰을 발급합니다. Router는 자신의 자격 증명을 사용해 업스트림 실제 사용자를 대신해 다운스트림 namenode로 안전하게 프록시합니다. Router 프린시펄은 모든 보안 다운스트림 namenode에서 슈퍼유저로 구성되어야 합니다. namenode용 프록시 사용자 구성은 여기를 참고하세요. 또한 router 데몬을 소유한 사용자는 namenode 프로세스 자체와 동일한 신원으로 구성되어야 합니다. 자세한 내용은 여기를 참고하세요. Router는 토큰을 모든 라우터에 분배하기 위해 state store에 의존합니다. 제공되는 기본 구현 외에도 사용자는 토큰 관리를 위한 자체 state store 구현을 플러그인할 수 있습니다. 기본 구현은 토큰 관리에 zookeeper에 의존합니다. 큰 router/zookeeper 클러스터는 수백만 개의 토큰을 보유할 수 있으므로, zookeeper 클라이언트가 의존하는 jute.maxbuffer 시스템 속성이 router 데몬에서 적절히 구성되어야 합니다.

이 기능에 대한 자세한 정보는 Apache JIRA 티켓 HDFS-13532를 참고하세요.

격리 (Isolation)

Router는 프록시하도록 구성된 모든 다운스트림 nameservice에 대한 격리를 달성하기 위해 전용 수의 RPC 핸들러 할당을 지원합니다. 크거나 바쁜 클러스터는 다른 클러스터 namenode보다 namenode에 비교적 높은 RPC 트래픽을 가질 수 있으므로, 이 기능이 활성화되면 관리자가 바쁜 클러스터에 더 많은 수의 RPC 핸들러를 구성할 수 있습니다. 특정 nameservice에 전용 핸들러가 할당되지 않으면 구성된 모든 nameservice에 대해 RPC 핸들러의 균등 분배가 이루어집니다. Fanout 호출은 특별한 nameservice를 대상으로 취급되므로 핸들러로 구성할 수 있습니다.

다운스트림 namenode가 충분히 느리거나 바빠서 허가가 불가능하면 Router가 클라이언트에 StandByException 예외를 던집니다. 이는 클라이언트 측에서 장애 조치 동작을 트리거하고 클라이언트가 클러스터의 다른 라우터에 연결하게 됩니다. 이는 모든 라우터 노드에 걸쳐 RPC를 자동으로 로드 밸런싱하는 긍정적인 효과를 제공합니다. 이는 불건전한 namenode의 경우 단일 라우터가 병목이 되지 않도록 하고 전체 라우터 클러스터의 모든 핸들러가 활용되도록 보장하는 데 중요합니다.

사용자는 개별 다운스트림 namenode가 기대하는 정상 상태 부하에 기반해 핸들러를 구성하고, 전반적으로 더 많은 RPC를 처리하기 위해 클러스터에 더 많은 라우터를 도입할 수 있습니다. 특정 namenode가 과부하된 이벤트에서 클라이언트가 이 기능에서 자동으로 튀는(bouncing) 동작 때문에, 좋은 namenode에 연결된 좋은 클라이언트는 항상 그들에게 전용된 Rpc 레인을 계속 사용합니다. 잘못 행동하는 namenode나 namenode에 스파이크 부하를 주는 backfill 작업의 경우, 필요하면 특정 nameservice를 위한 트래픽 급증을 처리하기 위해 평소보다 높은 핸들러 수로 더 많은 라우터를 추가할 수 있습니다.

전체적으로 격리 기능은 구성 dfs.federation.router.handler.isolation.enable로 노출됩니다. 이 기능의 기본값은 "false"입니다. 사용자는 다양한 nameservice에 핸들러를 사용자 지정 할당하기 위한 자신의 공정성 정책 컨트롤러를 도입할 수도 있습니다.

이 기능에 대한 자세한 정보는 Apache JIRA 티켓 HDFS-14090을 참고하세요.

배포 (Deployment)

기본적으로 Router는 로컬 머신의 요청을 받고 NameNode를 모니터링할 준비가 되어 있습니다. dfs.federation.router.store.driver.class를 설정해 State Store 엔드포인트를 알아야 합니다. 나머지 옵션은 hdfs-rbf-default.xml에 문서화되어 있습니다.

Router가 구성되면 시작할 수 있습니다.

[hdfs]$ $HADOOP_PREFIX/bin/hdfs --daemon start dfsrouter

그리고 중지하려면:

[hdfs]$ $HADOOP_PREFIX/bin/hdfs --daemon stop dfsrouter

마운트 테이블 관리 (Mount table management)

마운트 테이블 항목은 ViewFs와 거의 동일합니다. 마운트 테이블 항목을 만들기 전에 다운스트림 네임스페이스 경로가 존재하는지 확인하세요. 관리를 단순화하는 좋은 방법은 페더레이션된 네임스페이스에 대상 네임스페이스와 같은 이름을 붙이는 것입니다. 예를 들어 페더레이션된 네임스페이스에 /data/app1을 마운트한다면 대상 네임스페이스에도 같은 이름을 갖는 것이 좋습니다.

페더레이션 관리 도구는 마운트 테이블 관리를 지원합니다. 예를 들어 세 개의 마운트 포인트를 만들고 나열하려면:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /tmp ns1 /tmp
[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /data/app1 ns2 /data/app1
[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /data/app2 ns3 /data/app2
[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -ls

쓰기를 허용하지 않는 마운트 포인트도 지원합니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /readonly ns1 / -readonly

마운트 포인트가 설정되지 않으면 Router는 기본 네임스페이스 dfs.federation.router.default.nameserviceId로 매핑합니다.

마운트 테이블은 UNIX 유사 권한을 가지며, 이는 어떤 사용자와 그룹이 마운트 포인트에 접근할 수 있는지 제한합니다. 쓰기 권한은 사용자가 마운트 포인트를 추가, 갱신, 제거할 수 있게 합니다. 읽기 권한은 사용자가 마운트 포인트를 나열할 수 있게 합니다. 실행 권한은 사용되지 않습니다.

마운트 테이블 권한은 다음 명령으로 설정할 수 있습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /tmp ns1 /tmp -owner root -group supergroup -mode 0755

mode 옵션은 마운트 테이블의 UNIX 스타일 권한입니다. 권한은 8진수로 지정됩니다(예: 0755). 기본적으로 0755로 설정됩니다.

할당량 (Quotas)

Router 기반 페더레이션은 마운트 테이블 수준에서 전역 할당량을 지원합니다. 마운트 테이블 항목은 여러 하위 클러스터에 걸쳐 퍼질 수 있으며 전역 할당량은 이 하위 클러스터들에 걸쳐 계산됩니다.

페더레이션 관리 도구는 지정된 마운트 테이블 항목에 대한 할당량 설정을 지원합니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -setQuota /path -nsQuota 100 -ssQuota 1024

위 명령은 해당 경로가 최대 100개의 파일/디렉터리를 갖고 최대 1024바이트 저장 공간을 사용할 수 있게 함을 의미합니다. ssQuota 파라미터는 여러 크기 단위 접미사를 지원합니다(예: 1k는 1KB, 5m는 5MB). 접미사가 지정되지 않으면 바이트로 간주합니다.

지정된 마운트 테이블 항목에 대한 저장 유형 할당량 설정:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -setStorageTypeQuota <path> -storageType <storage type>

지정된 마운트 테이블 항목에 대한 할당량 제거:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -clrQuota <path>

지정된 마운트 테이블 항목에 대한 저장 유형 할당량 제거:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -clrStorageTypeQuota <path>

Ls 명령은 각 마운트 테이블 항목에 대해 아래 정보를 표시합니다.

Source                    Destinations              Owner                     Group                     Mode                      Quota/Usage
/path                     ns0->/path                root                      supergroup                rwxr-xr-x                 [NsQuota: 50/0, SsQuota: 100 B/0 B]

마운트 테이블 캐시는 주기적으로 새로고침되지만 refresh 명령을 실행해 새로고침할 수도 있습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -refresh

위 명령은 연결된 router의 캐시를 새로고침합니다. 마운트 테이블 새로고침 서비스가 활성화되면 서비스가 항상 캐시를 최신 상태로 유지하므로 이 명령은 중복됩니다.

여러 하위 클러스터

마운트 포인트는 여러 하위 클러스터의 매핑도 지원합니다. 예를 들어 하위 클러스터 ns1과 ns2에 파일을 저장하는 마운트 포인트를 만들려면:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /data ns1,ns2 /data -order SPACE

/data를 나열하면 두 하위 클러스터의 모든 폴더와 파일이 표시됩니다. 새 파일/폴더를 어디에 만들지 결정할 때는 order 파라미터를 사용하며, 현재 다음 방법을 지원합니다.

  • HASH: 첫 번째 레벨에서 일관된 해싱(consistent hashing)을 따릅니다. 더 깊은 레벨은 부모 중 하나에 있습니다.
  • LOCAL: 로컬 하위 클러스터에 데이터를 쓰려고 시도합니다.
  • RANDOM: 임의 하위 클러스터. 보통 부하를 분산하는 데 유용합니다. 폴더는 모든 하위 클러스터에 만들어집니다.
  • HASH_ALL: 모든 레벨에서 일관된 해싱을 따릅니다. 이 접근 방식은 읽기와 쓰기를 하위 클러스터에 균등하게 분산하려고 시도합니다. 폴더는 모든 하위 클러스터에 만들어집니다.
  • SPACE: 가장 많은 사용 가능 공간이 있는 하위 클러스터에 데이터를 쓰려고 시도합니다. 폴더는 모든 하위 클러스터에 만들어집니다.
  • LEADER_FOLLOWER: 리더 하위 클러스터에 최대한 데이터를 쓰려고 시도하고, 실패하면 팔로워 하위 클러스터를 시도합니다. 폴더는 모든 하위 클러스터에 만들어집니다.

해시 기반 접근 방식의 경우, 차이점은 HASH는 폴더 내의 모든 파일/폴더가 같은 하위 클러스터에 속하게 하는 반면, HASH_ALL은 마운트 포인트 아래의 모든 파일을 분산시킨다는 것입니다. 예를 들어 /data/hash에 대한 HASH 마운트 포인트가 있다면 /data/hash/folder0 아래의 파일과 폴더는 모두 같은 하위 클러스터에 있습니다. 반면 /data/hash_all에 대한 HASH_ALL 마운트 포인트는 /data/hash_all/folder0 아래의 파일을 해당 마운트 포인트의 모든 하위 클러스터에 분산시킵니다(하위 폴더가 모든 하위 클러스터에 만들어짐).

RANDOM은 서로 다른 하위 클러스터에서 데이터를 읽고 쓰는 데 사용할 수 있습니다. 이 접근 방식의 일반적인 용도는 여러 하위 클러스터에 같은 데이터를 두고 읽기를 하위 클러스터에 걸쳐 분산하는 것입니다. 예를 들어 수천 개의 컨테이너가 같은 데이터(예: 라이브러리)를 읽어야 한다면, RANDOM을 사용해 어떤 하위 클러스터에서든 데이터를 읽을 수 있습니다.

LEADER_FOLLOWER는 클러스터 간 재해 허용에 사용할 수 있으며, 하위 클러스터 간 부하 공유를 위한 것이 아닙니다. -add /data ns2,ns1 /data -order LEADER_FOLLOWER처럼 이 모드를 사용할 때 ns2는 active 하위 클러스터로, ns1은 팔로워 하위 클러스터로 간주됩니다. 네임스페이스의 순서는 항상 leader,follower,follower...입니다.

어느 하위 클러스터에 파일이 있는지 결정하려면:

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -getDestination /user/user1/file.txt

Router는 하위 클러스터 간 데이터 일관성을 보장하지 않습니다. 기본적으로 한 하위 클러스터가 사용 불가능하면 해당 하위 클러스터를 대상으로 하는 쓰기가 실패할 수 있습니다. 다른 하위 클러스터에 쓰는 것을 허용하려면 마운트 포인트를 장애 허용으로 만들 수 있습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -add /data ns1,ns2 /data -order HASH_ALL -faulttolerant

이것은 파일이 여러 하위 클러스터에 쓰이거나 폴더가 하나에서 누락되는 결과를 초래할 수 있음을 유의하세요. 이러한 불일치의 가능성을 알고 이 faulttolerant 접근 방식을 회복력 있는 경로에만 적용해야 합니다. 예로 /app-logs 폴더가 있는데, 대부분 하위 폴더에 한 번만 쓰입니다.

nameservice 비활성화

nameservice(하위 클러스터)에 대한 접근을 방지하려면 페더레이션에서 비활성화할 수 있습니다. 예를 들어 ns1을 비활성화하고, 나열하고, 다시 활성화할 수 있습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -nameservice disable ns1
[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -getDisabledNameservices
[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -nameservice enable ns1

이는 하위 클러스터를 폐기(decommission)할 때 또는 하위 클러스터 하나가 잘못 행동할 때(예: 낮은 성능이나 사용 불가) 유용합니다.

Router 서버 일반 새로고침

host:ipc_port에서 가 지정한 리소스의 런타임 새로고침을 트리거합니다. 예를 들어 화이트리스트 검사를 활성화하려면 router 서버를 재시작하는 대신 refresh 명령을 보내면 됩니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -refreshRouterArgs <host:ipc_port> <key> [arg1..argn]

Router 상태 덤프

router의 현재 상태를 진단하려면 dumpState 명령을 사용할 수 있습니다. 이 명령은 State Store의 레코드에 대한 텍스트 덤프를 생성합니다. 구성으로 state store를 찾고 읽기 때문에, router가 실행되는 머신을 사용하는 것이 가장 쉬운 경우가 많습니다. 이 명령은 로컬로 실행되므로 router가 실행 중일 필요가 없습니다.

[hdfs]$ $HADOOP_HOME/bin/hdfs dfsrouteradmin -dumpState

클라이언트 구성

클라이언트가 페더레이션된 네임스페이스를 사용하려면 라우터를 가리키는 새 네임스페이스를 만들어야 합니다. 예를 들어 ns0, ns1, ns2, ns3의 4개 네임스페이스가 있는 클러스터는 hdfs-site.xml에 두 라우터를 가리키는 ns-fed라는 새 네임스페이스를 추가할 수 있습니다.

<configuration>
  <property>
    <name>dfs.nameservices</name>
    <value>ns0,ns1,ns2,ns3,ns-fed</value>
  </property>
  <property>
    <name>dfs.ha.namenodes.ns-fed</name>
    <value>r1,r2</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns-fed.r1</name>
    <value>router1:rpc-port</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns-fed.r2</name>
    <value>router2:rpc-port</value>
  </property>
  <property>
    <name>dfs.client.failover.proxy.provider.ns-fed</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  </property>
  <property>
    <name>dfs.client.failover.random.order</name>
    <value>true</value>
  </property>
</configuration>

dfs.client.failover.random.order를 true로 설정하면 라우터 간에 부하를 균등하게 분산할 수 있습니다.

이 설정으로 사용자는 ns-fed를 일반 네임스페이스처럼 상호작용할 수 있습니다.

$ $HADOOP_HOME/bin/hdfs dfs -ls hdfs://ns-fed/
/tmp
/data

이 페더레이션된 네임스페이스는 core-site.xml에서 fs.defaultFS를 사용해 기본 네임스페이스로 설정할 수도 있습니다.

NameNode 구성

시스템이 데이터 지역성을 지원하려면 NameNode가 라우터가 제공하는 사용자의 클라이언트 IP 주소를 신뢰하도록 구성해야 합니다. dfs.namenode.ip-proxy-users는 호출자 컨텍스트를 통해 클라이언트 ip 주소를 제공할 수 있는 사용자의 쉼표 구분 목록을 정의합니다.

<configuration>
  <property>
    <name>dfs.namenode.ip-proxy-users</name>
    <value>hdfs</value>
  </property>
</configuration>

Router 구성

hdfs-rbf-site.xml에 Router 기반 페더레이션 구성(config)을 추가할 수 있습니다. 주요 옵션은 hdfs-rbf-default.xml에 문서화되어 있습니다. 구성 값은 이 절에서 설명합니다.

RPC 서버

클라이언트로부터 연결을 받는 RPC 서버.

속성 기본값 설명
dfs.federation.router.default.nameserviceId (비어 있음) 모니터링할 기본 하위 클러스터의 nameservice 식별자.
dfs.federation.router.rpc.enable true true이면 router에서 클라이언트 요청을 처리하는 RPC 서비스가 활성화됩니다.
dfs.federation.router.rpc-address 0.0.0.0:8888 모든 클라이언트 요청을 처리하는 RPC 주소.
dfs.federation.router.rpc-bind-host 0.0.0.0 RPC 서버가 실제로 바인딩할 주소.
dfs.federation.router.handler.count 10 router가 클라이언트의 RPC 요청을 처리하는 서버 스레드 수.
dfs.federation.router.handler.queue.size 100 RPC 클라이언트 요청을 처리하는 핸들러 수에 대한 큐 크기.
dfs.federation.router.reader.count 1 router가 RPC 클라이언트 요청을 처리하는 리더 수.
dfs.federation.router.reader.queue.size 100 router가 RPC 클라이언트 요청을 처리하는 리더 수에 대한 큐 크기.

NameNode에 대한 연결

Router는 클라이언트 요청을 NameNode로 전달합니다. 연결 생성의 지연을 줄이기 위해 연결 풀을 사용합니다.

속성 기본값 설명
dfs.federation.router.connection.pool-size 1 router에서 namenode로의 연결 풀 크기.
dfs.federation.router.connection.clean.ms 10000 연결 풀이 사용하지 않는 연결을 제거해야 하는지 확인하는 시간 간격(밀리초).
dfs.federation.router.connection.pool.clean.ms 60000 연결 관리자가 사용하지 않는 연결 풀을 제거해야 하는지 확인하는 시간 간격(밀리초).
dfs.federation.router.enable.multiple.socket false true이면 ConnectionPool이 같은 사용자에 대해 새 연결을 만들 때 새 소켓을 사용합니다. dfs.federation.router.max.concurrency.per.connection과 함께 사용하는 것이 가장 좋습니다.
dfs.federation.router.max.concurrency.per.connection 1 연결이 동시에 처리할 수 있는 최대 요청 수.

Admin 서버

Mount Table을 관리하는 관리 서버.

속성 기본값 설명
dfs.federation.router.admin.enable true true이면 router에서 클라이언트 요청을 처리하는 RPC admin 서비스가 활성화됩니다.
dfs.federation.router.admin-address 0.0.0.0:8111 admin 요청을 처리하는 RPC 주소.
dfs.federation.router.admin-bind-host 0.0.0.0 RPC admin 서버가 실제로 바인딩할 주소.
dfs.federation.router.admin.handler.count 1 router가 admin의 RPC 요청을 처리하는 서버 스레드 수.

HTTP 서버

클라이언트에 Web UI와 HDFS REST 인터페이스(WebHDFS)를 제공하는 HTTP 서버. 기본 URL은 "http://router_host:50071"입니다.

속성 기본값 설명
dfs.federation.router.http.enable true true이면 router에서 클라이언트 요청을 처리하는 HTTP 서비스가 활성화됩니다.
dfs.federation.router.http-address 0.0.0.0:50071 Router에 대한 웹 요청을 처리하는 HTTP 주소.
dfs.federation.router.http-bind-host 0.0.0.0 HTTP 서버가 실제로 바인딩할 주소.
dfs.federation.router.https-address 0.0.0.0:50072 Router에 대한 웹 요청을 처리하는 HTTPS 주소.
dfs.federation.router.https-bind-host 0.0.0.0 HTTPS 서버가 실제로 바인딩할 주소.

State Store

State Store에 대한 연결과 Router의 내부 캐싱.

속성 기본값 설명
dfs.federation.router.store.enable true true이면 Router가 State Store에 연결합니다.
dfs.federation.router.store.serializer org.apache.hadoop.hdfs.server.federation.store.driver.impl.StateStoreSerializerPBImpl State Store 레코드를 직렬화하는 클래스.
dfs.federation.router.store.driver.class org.apache.hadoop.hdfs.server.federation.store.driver.impl.StateStoreZooKeeperImpl State Store를 구현하는 클래스.
dfs.federation.router.store.connection.test 60000 State Store에 대한 연결을 확인하는 빈도(밀리초).
dfs.federation.router.cache.ttl 60000 State Store 캐시를 새로고침하는 빈도(밀리초).
dfs.federation.router.store.membership.expiration 300000 멤버십 레코드의 만료 시간(밀리초).
dfs.federation.router.store.driver.async.override.max.threads (비어 있음) 오버라이드할 때 레코드를 비동기적으로 덮어쓰고 삭제하는 스레드 수.
dfs.federation.router.mount-table.cache.update false true이면 모든 router에 대해 마운트 테이블 항목이 추가/수정/제거될 때마다 마운트 테이블 캐시가 갱신됩니다.
dfs.federation.router.mount-table.cache.update.timeout 1m 모든 router가 마운트 테이블 캐시 갱신을 마칠 때까지 기다리는 최대 시간.
dfs.federation.router.mount-table.cache.update.client.max.time 5m RouterClient 연결이 캐시될 수 있는 최대 시간.

라우팅

클라이언트 요청을 올바른 하위 클러스터로 전달.

속성 기본값 설명
dfs.federation.router.file.resolver.client.class org.apache.hadoop.hdfs.server.federation.resolver.MountTableResolver 파일을 하위 클러스터로 해석하는 클래스. 마운트 포인트에 여러 하위 클러스터를 활성화하려면 org.apache.hadoop.hdfs.server.federation.resolver.MultipleDestinationMountTableResolver로 설정.
dfs.federation.router.namenode.resolver.client.class org.apache.hadoop.hdfs.server.federation.resolver.MembershipNamenodeResolver 하위 클러스터의 namenode를 해석하는 클래스.

Namenode 모니터링

클라이언트 요청 전달을 위해 하위 클러스터의 namenode를 모니터링.

속성 기본값 설명
dfs.federation.router.heartbeat.enable true true이면 Router가 주기적으로 자신의 상태를 State Store에 하트비트합니다.
dfs.federation.router.namenode.heartbeat.enable (비어 있음) true이면 Router가 namenode 하트비트를 얻어 State Store에 보냅니다. 명시적으로 지정하지 않으면 dfs.federation.router.heartbeat.enable과 같은 값을 받습니다.
dfs.federation.router.heartbeat.interval 5000 Router가 State Store에 하트비트해야 하는 빈도(밀리초).
dfs.federation.router.monitor.namenode (비어 있음) 모니터링하고 하트비트할 namenode의 식별자.
dfs.federation.router.monitor.localnamenode.enable true true이면 Router가 로컬 머신의 namenode를 모니터링해야 합니다.

참고: dfs.federation.router.monitor.localnamenode.enable이 활성화되면 dfs.nameservice.id 구성이 권장됩니다. 이렇게 하면 Router가 로컬 노드를 직접 찾을 수 있습니다. 그렇지 않으면 namenode RPC 주소를 로컬 노드 주소와 일치시켜 nameservice Id를 찾습니다. 여러 주소가 일치하면 Router가 시작에 실패합니다. 또한 로컬 노드가 HA 모드에 있으면 dfs.ha.namenode.id를 구성하는 것이 좋습니다.

할당량

페더레이션에서 지원되는 전역 할당량.

속성 기본값 설명
dfs.federation.router.quota.enable false true이면 Router의 할당량 시스템이 활성화됩니다. 그 경우 Router Admin 서버가 하위 클러스터의 할당량을 전역 할당량으로 덮어쓰므로 하위 클러스터의 할당량을 직접 설정/해제하는 것은 권장되지 않습니다.
dfs.federation.router.quota-cache.update.interval 60s Router가 할당량 캐시를 갱신하는 빈도. 이 설정은 여러 시간 단위 접미사를 지원합니다. 접미사가 없으면 밀리초로 간주합니다.

보안

페더레이션에서 지원되는 Kerberos 및 Delegation token.

속성 기본값 설명
dfs.federation.router.keytab.file (비어 있음) router가 서비스 프린시펄로 로그인하는 데 사용하는 keytab 파일. 프린시펄 이름은 'dfs.federation.router.kerberos.principal'로 구성됩니다.
dfs.federation.router.kerberos.principal (비어 있음) Router 서비스 프린시펄. 보통 router/[email protected]로 설정됩니다. 각 Router는 시작 시 _HOST를 자신의 완전한 호스트 이름으로 대체합니다. _HOST 플레이스홀더는 HA 설정의 모든 Router에서 동일한 구성 설정을 사용할 수 있게 합니다.
dfs.federation.router.kerberos.principal.hostname (비어 있음) 이 구성 파일을 포함하는 Router의 호스트 이름. 각 머신에 따라 다릅니다. 기본값은 현재 호스트 이름.
dfs.federation.router.kerberos.internal.spnego.principal ${dfs.web.authentication.kerberos.principal} Kerberos 보안이 활성화될 때 Router가 웹 UI SPNEGO 인증에 사용하는 서버 프린시펄. 보통 HTTP/[email protected]로 설정됩니다. SPNEGO 서버 프린시펄은 관례상 HTTP/ 접두사로 시작합니다. 값이 '*'이면 웹 서버가 keytab 파일 'dfs.web.authentication.kerberos.keytab'에 지정된 모든 프린시펄로 로그인을 시도합니다.
dfs.federation.router.secret.manager.class org.apache.hadoop.hdfs.server.federation.router.security.token.ZKDelegationTokenSecretManagerImpl 위임 토큰에 state store를 구현하는 클래스. 기본 구현은 위임 토큰을 저장하기 위한 백엔드로 zookeeper를 사용합니다.

격리

구성된 모든 다운스트림 nameservice에 걸친 격리와 전용 RPC 핸들러 할당. 이 숫자들의 합은 총 router 핸들러 수(dfs.federation.router.handler.count로 구성)보다 엄격히 작아야 합니다.

속성 기본값 설명
dfs.federation.router.fairness.policy.controller.class org.apache.hadoop.hdfs.server.federation.fairness.NoRouterRpcFairnessPolicyController 격리 기능이 활성화될 때 사용할 기본 핸들러 할당 모델. 이 기능을 완전히 사용하려면 org.apache.hadoop.hdfs.server.federation.fairness.StaticRouterRpcFairnessPolicyController를 사용하는 것이 좋습니다.
dfs.federation.router.fairness.handler.count.EXAMPLENAMESERVICE (비어 있음) 특정 nameservice에 할당된 전용 핸들러. 지정하지 않으면 모든 nameservice에 걸쳐 균등 할당이 이루어집니다.
dfs.federation.router.fairness.handler.count.concurrent (비어 있음) renewLease 같은 fan out 호출에 할당된 전용 핸들러.

메트릭 (Metrics)

Router와 State Store 통계는 metrics/JMX로 노출됩니다. 이 정보는 모니터링에 매우 유용합니다. 더 많은 메트릭 정보는 RBF Metrics, Router RPC Metrics 및 State Store Metrics를 참고하세요.

Router Federation Rename

네임스페이스 간 rename을 Router에서 활성화합니다. 현재는 HDFS Federation Balance 기반으로 구현되며 일반 rename과 비교해 몇 가지 제한이 있습니다. 1. 일반 rename보다 훨씬 느리므로 더 긴 RPC 타임아웃 구성이 필요합니다. RPC 타임아웃에 대한 자세한 내용은 ipc.client.rpc-timeout.ms와 그 설명을 참고하세요. 2. 스냅샷 경로를 지원하지 않습니다. 3. 여러 대상을 가진 경로의 rename을 지원하지 않습니다.

속성 기본값 설명
dfs.federation.router.federation.rename.option NONE 네임스페이스 간 rename 시 동작을 지정합니다. 옵션은 NONE(네임스페이스 간 rename 거부)과 DISTCP(distcp로 네임스페이스 간 rename)입니다.
dfs.federation.router.federation.rename.force.close.open.file true DIFF_DISTCP 단계에서 차이가 없을 때 열린 파일을 모두 강제로 닫습니다.
dfs.federation.router.federation.rename.map (비어 있음) 복사에 사용할 최대 동시 맵 수.
dfs.federation.router.federation.rename.bandwidth (비어 있음) 맵당 대역폭을 MB로 지정합니다.
dfs.federation.router.federation.rename.delay 1000 작업이 재시도해야 할 때 지연 시간(밀리초)을 지정합니다.
dfs.federation.router.federation.rename.diff 0 증분 복사 단계에서 사용되는 diff 항목의 임계값을 지정합니다.
dfs.federation.router.federation.rename.trash trash 이 옵션은 3가지 값이 있습니다: trash(소스 경로를 쓰레기통으로 이동), delete(소스 경로를 직접 삭제), skip(쓰레기통과 삭제 모두 건너뜀).

비동기 Router RPC (Asynchronous Router RPC)

비동기 router RPC는 높은 동시성과 여러 명명 서비스 시나리오에서 동기 router RPC의 성능 병목을 해결하도록 설계되었습니다. 비동기 처리 메커니즘을 도입해 요청 처리 프로세스를 최적화하고, 시스템의 동시성 용량과 리소스 활용 효율을 향상시킵니다.

이 기능에 대한 자세한 정보는 Apache JIRA 티켓 HDFS-17531을 참고하세요.

비동기 router RPC 스레드

  • Handler: CallQueue에서 RpcCall을 꺼내 사전 처리를 수행합니다. 예외(마운트 포인트가 없는 경우 등)가 발생하면 응답을 직접 response queue에 넣습니다. 그렇지 않으면 RpcCall을 Async-Handler로 전달합니다.
  • Async-Handler: RpcCall을 연결 스레드의 connection.calls에 넣고 블로킹 없이 즉시 반환합니다.
  • Async-Responder: 연결 스레드가 받은 응답 처리를 담당합니다. RpcCall을 재시도해야 하면(다운스트림 서비스가 StandbyException을 반환하는 경우 등) RpcCall을 connection.calls에 다시 추가합니다. 그렇지 않으면 응답을 ResponseQueue에 넣습니다.
  • Responder: ResponseQueue에서 응답을 꺼내 클라이언트에 반환합니다.

비동기 Router RPC의 장점

  • 높은 처리 성능: 비동기 RPC 처리 메커니즘 덕분에 비동기 router는 동시에 많은 요청을 처리할 수 있습니다. 이는 시스템의 동시 처리 용량을 크게 향상시킬 뿐 아니라 전반적인 처리량을 최적화합니다. 이 메커니즘은 시스템이 높은 트래픽 요청에 빠르게 응답하고 고부하 조건에서도 효율적으로 작동하게 합니다.
  • 높은 리소스 활용: 비동기 설계는 스레드 블로킹과 빈번한 스레드 전환을 효과적으로 줄입니다. 결과적으로 스레드와 관련된 리소스 낭비를 최소화해 시스템의 전반적 효율을 높이고 CPU 유휴 시간을 줄입니다.
  • 격리(Isolation): 서로 다른 name-service는 별개의 비동기 프로세서 스레드 풀을 사용합니다. 이 아키텍처는 name-service 간 격리를 달성합니다. 특정 name-service가 성능 저하를 겪어도 다른 name-service의 처리 능력에 영향을 주지 않아 전체 시스템의 안정성과 신뢰성을 보장합니다.

비동기 Router RPC 구성

속성 기본값 설명
dfs.federation.router.async.rpc.enable false true이면 router가 RpcCall을 비동기적으로 처리합니다.
dfs.federation.router.async.rpc.ns.handler.count (비어 있음) nameservice당 async-handler 수. 쉼표로 구분하고, 내부적으로는 콜론으로 구분합니다. nameservice의 식별자는 dfs.nameservices 구성 항목에 있습니다. 예: ns1:count1,ns2:count2,ns3:count3.
dfs.federation.router.async.rpc.handler.count 10 dfs.federation.router.async.rpc.ns.handler.count 구성 항목에 없는 nameservice에 대해 이 값을 async-handler 수로 사용합니다.
dfs.federation.router.async.rpc.responder.count 10 async-responder의 스레드 수.

더 알아보기 (Learn more)