ViewFs 가이드

ViewFs 가이드 (View File System Guide)

여러 Hadoop 파일 시스템 네임스페이스(또는 네임스페이스 볼륨)를 관리하는 View File System(ViewFs) 을 설명하는 문서예요. 페더레이션 클러스터에서 클러스터별 전역 네임스페이스를 제공하며, Nfly 마운트 지점, 정규식 기반 마운트 지점을 다룹니다.

출처: 문서

본문

소개 (Introduction)

View File System(ViewFs)은 여러 Hadoop 파일 시스템 네임스페이스(또는 네임스페이스 볼륨)를 관리하는 방법을 제공합니다. HDFS Federation에서 여러 네임노드, 따라서 여러 네임스페이스를 가진 클러스터에 특히 유용해요. ViewFs는 일부 Unix/Linux 시스템의 클라이언트 측 마운트 테이블 과 유사합니다. ViewFs로 개인화된 네임스페이스 뷰와 클러스터별 공통 뷰를 만들 수 있습니다.

이 가이드는 여러 클러스터(각 클러스터는 여러 네임스페이스로 페더레이션될 수 있음)를 가진 Hadoop 시스템 맥락에서 다룹니다. 또한 페더레이션된 HDFS에서 ViewFs를 사용해 클러스터별 전역 네임스페이스를 제공해, 애플리케이션이 페더레이션 전 세계와 비슷하게 동작할 수 있게 하는 방법을 설명합니다.

옛 세계 (페더레이션 이전) (The Old World)

단일 네임노드 클러스터

HDFS Federation 이전의 옛 세계에서 클러스터는 그 클러스터를 위한 단일 파일 시스템 네임스페이스를 제공하는 단일 네임노드를 가집니다. 여러 클러스터가 있다고 합시다. 각 클러스터의 파일 시스템 네임스페이스는 완전히 독립적이고 서로소입니다. 또한 물리 저장소는 클러스터 간에 공유되지 않습니다(즉 Datanode가 클러스터 간에 공유되지 않음).

각 클러스터의 core-site.xml에는 기본 파일 시스템을 그 클러스터의 네임노드로 설정하는 구성 속성이 있습니다.

<property>
  <name>fs.default.name</name>
  <value>hdfs://namenodeOfClusterX:port</value>
</property>

이런 구성 속성을 사용하면 슬래시 상대 이름으로 클러스터 네임노드 기준 경로를 해석할 수 있습니다. 예를 들어 경로 /foo/bar는 위 구성을 사용해 hdfs://namenodeOfClusterX:port/foo/bar를 가리킵니다.

이 구성 속성은 각 클러스터의 게이트웨이와 JobTracker, Oozie 같은 해당 클러스터의 핵심 서비스에도 설정됩니다.

경로명 사용 패턴 (Pathnames Usage Patterns)

core-site.xml이 위와 같이 설정된 Cluster X의 일반적인 경로명은 다음과 같습니다.

  1. /foo/bar
    • 앞에서처럼 hdfs://namenodeOfClusterX:port/foo/bar와 동일합니다.
  2. hdfs://namenodeOfClusterX:port/foo/bar
    • 유효한 경로명이지만, 필요할 때 애플리케이션과 데이터를 투명하게 다른 클러스터로 옮길 수 있게 해 주는 /foo/bar를 쓰는 것이 더 좋습니다.
  3. hdfs://namenodeOfClusterY:port/foo/bar
    • Cluster Y 같은 다른 클러스터의 경로명을 가리키는 URI입니다. 특히 Cluster Y에서 Cluster Z로 파일을 복사하는 명령은 다음과 같습니다.
      distcp hdfs://namenodeClusterY:port/pathSrc hdfs://namenodeClusterZ:port/pathDest
      
  4. webhdfs://namenodeClusterX:http_port/foo/bar
    • WebHDFS 파일 시스템을 통해 파일에 접근하는 URI입니다. WebHDFS는 네임노드의 RPC 포트가 아니라 HTTP 포트를 사용한다는 점에 유의하세요.
  5. http://namenodeClusterX:http_port/webhdfs/v1/foo/bar 및 http://proxyClusterX:http_port/foo/bar
    • 각각 WebHDFS REST API와 HDFS 프록시를 통해 파일에 접근하는 HTTP URL입니다.

