Hadoop 인터페이스 분류: 대상(Audience)과 안정성(Stability) 분류

Hadoop 인터페이스 분류: 대상(Audience)과 안정성(Stability) 분류

여기서 제공하는 인터페이스 분류(interface taxonomy)는 인터페이스의 개발자와 사용자를 위한 안내입니다. 이 분류는 개발자가 인터페이스의 대상 사용자(audience)와 안정성(stability)을 선언하도록 안내합니다.

출처: Hadoop Interface Taxonomy: Audience and Stability Classification

  • 인터페이스 사용자에게 주는 이점: 어떤 인터페이스를 쓰고 쓰지 말아야 하는지, 그리고 그 안정성이 무엇인지 알 수 있습니다.
  • 개발자에게 주는 이점: 인터페이스의 우발적 변경, 나아가 사용자나 다른 구성요소·시스템에 대한 우발적 영향을 막아줍니다. 특히 프로젝트의 공유 상태/이력을 모두 공유하지 못하는 많은 개발자가 있는 대규모 시스템에서 유용합니다.

인터페이스 분류

Hadoop은 다음 인터페이스 분류를 채택합니다. 이 분류는 OpenSolaris 분류에서 유래했으며, 어느 정도 Yahoo 내부에서 사용하는 분류에서도 비롯되었습니다. 인터페이스에는 두 가지 주요 속성이 있습니다: **Audience(대상)**와 Stability(안정성).

Audience (대상)

Audience는 인터페이스의 잠재적 소비자를 뜻합니다. 많은 인터페이스는 구현에 대해 내부적/비공개(Private)인 반면, 다른 인터페이스는 애플리케이션 및/또는 클라이언트가 더 넓게 사용하도록 만들어진 공개/외부(Public/External) 인터페이스입니다. 예를 들어 POSIX에서 libc는 외부 또는 공개 인터페이스인 반면, 커널의 많은 부분은 내부 또는 비공개 인터페이스입니다. 또한 일부 인터페이스는 다른 특정 하위 시스템을 대상으로 합니다.

인터페이스의 대상을 식별하면 그것을 깨뜨릴 때의 영향을 정의하는 데 도움이 됩니다. 예를 들어 대상이 소수의 특정 하위 시스템뿐인 인터페이스의 호환성을 깨뜨리는 것은 괜찮을 수 있습니다. 반면 수백만 인터넷 사용자가 의존하는 프로토콜 인터페이스를 깨뜨리는 것은 아마 괜찮지 않을 것입니다.

Hadoop은 가시성이 증가/확대되는 순서로 다음 종류의 audience를 사용합니다.

Hadoop에는 Company-Private 분류가 없습니다. 이는 회사 내 다른 프로젝트가 사용하도록 만들어진 API를 위한 것인데, 오픈소스 프로젝트에는 적용되지 않기 때문입니다. 또한 일부 API는 @VisibleForTesting(com.google.common.annotations.VisibleForTesting)으로 주석 처리되어 있으며, 이들은 단위 테스트 전용으로 사용되어야 하고 "Private" API로 취급되어야 합니다.

Private

Private 인터페이스는 프로젝트(HDFS나 MapReduce 같은) 내부에서만 사용하기 위한 것입니다. 애플리케이션이나 다른 프로젝트가 사용해서는 안 됩니다. 프로젝트의 대부분 인터페이스는 Private입니다(project-private라고도 함). 외부 소비를 위해 의도적으로 노출하지 않는 한, 인터페이스는 Private으로 표시해야 합니다.

Limited-Private

Limited-Private 인터페이스는 지정된 프로젝트 또는 시스템 집합(보통 밀접하게 관련된 프로젝트)이 사용합니다. 다른 프로젝트나 시스템은 이 인터페이스를 사용해서는 안 됩니다. 인터페이스 변경은 지정된 프로젝트와 소통/협의됩니다. 예를 들어 Hadoop 프로젝트에서 일부 인터페이스는 LimitedPrivate{HDFS, MapReduce}인데, 이는 HDFS와 MapReduce 프로젝트에만 비공개라는 뜻입니다.

Public

Public 인터페이스는 어떤 애플리케이션이든 일반 사용을 위한 것입니다.

변경 호환성 (Change Compatibility)

API에 대한 변경은 크게 두 범주로 나뉩니다: 호환(compatible)과 비호환(incompatible)입니다. 호환 변경은 다음 기준을 충족하는 변경입니다.

  • 기존 기능이 제거되지 않고,
  • 기존 기능이 변경 전에 인터페이스를 사용하도록 만들어진 클라이언트가 사용하지 못하게 막는 방식으로 수정되지 않으며,
  • 변경 전에 인터페이스를 사용하도록 만들어진 클라이언트에 변경을 요구하는 기능이 추가되지 않습니다.

이 세 기준을 충족하지 못하는 변경은 비호환 변경입니다. 간단히 말해 호환 변경은 기존 클라이언트를 깨뜨리지 않습니다. 다음은 호환 변경의 예입니다.

  • Java 클래스에 메서드를 추가하는 것,
  • RESTful 웹 서비스에 선택적 파라미터를 추가하는 것,
  • XML 문서에 태그를 추가하는 것,
  • 인터페이스의 audience 주석을 더 넓게 만들기(예: Private → Public) 또는 변경 호환성 주석을 더 제한적으로 만들기(예: Evolving → Stable).

