Hadoop インターフェース分類体系:対象者と安定性分類

動機

ここに示すインターフェース分類体系は、インターフェースの開発者とユーザーへのガイダンスを目的としています。この分類は、開発者がインターフェースの対象ユーザーと安定性を宣言する際のガイドラインとなります。

  • インターフェースのユーザーへのメリット:使用するインターフェースとその安定性を認識できます。

  • 開発者へのメリット:インターフェースの意図しない変更、ひいてはユーザーや他のコンポーネント、システムへの意図しない影響を防ぎます。これは、多くの開発者が関与し、プロジェクトの共有状態/履歴を持たない可能性のある大規模システムで特に役立ちます。

インターフェース分類

Hadoopは次のインターフェース分類を採用しています。この分類はOpenSolarisの分類体系、そしてある程度Yahoo!内部で使用されている分類体系を基にしています。インターフェースには、対象者と安定性の2つの主要な属性があります。

対象者

対象者は、インターフェースの潜在的な利用者を意味します。多くのインターフェースは実装内部/プライベートですが、アプリケーションやクライアントによる広範な利用を意図したパブリック/外部インターフェースもあります。例えば、POSIXでは、libcは外部またはパブリックインターフェースですが、カーネルの大部分は内部またはプライベートインターフェースです。また、一部のインターフェースは、他の特定のサブシステムを対象としています。

インターフェースの対象者を特定することで、インターフェースを破棄することの影響を定義するのに役立ちます。例えば、少数の特定のサブシステムのみを対象とするインターフェースの互換性を破棄しても問題ない場合があります。一方、数百万人のインターネットユーザーが依存しているプロトコルインターフェースを破棄することは、おそらく適切ではありません。

Hadoopは、可視性の広がり順に次の種類の対象者を使用します。

Hadoopには、企業内の他のプロジェクトで使用することを目的としたAPIを意味するCompany-Private分類はありません。これはオープンソースプロジェクトには適用されないためです。また、一部のAPIは`@VisibleForTesting` (com.google.common.annotations.VisibleForTestingから)として注釈されています。これらはユニットテストのみに使用することを目的としており、「プライベート」APIとして扱う必要があります。

プライベート

プライベートインターフェースは、プロジェクト内(HDFSやMapReduceなど)での内部使用を目的としており、アプリケーションや他のプロジェクトでは使用しないでください。プロジェクトのほとんどのインターフェースはプライベートです(プロジェクトプライベートとも呼ばれます)。インターフェースが意図的に外部利用のために公開されない限り、プライベートとしてマークする必要があります。

限定プライベート

限定プライベートインターフェースは、指定された一連のプロジェクトまたはシステム(通常は密接に関連するプロジェクト)によって使用されます。他のプロジェクトやシステムは、このインターフェースを使用しないでください。インターフェースへの変更は、指定されたプロジェクトと連携して行われます。例えば、Hadoopプロジェクトでは、一部のインターフェースはLimitedPrivate{HDFS, MapReduce}であり、HDFSとMapReduceプロジェクトにプライベートです。

パブリック

パブリックインターフェースは、任意のアプリケーションによる一般使用を目的としています。

変更互換性

APIへの変更は、互換性のある変更と互換性のない変更の2つの大きなカテゴリに分類されます。互換性のある変更とは、次の基準を満たす変更です。

  • 既存の機能は削除されません。
  • 変更前にインターフェースを使用するように構築されたクライアントによる使用を妨げる方法で、既存の機能が変更されません。
  • 変更前にインターフェースを使用するように構築されたクライアントに変更を必要とする機能は追加されません。

これらの3つの基準を満たさない変更は、互換性のない変更です。簡単に言えば、互換性のある変更は既存のクライアントを破壊しません。これらの例は互換性のある変更です。

  • Javaクラスにメソッドを追加する。
  • RESTful Webサービスにオプションのパラメータを追加する。
  • XMLドキュメントにタグを追加する。
  • インターフェースの対象者アノテーションをより広範にする(例:プライベートからパブリックへ)、または変更互換性アノテーションをより制限する(例:進化中から安定へ)。

これらの例は互換性のない変更です。

  • Javaクラスからメソッドを削除する。
  • Javaインターフェースにメソッドを追加する。
  • RESTful Webサービスに必須パラメータを追加する。
  • JSONドキュメントのフィールド名を変更する。
  • インターフェースの対象者アノテーションをより狭める(例:パブリックから限定プライベートへ)、または変更互換性アノテーションをより制限する(例:進化中から不安定へ)。

安定性

安定性は、インターフェースの安定性と、インターフェースへの互換性のある変更と互換性のない変更をいつ許可するかを示します。Hadoop APIには、次の安定性のレベルがあります。

安定