경로명 사용 모범 사례 (Pathname Usage Best Practices)

클러스터 안에 있을 때는 위 (2)와 같은 완전히 정규화된 URI 대신 (1) 유형의 경로명을 사용하는 것이 권장됩니다. 완전히 정규화된 URI는 주소와 비슷하며 애플리케이션이 데이터와 함께 이동할 수 없게 합니다.

새 세계 — 페더레이션과 ViewFs (New World)

클러스터의 모습 (How The Clusters Look)

여러 클러스터가 있다고 합시다. 각 클러스터는 하나 이상의 네임노드를 가집니다. 각 네임노드는 자신의 네임스페이스를 가집니다. 네임노드는 정확히 하나의 클러스터에 속해요. 같은 클러스터의 네임노드들은 그 클러스터의 물리 저장소를 공유합니다. 클러스터 간 네임스페이스는 이전처럼 독립적입니다.

운영 담당자는 저장소 요구에 따라 클러스터 안의 각 네임노드에 무엇을 저장할지 결정합니다. 예를 들어 모든 사용자 데이터(/user/<username>)를 한 네임노드에, 모든 피드 데이터(/data)를 다른 네임노드에, 모든 프로젝트(/projects)를 또 다른 네임노드에 둘 수 있습니다.

ViewFs를 사용한 클러스터별 전역 네임스페이스

옛 세계와의 투명성을 제공하기 위해 ViewFs 파일 시스템(즉 클라이언트 측 마운트 테이블)을 사용해 각 클러스터에 옛 세계의 네임스페이스와 비슷한 독립적 클러스터 네임스페이스 뷰를 만듭니다. 클라이언트 측 마운트 테이블은 Unix 마운트 테이블과 같으며, 옛 네이밍 규약으로 새 네임스페이스 볼륨을 마운트합니다. 다음 그림은 /user, /data, /projects, /tmp의 네 개 네임스페이스 볼륨을 마운트하는 마운트 테이블을 보여줍니다.

ViewFs는 HDFS와 로컬 파일 시스템처럼 Hadoop 파일 시스템 인터페이스를 구현합니다. 다른 파일 시스템에 연결만 허용한다는 점에서 사소한(trivial) 파일 시스템입니다. ViewFs가 Hadoop 파일 시스템 인터페이스를 구현하므로 Hadoop 도구와 투명하게 동작합니다. 예를 들어 모든 셸 명령이 HDFS와 로컬 파일 시스템처럼 ViewFs에서 동작합니다.

각 클러스터 구성에서 기본 파일 시스템은 아래처럼 해당 클러스터의 마운트 테이블로 설정됩니다(단일 네임노드 클러스터의 구성과 비교).

<property>
  <name>fs.defaultFS</name>
  <value>viewfs://clusterX</value>
</property>

URI에서 viewfs:// 스킴을 따르는 authority가 마운트 테이블 이름입니다. 클러스터의 마운트 테이블은 클러스터 이름으로 명명하는 것이 권장됩니다. 그러면 Hadoop 시스템이 Hadoop 구성 파일에서 "clusterX"라는 이름의 마운트 테이블을 찾습니다. 운영 담당자는 모든 게이트웨이와 서비스 머신에 모든 클러스터의 마운트 테이블을 배치해서, 각 클러스터에 대해 기본 파일 시스템이 위에서 설명한 대로 해당 클러스터의 ViewFs 마운트 테이블로 설정되게 합니다.