다음은 비호환 변경의 예입니다.

  • Java 클래스에서 메서드를 제거하는 것,
  • Java 인터페이스에 메서드를 추가하는 것,
  • RESTful 웹 서비스에 필수 파라미터를 추가하는 것,
  • JSON 문서에서 필드 이름을 바꾸는 것,
  • 인터페이스의 audience 주석을 덜 넓게 만들기(예: Public → Limited Private) 또는 변경 호환성 주석을 더 제한적으로 만들기(예: Evolving → Unstable).

안정성 (Stability)

Stability는 인터페이스가 얼마나 안정적인지, 그리고 언제 호환/비호환 변경이 허용되는지를 나타냅니다. Hadoop API에는 다음과 같은 안정성 수준이 있습니다.

Stable

Stable 인터페이스는 선호되는 통신 수단으로 노출됩니다. Stable 인터페이스는 메이저 릴리스 내에서 비호환적으로 변경되지 않을 것으로 예상되므로 안전한 개발 대상이 됩니다. Stable 인터페이스는 마이너 릴리스 사이에서 호환적으로 진화할 수 있습니다.

허용되는 비호환 변경: major (X.0.0) / 허용되는 호환 변경: maintenance (x.y.Z)

Evolving

Evolving 인터페이스는 보통 기능이 안정화되기 전에 사용자나 외부 코드가 기능을 활용할 수 있도록 노출됩니다. 인터페이스가 "결국" 안정화되어 Stable로 승격될 것이라는 기대는, 단지 인터페이스를 Evolving으로 표시하기 위한 요구 사항은 아닙니다.

Evolving 인터페이스에 대한 비호환 변경은 마이너 릴리스에서만 허용됩니다.

허용되는 비호환 변경: minor (x.Y.0) / 허용되는 호환 변경: maintenance (x.y.Z)

Unstable

Unstable 인터페이스는 호환성을 전혀 보장하지 않는 인터페이스입니다. Unstable 인터페이스가 반드시 불안정하다는 뜻은 아닙니다. Unstable 인터페이스는 보통 사용자나 외부 코드가 소비용이 아닌 인터페이스에 접근해야 하기 때문에 노출됩니다. 인터페이스가 노출되더라도 선호되는 접근 경로가 아니며 호환성이 보장되지 않음을 명확히 하기 위해 Unstable 인터페이스로 노출합니다.

인터페이스에 호환성 보장을 제공할 이유가 없다면, 노출되든 아니든 Unstable로 표시해야 합니다. Private 인터페이스도 대부분의 경우 Unstable이어야 합니다.

Unstable 인터페이스에 대한 비호환 변경은 언제든 허용됩니다.

허용되는 비호환 변경: maintenance (x.y.Z) / 허용되는 호환 변경: maintenance (x.y.Z)

Deprecated

Deprecated 인터페이스는 향후 제거될 가능성이 있으므로 사용해서는 안 됩니다. 그럼에도 Deprecated 인터페이스는 제거될 때까지 계속 동작합니다. Deprecated 인터페이스를 언제 제거할 수 있는지는 그것이 Stable, Evolving, Unstable 중 어느 것인지에 따라 달라집니다.

분류는 어떻게 기록되나요?

Hadoop API에 대한 분류는 어떻게 기록될까요?

각 인터페이스나 클래스는 org.apache.hadoop.classification 패키지의 주석(annotation)을 사용해 audience와 stability를 기록합니다.

maven 타깃 javadoc:javadoc으로 생성되는 javadoc은 공개 API만 나열합니다.

Java 클래스와 Java 인터페이스의 audience는 그것이 포함된 패키지의 audience로부터 유도할 수 있습니다. 따라서 각 Java 패키지의 audience를 public 또는 private(그리고 private audience 변형)으로 선언하는 것이 유용합니다.

CLI 같은 다른 인터페이스에 대한 분류는 어떻게 기록될까요?

  • 자세한 내용은 Hadoop Compatibility 페이지를 참고하세요.

FAQ

Java의 스코프(private, package private, public)만으로 충분하지 않은 이유는 무엇인가요?

  • Java의 스코핑은 그다지 완전하지 않습니다. 내부 다른 구성요소가 사용할 수 있도록 클래스를 public으로 만들어야 하는 경우가 많습니다. 또한 C++의 friend나 sub-package-private 같은 것도 없습니다.

Java public이라면 Private 인터페이스에 쉽게 접근할 수 있는데, 보호와 통제는 어디에 있나요?

  • 이 분류 체계의 목적은 절대적인 접근 제어를 제공하는 것이 아닙니다. 그 목적은 사용자와 개발자에게 소통하는 것입니다. libc의 private 구현 함수에 접근할 수는 있지만, 내부 구현 세부 사항을 바꾸면 애플리케이션이 깨지고 libc 제공자로부터 동정을 받기 어려울 것입니다. 비공개 인터페이스를 사용할 때는 그 위험이 이해되고 있다는 뜻입니다.

