Hadoop 介面分類法:受眾和穩定性分類

動機

這裡提供的介面分類法分類是為介面的開發人員和使用者提供指導。此分類法指導開發人員宣告介面的目標受眾或使用者,以及其穩定性。

  • 對介面使用者的優點:知道哪些介面可以使用或不可以使用,以及其穩定性。

  • 對開發人員的優點:防止介面的意外變更,因此不會意外影響使用者或其他元件或系統。這在有許多開發人員的大型系統中特別有用,這些開發人員可能不會都有專案的共用狀態/歷史記錄。

介面分類

Hadoop 採用下列介面分類,此分類衍生自 OpenSolaris 分類法,在某種程度上也來自 Yahoo 內部使用的分類法。介面有兩個主要屬性:受眾和穩定性。

受眾

受眾表示介面的潛在使用者。雖然許多介面是實作的內部/私人介面,但其他介面是公共/外部介面,供應用程式和/或客戶端廣泛使用。例如,在 posix 中,libc 是外部或公共介面,而 kernel 的大部分是內部或私人介面。此外,有些介面針對其他特定子系統。

找出介面的受眾有助於定義中斷介面的影響。例如,中斷受眾為少數特定子系統的介面相容性可能是可以接受的。另一方面,中斷數百萬網際網路使用者依賴的通訊協定介面可能是不可以接受的。

Hadoop 使用下列受眾類型,依可見度增加/擴大排序

Hadoop 沒有公司私人分類,這是針對公司內其他專案預計使用的 API,因為它不適用於開放原始碼專案。此外,某些 API 標註為 @VisibleForTesting (來自 com.google.common .annotations.VisibleForTesting) - 這些 API 嚴格用於單元測試,且應視為「私人」API。

私人

私人介面供專案內部使用 (例如 HDFS 或 MapReduce),不應由應用程式或其他專案使用。專案的大部分介面都是私人介面 (也稱為專案私人介面)。除非介面是故意公開供外部使用,否則應標記為私人介面。

受限私人

受限私人介面由特定專案或系統集使用 (通常是密切相關的專案)。其他專案或系統不應使用此介面。介面的變更會與特定專案溝通/協商。例如,在 Hadoop 專案中,有些介面是 LimitedPrivate{HDFS, MapReduce},表示它們是 HDFS 和 MapReduce 專案的私人介面。

公共

公共介面供任何應用程式一般使用。

變更相容性

對 API 的變更可分為兩大類別:相容和不相容。相容變更符合下列準則

  • 不移除任何現有功能
  • 不以妨礙客戶端使用在變更前建構來使用介面的方式修改任何現有功能,且
  • 不新增任何需要變更在變更前建構來使用介面的客戶端的功能。

任何不符合這三個準則的變更都是不相容變更。簡單來說,相容變更不會中斷現有客戶端。以下範例是相容變更

  • 新增方法至 Java 類別
  • 新增選用參數至 RESTful 網路服務
  • 新增標籤至 XML 文件
  • 將介面的受眾註解變得更廣泛(例如,從私人變為公開)或將變更相容性註解變得更具限制性(例如,從演進變為穩定)

以下範例是不相容變更

  • 從 Java 類別移除方法
  • 新增方法至 Java 介面
  • 新增必要參數至 RESTful 網路服務
  • 重新命名 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 範圍(私有、封裝私有和公有)不夠好?

    • Java 的範圍並不完整。通常被迫將類別設為公有,以便其他內部元件使用它。它也不像 C++ 一樣有朋友或子封裝私有。
  • 但如果 Java 是公有的,我可以輕鬆存取私有介面。保護和控制在哪裡?

    • 此分類方案的目的是不提供絕對的存取控制。其目的是與使用者和開發人員溝通。可以在 libc 中存取私有實作函式;但是,如果他們變更內部實作詳細資料,應用程式將會中斷,而且你將得不到提供 libc 的人多少同情。使用非公有介面時,風險是已知的。
  • 為何要費心宣告私有介面的穩定性?私有介面不總是會不穩定嗎?

    • 私有介面並不總是會不穩定。在它們穩定的情況下,它們會擷取系統的內部屬性,並可以將這些屬性傳達給其內部使用者和介面的開發人員。
      • 例如,在 HDFS 中,NN-DN 協定是私有但穩定的,而且可以協助實作滾動升級。穩定性註解傳達,即使此介面是私有的,也不應該以不相容的方式變更它。
      • 例如,在 HDFS 中,FSImage 的穩定性指定提供更彈性的回滾。
  • 應用程式使用穩定的私有介面有什麼害處?它與公有穩定介面有何不同?

    • 雖然標示為穩定的私有介面目標只在主要版本中變更,但如果該介面的提供者也願意變更該介面的內部使用者,它可能會在其他時間中斷。此外,公有穩定介面即使在主要版本中也不太可能中斷(即使允許中斷相容性),因為變更的影響較大。如果你使用私有介面(不論其穩定性),你會承擔不相容性的風險。
  • 為何要費心處理有限私有?這不是對某些專案給予特殊待遇嗎?這不公平。

    • 大多數介面都應該是公有或私有的。除非明確用於一般用途,否則介面應該是私有的。
    • Limited-Private 是針對非一般用途介面而設計。它們會公開給需要特殊掛勾的相關專案。此類分類對介面的供應商和消費者來說都是一筆成本。如果未來有需要中斷介面,兩者都必須合作;例如供應商和消費者必須合作,才能協調各自專案的版本發布。此合約不應輕忽看待,如果可能,請使用 Private;如果介面確實是所有應用程式的通用介面,請使用 Public。請務必記住,將介面設為 Public 會帶來重大的責任負擔。有時 Limited-Private 才是最適合的。
    • Limited-Private 介面的良好範例是 BlockLocations。此介面是相當低階的介面,會公開給 MapReduce 和 HBase。此介面很可能會在未來變更,屆時必須與 MapReduce 開發團隊協調版本發布工作。儘管 MapReduce 和 HDFS 目前總是同步發布,但此政策可能會在未來變更。
    • 如果您的 Limited-Private 介面列出了許多專案,則該介面很可能適合設為 Public。
  • 讓我們將所有 Private 介面都視為 Hadoop 的 Limited-Private。如果 Hadoop 家族中的專案可以存取私人類別,會造成什麼危害?

    • 程式碼中過去有許多情況,其中一個專案依賴於另一個專案的內部實作細節。我們投入大量心力來清理這些問題。將所有介面都開放為 Hadoop 的 Limited-Private,會讓此類耦合問題再度發生。
  • 難道所有 Public 介面都不是穩定的嗎?

    • 有人可能會在 Public 介面的早期將其標記為 Evolving。在此,有人承諾會努力進行相容性變更,但可能需要在次要版本中中斷介面。
    • 不穩定的 Public 介面範例之一,是提供仍處於開發階段的標準組織介面的實作。例如,許多公司為了搶先上市,提供了新 NFS 協定的實作,即使 IETF 尚未完全完成該協定。實作人員無法以造成最少中斷的方式來演進介面,因為穩定性是由標準組織控制的。因此,將介面標記為 Unstable 是適當的。