마운트 테이블의 마운트 지점은 표준 Hadoop 구성 파일에 지정됩니다. viewfs의 모든 마운트 테이블 구성 항목은 fs.viewfs.mounttable. 접두어가 붙습니다. 다른 파일 시스템을 연결하는 마운트 지점은 link 태그로 지정합니다. 마운트 지점 이름은 연결된 파일 시스템 대상 위치와 같게 하는 것이 권장됩니다. 마운트 테이블에 구성되지 않은 모든 네임스페이스는 linkFallback으로 기본 파일 시스템에 폴백시킬 수 있습니다.

아래 마운트 테이블 구성에서 네임스페이스 /data는 파일 시스템 hdfs://nn1-clusterx.example.com:8020/data에, /project는 hdfs://nn2-clusterx.example.com:8020/project에 연결됩니다. /logs 같은 마운트 테이블에 구성되지 않은 모든 네임스페이스는 hdfs://nn5-clusterx.example.com:8020/home에 연결됩니다.

<configuration>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./data</name>
    <value>hdfs://nn1-clusterx.example.com:8020/data</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./project</name>
    <value>hdfs://nn2-clusterx.example.com:8020/project</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./user</name>
    <value>hdfs://nn3-clusterx.example.com:8020/user</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./tmp</name>
    <value>hdfs://nn4-clusterx.example.com:8020/tmp</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.linkFallback</name>
    <value>hdfs://nn5-clusterx.example.com:8020/home</value>
  </property>
</configuration>

대안으로 linkMergeSlash로 마운트 테이블의 루트를 다른 파일 시스템의 루트에 병합할 수 있습니다. 아래 구성에서 clusterY의 루트는 hdfs://nn1-clustery.example.com:8020의 루트 파일 시스템과 병합됩니다.

<configuration>
  <property>
    <name>fs.viewfs.mounttable.clusterY.linkMergeSlash</name>
    <value>hdfs://nn1-clustery.example.com:8020/</value>
  </property>
</configuration>

경로명 사용 패턴 (Pathname Usage Patterns)

core-site.xml이 기본 fs를 그 클러스터의 마운트 테이블로 쓰도록 설정된 Cluster X의 일반적인 경로명은 다음과 같습니다.

  1. /foo/bar
    • viewfs://clusterX/foo/bar와 동일합니다. 이런 경로명을 옛 비페더레이션 세계에서 썼다면, 페더레이션 세계로의 전환이 투명합니다.
  2. viewfs://clusterX/foo/bar
    • 유효한 경로명이지만, 필요할 때 애플리케이션과 데이터를 투명하게 옮길 수 있게 해 주는 /foo/bar를 쓰는 것이 좋습니다.
  3. viewfs://clusterY/foo/bar
    • Cluster Y 같은 다른 클러스터의 경로명을 가리키는 URI입니다. Cluster Y에서 Cluster Z로 파일을 복사하는 명령은 다음과 같습니다.
      distcp viewfs://clusterY/pathSrc viewfs://clusterZ/pathDest
      
  4. viewfs://clusterX-webhdfs/foo/bar
    • WebHDFS 파일 시스템을 통해 파일에 접근하는 URI입니다.
  5. http://namenodeClusterX:http_port/webhdfs/v1/foo/bar 및 http://proxyClusterX:http_port/foo/bar
    • 각각 WebHDFS REST API와 HDFS 프록시를 통해 파일에 접근하는 HTTP URL입니다. 이전과 같습니다.

경로명 사용 모범 사례 (Pathname Usage Best Practices)

클러스터 안에 있을 때는 (2)와 같은 완전히 정규화된 URI보다 (1) 유형의 경로명을 사용하는 것이 권장됩니다. 또한 애플리케이션은 마운트 지점에 대한 지식을 사용해 특정 네임노드의 파일을 가리키는 hdfs://namenodeContainingUserDirs:port/joe/foo/bar 같은 경로를 쓰면 안 됩니다. 대신 /user/joe/foo/bar를 사용해야 해요.

네임스페이스 간 경로명 이름 바꾸기 (Renaming Pathnames Across Namespaces)

옛 세계에서 네임노드나 클러스터를 가로질러 파일·디렉터리 이름을 바꿀 수 없었다는 점을 기억하세요. 새 세계에서도 마찬가지이지만 추가적인 복잡함이 있습니다. 예를 들어 옛 세계에서는 아래 명령을 수행할 수 있었습니다.