Private 인터페이스의 안정성을 선언하는 이유는 무엇인가요? Private 인터페이스는 항상 Unstable 아닌가요?

  • Private 인터페이스가 항상 Unstable인 것은 아닙니다. Stable인 경우 시스템의 내부 속성을 포착하여 이를 내부 사용자와 인터페이스 개발자에게 전달할 수 있습니다.
  • 예: HDFS에서 NN-DN 프로토콜은 Private이지만 Stable이며, 롤링 업그레이드(rolling upgrade) 구현에 도움이 됩니다. 안정성 주석은 이 인터페이스가 Private이어도 비호환적인 방식으로 변경되어서는 안 된다는 것을 전달합니다.
  • 예: HDFS에서 FSImage의 Stable 지정은 더 유연한 롤백을 제공합니다.

애플리케이션이 Stable이지만 Private 인터페이스를 사용하면 어떤 해가 있나요? Public Stable 인터페이스와 어떻게 다른가요?

  • Stable로 표시된 Private 인터페이스는 메이저 릴리스에서만 변경되는 것을 목표로 하지만, 해당 인터페이스의 제공자가 그 인터페이스의 내부 소비자도 바꾸겠다면 다른 때에도 깨질 수 있습니다. 또한 Public Stable 인터페이스는 (호환성을 깨뜨리는 것이 허용되더라도) 변경의 영향이 더 크기 때문에 메이저 릴리스에서도 깨질 가능성이 더 낮습니다. Private 인터페이스를 사용하면 (안정성과 관계없이) 비호환성의 위험을 감수하게 됩니다.

Limited-Private는 왜 필요한가요? 일부 프로젝트에 특혜를 주는 것 아닌가요? 공평하지 않습니다.

  • 대부분의 인터페이스는 Public 또는 Private이어야 합니다. 일반 사용을 명시적으로 의도하지 않는 한 인터페이스는 Private이어야 합니다.
  • Limited-Private는 일반 사용을 위한 것이 아닌 인터페이스용입니다. 특별한 훅이 필요한 관련 프로젝트에 노출됩니다. 이러한 분류는 인터페이스의 공급자와 소비자 모두에게 비용이 듭니다. 향후 인터페이스를 깨뜨릴 필요가 생기면 양측이 함께 작업해야 합니다. 예를 들어 공급자와 소비자는 각 프로젝트의 릴리스를 조정하기 위해 함께 작업해야 합니다. 이 계약을 가볍게 여겨서는 안 됩니다. 가능하면 Private을 사용하고, 정말 모든 애플리케이션을 위한 일반 사용용 인터페이스라면 Public을 사용하세요. 인터페이스를 Public으로 만드는 것은 큰 책임을 수반한다는 점을 항상 기억하세요. 때로는 Limited-Private가 딱 맞습니다.
  • Limited-Private 인터페이스의 좋은 예는 BlockLocations입니다. 이 인터페이스는 상당히 저수준 인터페이스로 MapReduce와 HBase에 노출됩니다. 나중에 변경될 가능성이 높으며, 그때는 MapReduce 개발 팀과 릴리스 노력을 조정해야 합니다. MapReduce와 HDFS는 오늘날 항상 함께 릴리스되지만, 그 정책은 나중에 바뀔 수 있습니다.
  • 프로젝트가 많이 나열된 Limited-Private 인터페이스가 있다면 그 인터페이스는 Public으로 만드는 것이 좋은 후보입니다.

모든 Hadoop에서 모든 Private 인터페이스를 Limited-Private로 취급해 봅시다. Hadoop 계열 프로젝트가 private 클래스에 접근할 수 있다면 어떤 해가 있나요?

  • 다른 프로젝트의 내부 구현 세부 사항에 의존하는 사례가 코드에서 많았습니다. 이런 문제를 정리하는 데 상당한 노력이 들었습니다. 모든 인터페이스를 모든 Hadoop에 대해 Limited-Private로 여는 것은 이런 결합(coupling) 문제를 다시 도입하는 문을 열게 됩니다.

모든 Public 인터페이스가 Stable인가요?

  • 초기 단계의 Public 인터페이스를 Evolving으로 표시할 수 있습니다. 이 경우 호환 변경을 하도록 노력하겠다고 약속하지만 마이너 릴리스에서 깨뜨려야 할 수도 있습니다.
  • Unstable인 Public 인터페이스의 한 예는 아직 개발 중인 표준 기구 기반 인터페이스의 구현을 제공할 때입니다. 예를 들어 많은 회사가 IETF가 프로토콜을 완전히 완성하지 않았음에도 시장 선점을 위해 새 NFS 프로토콜 구현을 제공했습니다. 표준 기구가 안정성을 통제하기 때문에 구현자는 최소한의 혼란을 일으키는 방식으로 인터페이스를 진화시킬 수 없습니다. 따라서 인터페이스를 Unstable로 표시하는 것이 적절합니다.

더 알아보기 (Learn more)