安定したインターフェースは、好ましい通信手段として公開されます。安定したインターフェースは、メジャーリリース内で互換性のない変更がないと予想され、安全な開発ターゲットとして機能します。安定したインターフェースは、マイナーリリース間で互換性のある進化を遂げることがあります。

許容される非互換な変更:メジャー (X.0.0) 許容される互換性のある変更:メンテナンス (x.y.Z)

進化中

進化中のインターフェースは、通常、ユーザーまたは外部コードが安定する前に機能を利用できるようにするために公開されます。ただし、インターフェースが「最終的に」安定し、安定版に昇格する必要があるという期待は、インターフェースを進化中としてラベル付けするための要件ではありません。

非互換な変更は、進化中のインターフェースに対してマイナーリリースでのみ許可されます。

許容される非互換な変更:マイナー (x.Y.0) 許容される互換性のある変更:メンテナンス (x.y.Z)

不安定

不安定なインターフェースとは、互換性の保証がされていないインターフェースです。不安定なインターフェースが必ずしも不安定であるとは限りません。不安定なインターフェースは、通常、ユーザーまたは外部コードが消費を意図していないインターフェースにアクセスする必要があるために公開されます。インターフェースは、インターフェースが公開されているにもかかわらず、好ましいアクセスパスではなく、互換性の保証がされていないことを明確に示すために、不安定なインターフェースとして公開されます。

インターフェースで互換性の保証を提供する理由がない限り、公開されているかどうかにかかわらず、不安定としてラベル付けする必要があります。プライベートインターフェースもほとんどの場合、不安定である必要があります。

不安定なインターフェースに対する非互換な変更は、いつでも許可されます。

許容される非互換な変更:メンテナンス (x.y.Z) 許容される互換性のある変更:メンテナンス (x.y.Z)

非推奨

非推奨のインターフェースは、将来削除される可能性があり、使用しないでください。それでも、非推奨のインターフェースは削除されるまで機能し続けます。非推奨のインターフェースを削除できる時期は、安定版、進化中、不安定のいずれであるかによって異なります。

分類はどのように記録されますか?

Hadoop APIの分類はどのように記録されますか?

  • 各インターフェースまたはクラスには、org.apache.hadoop.classificationパッケージのアノテーションを使用して、対象者と安定性が記録されます。

  • mavenターゲット`javadoc:javadoc`によって生成されるjavadocは、パブリックAPIのみをリストアップします。

  • JavaクラスとJavaインターフェースの対象者は、それらが含まれているパッケージの対象者から導き出すことができます。したがって、各Javaパッケージの対象者をパブリックまたはプライベート(プライベート対象のバリエーションを含む)として宣言することが役立ちます。

CLIなどの他のインターフェースでは、どのように分類が記録されますか?

よくある質問

  • なぜJavaのスコープ(private、package private、public)だけでは不十分なのですか?

    • Javaのスコープは完全ではありません。他の内部コンポーネントが使用するために、クラスをpublicにすることを強いられることがよくあります。また、C++のようなfriendsやsub-package-privateもありません。
  • しかし、JavaでpublicなPrivateインターフェースには簡単にアクセスできます。保護と制御はどこにあるのですか?

    • この分類スキームの目的は、絶対的なアクセス制御を提供することではありません。その目的は、ユーザーと開発者に伝えることです。libcではprivateな実装関数にアクセスできますが、内部実装の詳細を変更すると、アプリケーションが壊れ、libcを提供している担当者から同情されることはありません。非公開インターフェースを使用する場合、リスクは理解されています。
  • なぜPrivateインターフェースの安定性を宣言する必要があるのですか?Privateインターフェースは常に不安定ではありませんか?

    • Privateインターフェースが常に不安定とは限りません。安定している場合、それらはシステムの内部プロパティを捉え、それらのプロパティを内部ユーザーとインターフェースの開発者に伝えることができます。
      • 例:HDFSでは、NN-DNプロトコルはPrivateですがStableであり、ローリングアップグレードの実装に役立ちます。安定性の注釈は、このインターフェースが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として開くと、そのような結合の問題を再導入する可能性があります。
  • すべてのPublicインターフェースはStableですか?

    • 初期段階では、PublicインターフェースをEvolvingとしてマークできます。ここでは、互換性のある変更を行う努力をすることを約束しますが、マイナーリリースで壊れる必要がある可能性があります。
    • 不安定なPublicインターフェースの例としては、開発中の標準機関ベースのインターフェースの実装を提供する場合があります。たとえば、多くの企業は、市場にいち早く参入するために、IETFによって完全に完成されていない新しいNFSプロトコルの実装を提供しています。実装者は、安定性が標準機関によって制御されているため、最小限の混乱を引き起こす方法でインターフェースを進化させることはできません。したがって、インターフェースを不安定としてラベル付けすることが適切です。