rename /user/joe/myStuff /data/foo/bar

새 세계에서는 /user와 /data가 실제로 클러스터 안의 서로 다른 네임노드에 저장돼 있다면 이것은 동작하지 않습니다.

Nfly 마운트 지점을 사용한 다중 파일 시스템 I/O

HDFS와 다른 분산 파일 시스템은 블록 복제나 더 정교한 분산 인코딩 같은 일종의 중복성으로 데이터 탄력성을 제공합니다. 하지만 현대 설정은 여러 Hadoop 클러스터, 엔터프라이즈 파일러, 온프레미스/오프프레미스 호스팅으로 구성될 수 있어요. Nfly 마운트 지점은 단일 논리 파일을 여러 파일 시스템이 동기적으로 복제할 수 있게 합니다. 최대 1GB까지의 비교적 작은 파일을 위해 설계됐습니다. 일반적으로 단일 코어/단일 네트워크 링크 성능의 함수인데, FsShell이나 MapReduce 작업 같은 ViewFs를 사용하는 단일 클라이언트 JVM에 로직이 있기 때문이에요.

기본 구성 (Basic Configuration)

Nfly의 기본 구성을 이해하기 위해 다음 예시를 생각해 봅시다. ads 디렉터리를 uri1, uri2, uri3로 표현되는 세 파일 시스템에 복제해 유지하고 싶다고 합시다.

<property>
  <name>fs.viewfs.mounttable.global.linkNfly../ads</name>
  <value>uri1,uri2,uri3</value>
</property>

속성 이름의 연속된 .. 2개에 유의하세요. 이는 다음 절에서 보여줄 마운트 지점의 고급 조정을 위한 빈 설정 때문에 생깁니다. 속성 값은 URI의 쉼표 구분 목록입니다.

URI는 여러 리전의 서로 다른 클러스터 hdfs://datacenter-east/ads, s3a://models-us-west/ads, hdfs://datacenter-west/ads를 가리키거나, 가장 단순한 경우 같은 파일 시스템 아래의 다른 디렉터리 file:/tmp/ads1, file:/tmp/ads2, file:/tmp/ads3를 가리킬 수 있습니다.

전역 경로 viewfs://global/ads 아래에서 수행되는 모든 수정 은 기본 시스템이 사용 가능하면 모든 대상 URI에 전파됩니다.

예를 들어 hadoop 셸로 파일을 만들면

hadoop fs -touchz viewfs://global/ads/z1

후자 구성에서 로컬 파일 시스템으로 그것을 찾을 수 있습니다.

ls -al /tmp/ads*/z1
-rw-r--r--  1 user  wheel  0 Mar 11 12:17 /tmp/ads1/z1
-rw-r--r--  1 user  wheel  0 Mar 11 12:17 /tmp/ads2/z1
-rw-r--r--  1 user  wheel  0 Mar 11 12:17 /tmp/ads3/z1

전역 경로에서의 읽기는 예외를 일으키지 않는 첫 번째 파일 시스템으로 처리됩니다. 파일 시스템에 접근하는 순서는 그 시점에 사용 가능한지, 그리고 토폴로지 순서가 존재하는지에 따라 달라집니다.

고급 구성 (Advanced Configuration)

마운트 지점 linkNfly는 쉼표 구분 key=value 쌍 목록으로 전달되는 파라미터로 더 구성할 수 있습니다. 현재 다음 파라미터가 지원됩니다.

minReplication=int는 예외 없이 쓰기 수정을 처리해야 하는 대상의 최소 수를 결정합니다. 이 수 미만이면 nfly 쓰기가 실패합니다. minReplication을 대상 URI 수보다 높게 두는 것은 구성 오류입니다. 기본값 2.

minReplication이 대상 URI 수보다 낮으면 최신 쓰기가 없는 대상 URI가 있을 수 있습니다. 이는 다음 설정으로 제어되는 더 비싼 읽기 연산으로 보상할 수 있습니다.

readMostRecent=boolean이 true로 설정되면 Nfly 클라이언트가 첫 번째 토폴로지 순서 URI 대신 모든 대상 URI 아래 경로를 확인하게 합니다. 그 시점에 사용 가능한 것 중 가장 최근 수정 시간을 가진 것을 처리합니다.

repairOnRead=boolean이 true로 설정되면 Nfly가 최신 복제본을 오래된 대상에 복사해, 이후 읽기를 다시 가장 가까운 복제본에서 저렴하게 할 수 있게 합니다.

네트워크 토폴로지 (Network Topology)

Nfly는 "가장 가까운" 대상 URI에서 읽기를 충족시키고자 합니다. 이를 위해 Nfly는 Rack Awareness의 개념을 대상 URI의 authority로 확장합니다.

Nfly는 URI authority를 해석하기 위해 NetworkTopology를 적용합니다. 가장 흔히 스크립트 기반 매핑이 이기종 설정에서 사용됩니다. 다음 토폴로지 매핑을 제공하는 스크립트가 있을 수 있습니다.

URI 토폴로지
hdfs://datacenter-east/ads /us-east/onpremise-hdfs
s3a://models-us-west/ads /us-west/aws
hdfs://datacenter-west/ads /us-west/onpremise-hdfs

file:/처럼 대상 URI에 authority 부분이 없으면 Nfly는 클라이언트의 로컬 노드 이름을 주입합니다.

예시 Nfly 구성 (Example Nfly Configuration)

<property>
  <name>fs.viewfs.mounttable.global.linkNfly.minReplication=3,readMostRecent=true,repairOnRead=false./ads</name>
  <value>hdfs://datacenter-east/ads,hdfs://datacenter-west/ads,s3a://models-us-west/ads,file:/tmp/ads</value>
</property>

Nfly 파일 생성 작동 방식 (How Nfly File Creation works)

FileSystem fs = FileSystem.get("viewfs://global/", ...);
FSDataOutputStream out = fs.create("viewfs://global/ads/f1");
out.write(...);
out.close();

위 코드는 다음 실행을 일으킵니다.

  1. 각 대상 URI 아래에 보이지 않는 파일 _nfly_tmp_f1을 만듭니다. 즉 hdfs://datacenter-east/ads/_nfly_tmp_f1, hdfs://datacenter-west/ads/_nfly_tmp_f1 등입니다. 이는 기본 파일 시스템에서 create를 호출해 네 출력 스트림을 모두 감싸는 FSDataOutputStream 객체 out을 반환해 수행됩니다.
  2. 따라서 out에 대한 각 후속 쓰기는 각 감싸진 스트림에 전달될 수 있습니다.
  3. out.close에서 모든 스트림이 닫히고, 파일이 _nfly_tmp_f1에서 f1로 이름이 바뀝니다. 모든 파일은 이 단계 시작 시점의 클라이언트 시스템 시간에 해당하는 같은 수정 시간 을 받습니다.
  4. 최소 minReplication 대상이 실패 없이 1-3단계를 통과하면 Nfly는 트랜잭션을 논리적으로 커밋된 것으로 간주하고, 그렇지 않으면 임시 파일을 최선으로 정리하려 합니다.

참고: 4단계는 최선(best-effort) 단계이고 클라이언트 JVM이 크래시해 작업을 재개하지 못할 수 있으므로, 이런 _nfly_tmp 파일을 정리하는 어떤 cron 작업을 준비해 두는 것이 좋습니다.

FAQ

  1. 비페더레이션 세계에서 페더레이션 세계로 이동할 때 서로 다른 볼륨의 네임노드를 추적해야 하는데, 어떻게 하나요? 아니요, 그럴 필요 없습니다. 위 예시를 보세요. 상대 이름을 사용해 기본 파일 시스템을 활용하거나, 경로를 hdfs://namenodeCLusterX/foo/bar에서 viewfs://clusterX/foo/bar로 바꾸는 것입니다.
  2. 운영 담당자가 클러스터 안에서 파일을 한 네임노드에서 다른 네임노드로 옮기면 어떻게 되나요? 운영 담당자는 저장소 용량 문제를 다루기 위해 한 네임노드에서 다른 네임노드로 파일을 옮길 수 있습니다. 애플리케이션이 깨지지 않도록 방지하는 방식으로 그렇게 할 거예요. 몇 가지 예를 들어봅시다.
    • 예시 1: /user와 /data가 한 네임노드에 있었는데 용량 문제로 나중에 별도 네임노드에 있어야 한다면, 운영 담당자는 /user와 /data에 별도 마운트 지점을 만들었을 것입니다. 변경 전에는 /user와 /data의 마운트가 같은 네임노드(예: namenodeContainingUserAndData)를 가리켰을 것입니다. 운영 담당자는 마운트 지점이 각각 namenodeContaingUser와 namenodeContainingData로 바뀌도록 마운트 테이블을 갱신합니다.
    • 예시 2: 모든 프로젝트가 한 네임노드에 맞춰졌는데 나중에 둘 이상의 네임노드가 필요하다면, ViewFs는 /project/foo와 /project/bar 같은 마운트를 허용합니다. 이로써 마운트 테이블이 해당 네임노드를 가리키도록 갱신될 수 있습니다.
  3. 마운트 테이블은 각 core-site.xml 에 있습니까, 아니면 별도 파일에 있습니까? 계획은 마운트 테이블을 별도 파일에 두고 core-site.xml이 그것을 xinclude 하는 것입니다. 각 머신에 로컬로 파일을 둘 수도 있지만, 중앙 위치에서 HTTP로 접근하는 것이 더 좋습니다.
  4. 구성에 한 클러스터만 마운트 테이블 정의를 가져야 합니까, 아니면 모든 클러스터를 가져야 합니까? 구성이 모든 클러스터의 마운트 정의를 가져야 합니다. distcp 같은 것으로 다른 클러스터의 데이터에도 접근해야 하기 때문입니다.
  5. 운영 담당자가 시간에 따라 마운트 테이블을 바꿀 수 있는데, 마운트 테이블은 언제 실제로 읽히나요? 마운트 테이블은 작업이 클러스터에 제출될 때 읽힙니다. core-site.xml의 XInclude는 작업 제출 시 확장됩니다. 이는 마운트 테이블이 바뀌면 작업을 다시 제출해야 한다는 뜻입니다. 그래서 마운트 테이블 변경 필요성을 크게 줄이는 merge-mount를 구현하려고 합니다. 또한 미래에는 작업 시작 시 초기화되는 다른 메커니즘으로 마운트 테이블을 읽고 싶습니다.
  6. JobTracker(또는 Yarn의 Resource Manager) 자체가 ViewFs를 사용할까요? 아니요, 그럴 필요 없습니다. NodeManager도 마찬가지입니다.
  7. ViewFs는 최상위 레벨에서만 마운트를 허용하나요? 아니요, 더 일반적입니다. 예: /user/joe와 /user/jane을 마운트할 수 있습니다. 이 경우 마운트 테이블의 /user에 대해 내부 읽기 전용 디렉터리가 만들어집니다. /user에 대한 모든 연산은 유효하지만 /user는 읽기 전용입니다.
  8. 애플리케이션이 클러스터 간에 작업하며 파일 경로를 영속적으로 저장해야 합니다. 어떤 경로를 저장해야 하나요? 애플리케이션을 실행할 때 사용하는 것과 같은 viewfs://cluster/path 유형의 경로명을 저장해야 합니다. 이는 운영 담당자가 투명하게 이동하는 한, 클러스터 안의 네임노드 내 데이터 이동으로부터 사용자를 격리합니다. 데이터가 한 클러스터에서 다른 클러스터로 이동되면 격리되지 않습니다. 옛(페더레이션 이전) 세계도 클러스터 간 데이터 이동으로부터 보호하지 못했습니다.
  9. 위임 토큰(delegation token)은 어떻게 되나요? 작업을 제출하는 클러스터에 대한 위임 토큰(그 클러스터의 마운트 테이블의 모든 마운트 볼륨 포함)과 map-reduce 작업의 입력·출력 경로에 대한 위임 토큰(지정된 입력·출력 경로의 마운트 테이블로 마운트된 모든 볼륨 포함)은 모두 자동으로 처리됩니다. 또한 특별한 상황을 위해 기본 클러스터 구성에 추가 위임 토큰을 더하는 방법도 있습니다.

스킴을 바꾸기 싫거나 마운트 테이블 구성을 모든 클라이언트에 복사하기 어렵나요?

View File System Overload Scheme Guide를 참고하세요.

정규식 패턴 기반 마운트 지점 (Regex Pattern Based Mount Points)

view 파일 시스템 마운트 지점은 Key-Value 기반 매핑 시스템이었습니다. 매핑 구성을 규칙으로 추상화할 수 있는 사용 사례에는 친숙하지 않아요. 예를 들어 사용자마다 GCS 버킷을 제공하고 총 수천 명의 사용자가 있을 수 있습니다. 옛 key-value 기반 접근은 몇 가지 이유로 잘 동작하지 않습니다.

  1. 마운트 테이블은 FileSystem 클라이언트가 사용합니다. 구성을 모든 클라이언트에 퍼뜨리는 데 비용이 있고 가능하면 피해야 합니다. View File System Overload Scheme Guide가 중앙 마운트 테이블 관리로 배포를 도울 수 있습니다. 하지만 여전히 매 변경마다 마운트 테이블을 갱신해야 해요. 규칙 기반 마운트 테이블을 제공하면 변경을 크게 줄일 수 있습니다.
  2. 클라이언트는 마운트 테이블의 모든 KV를 이해해야 합니다. 마운트 테이블이 수천 항목으로 커지면 이상적이지 않습니다. 예를 들어 사용자가 하나만 필요해도 수천 개의 파일 시스템이 초기화될 수 있습니다. 구성 자체도 대규모에서 비대해집니다.

차이 이해하기 (Understand the Difference)

key-value 기반 마운트 테이블에서 view 파일 시스템은 모든 마운트 지점을 파티션으로 취급합니다. 모든 파티션에 대한 연산을 초래하는 여러 파일 시스템 API가 있습니다. 예를 들어 여러 마운트가 있는 HDFS 클러스터가 있다고 합시다. 사용자가 로컬 디스크에서 HDFS 클러스터로 데이터를 복사하려고 "hadoop fs -put file <viewfs://hdfs.namenode.apache.org/tmp/" 명령을 실행하려 합니다. 이 명령은 ViewFileSystem이 모든 마운트 지점에 대해 파일 시스템을 초기화할 setVerifyChecksum() 메서드를 호출하게 합니다. 정규식 규칙 기반 마운트 테이블 항목은 파싱될 때까지 해당 경로를 알 수 없습니다. 그래서 이런 경우 정규식 기반 마운트 테이블 항목은 무시됩니다. 파일 시스템(ChRootedFileSystem)은 접근 시 생성됩니다. 하지만 기본 파일 시스템은 ViewFileSystem의 내부 캐시에 의해 캐시됩니다.

<property>
    <name>fs.viewfs.rename.strategy</name>
    <value>SAME_FILESYSTEM_ACROSS_MOUNTPOINT</value>
</property>

기본 정규식 링크 매핑 구성 (Basic Regex Link Mapping Config)

기본 정규식 마운트 지점 구성 예시입니다. ${username}은 Java Regex의 명명된 캡처 그룹입니다.

<property>
    <name>fs.viewfs.mounttable.hadoop-nn.linkRegx./^(?<username>\w+)</name>
    <value>gs://${username}.hadoop.apache.org/</value>
</property>

파싱 예시:

viewfs://hadoop-nn/user1/dir1 => gs://user1.hadoop.apache.org/dir1
viewfs://hadoop-nn/user2 => gs://user2.hadoop.apache.org/

src/key의 형식은 다음과 같습니다.

fs.viewfs.mounttable.${VIEWNAME}.linkRegx.${REGEX_STR}

인터셉터가 있는 정규식 링크 매핑 (Regex Link Mapping With Interceptors)

Interceptor는 해석 과정에서 소스나 대상을 수정하기 위해 도입된 메커니즘입니다. 선택 사항이며 특정 문자 교체나 특정 단어 교체 같은 사용 사례를 충족하는 데 사용할 수 있어요. Interceptor는 정규식 마운트 지점에서만 작동합니다. RegexMountPointResolvedDstPathReplaceInterceptor가 지금 유일한 내장 인터셉터입니다.

RegexMountPointResolvedDstPathReplaceInterceptor가 설정된 정규식 마운트 지점 항목 예시:

<property>
    <name>fs.viewfs.mounttable.hadoop-nn.linkRegx.replaceresolveddstpath:_:-#./^(?<username>\w+)</name>
    <value>gs://${username}.hadoop.apache.org/</value>
</property>

replaceresolveddstpath:_:-는 인터셉터 설정입니다. "replaceresolveddstpath"는 인터셉터 유형, "_"는 교체할 문자열, "-"는 교체 후 문자열입니다.

파싱 예시:

viewfs://hadoop-nn/user_ad/dir1 => gs://user-ad.hadoop.apache.org/dir1
viewfs://hadoop-nn/user_ad_click => gs://user-ad-click.hadoop.apache.org/

src/key의 형식은 다음과 같습니다.

fs.viewfs.mounttable.${VIEWNAME}.linkRegx.${REGEX_STR}
fs.viewfs.mounttable.${VIEWNAME}.linkRegx.${interceptorSettings}#.${srcRegex}

부록: 마운트 테이블 구성 예시 (Appendix)

일반적으로 사용자가 마운트 테이블을 정의하거나 사용할 core-site.xml을 정의할 필요는 없습니다. 이것은 운영 담당자가 하고, 오늘날 core-site.xml처럼 올바른 게이트웨이 머신에 올바른 구성이 설정됩니다.

마운트 테이블은 core-site.xml에 설명할 수 있지만, core-site.xml에서 indirection을 사용해 별도 구성 파일(예: mountTable.xml)을 참조하는 것이 더 좋습니다. mountTable.xml을 참조하도록 core-site.xml에 다음 구성 요소를 추가하세요.

<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> 
  <xi:include href="mountTable.xml" />
</configuration> 

mountTable.xml 파일에는 세 개의 네임노드가 관리하는 세 개의 네임스페이스 볼륨의 페더레이션인 가상 클러스터에 대한 마운트 테이블 "clusterX"의 정의가 있습니다.

  1. nn1-clusterx.example.com:8020,
  2. nn2-clusterx.example.com:8020,
  3. nn3-clusterx.example.com:8020.

여기서 /home과 /tmp는 네임노드 nn1-clusterx.example.com:8020이 관리하는 네임스페이스에 있고, 프로젝트 /foo와 /bar는 페더레이션 클러스터의 다른 네임노드에 호스팅됩니다. 홈 디렉터리 기본 경로가 /home으로 설정되어, 각 사용자가 FileSystem/FileContext에 정의된 getHomeDirectory() 메서드로 자신의 홈 디렉터리에 접근할 수 있습니다.

<configuration>
  <property>
    <name>fs.viewfs.mounttable.clusterX.homedir</name>
    <value>/home</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./home</name>
    <value>hdfs://nn1-clusterx.example.com:8020/home</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./tmp</name>
    <value>hdfs://nn1-clusterx.example.com:8020/tmp</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./projects/foo</name>
    <value>hdfs://nn2-clusterx.example.com:8020/projects/foo</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.clusterX.link./projects/bar</name>
    <value>hdfs://nn3-clusterx.example.com:8020/projects/bar</value>
  </property>
</configuration>

더 알아보기 (Learn more)