本文件记录了 Apache Hadoop 项目的兼容性目标。列举了影响 Hadoop 开发人员、下游项目和最终用户的 Hadoop 版本之间的不同类型的兼容性。对于每种类型的兼容性,本文件将
为了与以前的版本保持兼容性,所有 Hadoop 接口都根据目标受众和稳定性进行分类。有关分类的详细信息,请参阅Hadoop 接口分类法。
本文件供 Hadoop 开发人员社区使用。本文件描述了 Hadoop 项目更改的观察视角。为了让最终用户和第三方开发人员对跨版本兼容性充满信心,开发人员社区必须确保开发工作遵守这些策略。项目提交者有责任验证所有更改,以维护兼容性或明确标记为不兼容。
在组件中,Hadoop 开发人员可以自由使用私有和受限私有 API,但当使用不同模块的组件时,Hadoop 开发人员应遵循与第三方开发人员相同的准则:不要使用私有或受限私有(除非明确允许)接口,而应优先使用稳定接口,而不是不断发展的或不稳定的接口(如果可能)。如果不可能,首选的解决方案是扩展 API 的受众,而不是引入或延续这些兼容性准则的例外。在 Maven 模块中工作时,Hadoop 开发人员应尽可能遵守使用位于其他 Maven 模块中的组件的相同程度的约束。
最重要的是,Hadoop 开发人员必须注意其更改的影响。稳定接口不得在主要版本之间更改。不断发展的接口不得在次要版本之间更改。新类和组件必须针对受众和稳定性进行适当标记。有关何时使用各种标签的详细信息,请参阅Hadoop 接口分类法。一般来说,所有新接口和 API 都应具有最有限的标签(例如私有不稳定),这不会抑制接口或 API 的意图。
本文档根据各种兼容性问题分为多个部分。每个部分中的引言文本都会说明该部分中兼容性的含义、其重要性以及支持兼容性的意图。随后的“政策”部分会具体阐述管理政策。
关键词“必须”、“不得”、“必需”、“应当”、“不应当”、“应该”、“不应当”、“建议”、“可以”和“可选”的解释见RFC 2119。
Java API 提供 @Deprecated 注解,用于标记要删除的 API 元素。该注解的标准含义是,API 元素不应使用,并且可能会在以后的版本中删除。
在所有情况下,从 API 中删除元素都是不兼容的更改。元素的稳定性应决定何时允许进行此类更改。稳定元素必须在删除之前标记为弃用,并且不得在次要版本或维护版本中删除。演进元素必须在删除之前标记为弃用,并且不得在维护版本中删除。不稳定元素可以随时删除。如果可能,不稳定元素应在删除之前至少标记为弃用一个版本。例如,如果某个方法在 Hadoop 2.8 中标记为弃用,则在 Hadoop 4.0 之前无法将其删除。
稳定 API 元素在标记为已弃用(通过 @Deprecated 注释或其他适当文档)直至一个完整的重大版本后,才不得删除。如果一个 API 元素作为已弃用(表示它是一种临时措施,打算删除)引入,则该 API 元素可以在下一个重大版本中删除。在修改 稳定 API 时,开发人员应优先引入一个新方法或端点,并弃用现有方法或端点,而不是对方法或端点进行不兼容的更改。
开发人员应使用 @InterfaceAudience 和 @InterfaceStability 注释为所有 Hadoop 接口和类添加注释,以描述目标受众和稳定性。
注释可以在包、类或方法级别应用。如果一个方法没有隐私或稳定性注释,它应从其所属的类继承其目标受众或稳定性级别。如果一个类没有隐私或稳定性注释,它应从其所属的包继承其目标受众或稳定性级别。如果一个包没有隐私或稳定性注释,则应分别假定为 私有 和 不稳定。
如果一个元素的受众或稳定性注释与其父元素的相应注释(无论是显式的还是继承的)冲突,则该元素的受众或稳定性(分别)应由更严格的注释确定。例如,如果一个 私有 方法包含在一个 公共 类中,则该方法应被视为 私有。如果一个 公共 方法包含在一个 私有 类中,则该方法应被视为 私有。
兼容性策略应由相关包、类或成员变量或方法注释确定。
注意:从 proto 文件生成的 API 必须兼容滚动升级。有关更多详细信息,请参阅有关线协议兼容性的部分。因此,API 和线协议的兼容性策略必须齐头并进。
Apache Hadoop 努力确保 API 的行为在各个版本中保持一致,尽管为了正确性而进行的更改可能会导致行为发生变化。API 行为应由 JavaDoc API 文档(如果存在且完整)指定。当 JavaDoc API 文档不可用时,行为应由相关单元测试预期的行为指定。在没有 JavaDoc API 文档或单元测试覆盖的情况下,预期的行为被认为是显而易见的,并且应假定为接口命名所暗示的最低功能。社区正在对一些 API 进行更严格的规范,并增强测试套件以验证是否符合规范,从而有效地为易于测试的行为子集创建正式规范。
任何 API 的行为都可以根据 API 的稳定性更改为修复不正确的行为,并且此类更改应伴随更新现有文档和测试和/或添加新文档或测试。
Apache Hadoop 修订版应保留二进制兼容性,以便最终用户应用程序在没有任何修改的情况下继续工作。同一主要修订版内的次要 Apache Hadoop 修订版必须保留兼容性,以便现有的 MapReduce 应用程序(例如最终用户应用程序和 Apache Pig、Apache Hive 等项目)、现有的 YARN 应用程序(例如最终用户应用程序和 Apache Spark、Apache Tez 等项目)以及直接访问 HDFS 的应用程序(例如最终用户应用程序和 Apache HBase、Apache Flume 等项目)在与原始构建目标相同的任何 Apache Hadoop 集群中使用时无需修改且无需重新编译即可工作。
特别是对于 MapReduce 应用程序,即使用 org.apache.hadoop.mapred 和/或 org.apache.hadoop.mapreduce API 的应用程序,开发人员社区应支持主要版本之间的二进制兼容性。MapReduce API 应在主要版本之间兼容地支持。有关更多详细信息,请参阅 hadoop-1.x 和 hadoop-2.x 之间 MapReduce 应用程序的兼容性。
某些应用程序可能会受到磁盘布局更改或其他内部更改的影响。有关如何处理与非 API 接口不兼容的更改的策略,请参阅以下部分。
Hadoop 包含多个本机组件,包括压缩、容器执行器二进制文件和各种本机集成。这些本机组件为 Hadoop 引入了一组本机依赖项,包括在编译时和运行时,例如 cmake、gcc、zlib 等。这组本机依赖项是 Hadoop ABI 的一部分。
Hadoop 在编译时和/或运行时依赖的本机组件的最低必需版本应被视为 Evolving。在主要版本内的次要版本之间,最低必需版本不应增加,尽管可能会因安全问题、许可问题或其他原因而进行更新。当 Hadoop 所依赖的本机组件必须在主要版本内的次要版本之间进行更新时,如果可能,这些更改应仅更改组件的次要版本,而不更改主要版本。
线兼容性涉及 Hadoop 进程之间“通过网络”传输的数据。Hadoop 对大多数 RPC 通信使用 Protocol Buffers。保持兼容性需要禁止修改,如下所述。还应考虑非 RPC 通信,例如使用 HTTP 传输 HDFS 映像作为快照的一部分或传输 MapReduce map 任务输出。通信可归类如下
Apache Hadoop 的组件可能具有包含其自身协议的依赖项,例如 Zookeeper、S3、Kerberos 等。这些协议依赖项应视为内部协议,并受同一策略管辖。
除了协议本身的兼容性之外,维护跨版本通信还需要支持的传输也保持稳定。传输更改最可能来自安全传输,例如 SSL。将服务从 SSLv2 升级到 SSLv3 可能会破坏现有的 SSLv2 客户端。任何传输的最低受支持主版本号在主版本内的次要版本之间不应增加,尽管由于安全问题、许可问题或其他原因可能会发生更新。当必须在主版本内的次要版本之间更新传输时,如果可能,更改应仅更改组件的次要版本,而不更改主版本。
服务端口被视为传输机制的一部分。必须保持默认服务端口号一致,以防止破坏客户端。
Hadoop 线协议在 .proto(ProtocolBuffers)文件中定义。客户端-服务器和服务器-服务器协议应根据其 .proto 文件中注明的受众和稳定性分类进行分类。在没有分类的情况下,协议应被假定为 私有 和 稳定。
对 .proto 文件的以下更改应被视为兼容
对 .proto 文件的以下更改应被视为不兼容
对 .proto 文件的以下更改应被视为不兼容
未通过 .proto 文件定义的 Hadoop 线路协议应被视为私有和稳定。
除了作为稳定所施加的限制外,Hadoop 的线路协议还必须根据以下内容在主要版本内的次要版本之间向前兼容
新传输机制只能在次要或主要版本更改时引入。现有的传输机制必须在主要版本内的次要版本中继续得到支持。默认服务端口号应被视为稳定。
REST API 兼容性适用于公开的 REST 端点 (URL) 和响应数据格式。Hadoop REST API 专门用于跨版本(甚至是主要版本)稳定使用客户端。就本文档而言,公开的 PEST API 是在公开文档中记录的 API。以下是公开的 REST API 的非详尽列表
每个 API 都有一个特定于 API 的版本号。任何不兼容的更改都必须增加 API 版本号。
公开的 Hadoop REST API 应被视为 公共 和 不断演进。关于 API 版本号,公开的 Hadoop REST API 应被视为 公共 和 稳定,即不允许在 API 版本号内进行不兼容的更改。REST API 版本必须在可以删除之前标记为已弃用,以进行一次完整的重大版本发布。
Hadoop 守护程序和 CLI 通过 Log4j 生成日志输出,旨在帮助管理员和开发人员理解和解决集群行为问题。日志消息旨在供人类使用,但也支持自动化用例。
多个组件具有审计日志记录系统,以机器可读格式记录系统信息。对该数据格式进行不兼容的更改可能会破坏现有的自动化实用程序。对于审计日志,不兼容的更改是任何更改格式的更改,使得现有的解析器无法再解析日志。
虽然指标 API 兼容性受 Java API 兼容性支配,但 Hadoop 公开的指标数据格式必须保持兼容,以便数据使用者(例如自动化任务)使用。
用户和系统级别数据(包括元数据)存储在各种格式的文件中。对存储数据/元数据的元数据或文件格式的更改可能导致版本之间不兼容。以下针对每类文件格式进行说明。
对最终用户用于存储其数据的格式进行更改可能会阻止他们在以后的版本中访问数据,因此兼容性非常重要。这些格式的示例包括 har、war、SequenceFileFormat 等。
用户级文件格式应被视为公开且稳定。用户级文件格式更改应在主要版本之间保持向前兼容,并且必须在主要版本内保持向前兼容。开发人员社区应优先创建新的派生文件格式,而不是对现有文件格式进行不兼容的更改。此类新文件格式必须创建为可选择加入的格式,这意味着用户必须能够继续使用现有兼容格式,直到他们明确选择使用新文件格式为止。
Hadoop 内部数据也可以存储在文件或其他数据存储中。更改这些数据存储的架构可能导致不兼容。
MapReduce 使用 I-File 等格式存储特定于 MapReduce 的数据。
所有 MapReduce 内部文件格式(例如 I-File 格式或作业历史记录服务器的 jhist 文件格式)应被视为私有且稳定。
HDFS 以私有文件格式持久化元数据(映像和编辑日志)。对格式或元数据的任何不兼容更改都会阻止后续版本读取较旧的元数据。不兼容的更改必须包括一个进程,通过该进程可以升级现有元数据。
根据更改的不兼容程度,可能会出现以下潜在情况
HDFS 数据节点将数据存储在私有目录结构中。对目录结构的不兼容更改可能阻止旧版本访问存储的数据。不兼容更改必须包括一个可用于升级现有数据目录的过程。
HDFS 元数据格式应被视为 私有 和 不断演进。不兼容更改必须包括一个可用于升级现有元数据的过程。升级过程应允许需要一次以上的升级。升级过程必须允许群集元数据回滚到旧版本及其旧磁盘格式。回滚必须恢复原始数据,但不要求恢复更新的数据。对格式的任何不兼容更改都必须导致模式的主要版本号增加。
数据节点目录格式应被视为 私有 和 不断演进。不兼容更改必须包括一个可用于升级现有数据目录的过程。升级过程应允许需要一次以上的升级。升级过程必须允许数据目录回滚到旧布局。
S3Guard 元存储用于在 DynamoDB 表中存储元数据;因此,它必须维持一个兼容性策略。现在 S3Guard 已被移除,这些表不再需要。
配置为使用除“null”存储以外的 S3A 元数据存储的应用程序将失败。
YARN 资源管理器将有关群集状态的信息存储在外部状态存储中,以便在故障转移和恢复中使用。如果用于状态存储数据模式保持不兼容,则资源管理器将无法恢复其状态,并且将无法启动。状态存储数据模式包括指示兼容性的版本号。
YARN 资源管理器状态存储数据模式应被视为 私有 和 不断演进。对模式的任何不兼容更改都必须导致模式的主要版本号增加。对模式的任何兼容更改都必须导致次要版本号增加。
YARN 节点管理器将有关节点状态的信息存储在外部状态存储中,以便在恢复中使用。如果用于状态存储数据模式保持不兼容,则节点管理器将无法恢复其状态,并且将无法启动。状态存储数据模式包括指示兼容性的版本号。
YARN 节点管理器状态存储数据架构应被视为 私有 且 不断演进。对架构的任何不兼容更改都必须导致架构的主要版本号增加。对架构的任何兼容更改都必须导致次要版本号增加。
YARN 资源管理器联合会服务将有关联合集群、正在运行的应用程序和路由策略的信息存储在外部状态存储中,以用于复制和恢复。如果用于状态存储数据架构不保持兼容,则联合会服务将无法初始化。状态存储数据架构包括指示兼容性的版本号。
YARN 联合会服务状态存储数据架构应被视为 私有 且 不断演进。对架构的任何不兼容更改都必须导致架构的主要版本号增加。对架构的任何兼容更改都必须导致次要版本号增加。
Hadoop 命令行程序可以直接通过系统 shell 或通过 shell 脚本使用。CLI 包括面向用户的命令(如 hdfs 命令或 yarn 命令)和面向管理员的命令(如用于启动和停止守护进程的脚本)。更改命令的路径、删除或重命名命令行选项、参数的顺序或命令返回码和输出会破坏兼容性并对用户产生不利影响。
除非将所有 Hadoop CLI 路径、用法和输出记录为实验性质且可能会更改,否则应将其视为 公共 且 稳定。
请注意,CLI 输出应被视为不同于 Hadoop CLI 生成的日志输出。后者应受日志输出策略的约束。另请注意,对于 CLI 输出,所有更改都应被视为不兼容更改。
Web UI,尤其是网页的内容和布局,更改可能会干扰尝试从网页中筛选信息。然而,Hadoop Web UI 页面不适合被筛选,例如用于自动化目的。用户应使用 REST API 以编程方式访问集群信息。
用户依赖 Hadoop 集群的行为在各个版本中保持一致。导致集群行为意外不同的更改会带来挫折感和漫长的采用周期。不应添加任何更改现有集群行为的新配置,假设集群的配置文件保持不变。对于定义的任何新设置,应注意确保新设置不会更改现有集群的行为。
在同一小版本内的维护版本之间,对现有功能的更改不得更改默认行为或现有配置设置的含义,无论更改是源于系统或逻辑更改还是源于内部或外部默认配置值。
在同一大版本内的次要版本之间,对现有功能的更改不应更改默认行为或现有配置设置的含义,尽管更改(例如修复正确性或安全问题)可能需要不兼容的行为更改。如果可能,此类行为更改应默认关闭。
用户使用 Hadoop 定义的属性来配置和向 Hadoop 提供提示,并使用自定义属性向作业传递信息。建议用户避免使用与 Hadoop 定义的属性命名空间冲突的自定义配置属性名称,并且应避免使用 Hadoop 使用的任何前缀,例如 hadoop、io、ipc、fs、net、file、ftp、kfs、ha、file、dfs、mapred、mapreduce 和 yarn。
除了属性文件之外,Hadoop 还使用其他配置文件来设置系统行为,例如公平调度程序配置文件或资源配置文件。
Hadoop 定义的属性(名称和含义)应被视为 公共 和 稳定。Hadoop 定义的属性所隐含的单位不得更改,即使在主要版本之间也是如此。Hadoop 定义的属性的默认值应被视为 公共 和 演进。
不受上述关于 Hadoop 定义的属性的规则约束的 Hadoop 配置文件应被视为 公共 和 稳定。不兼容更改的定义取决于特定的配置文件格式,但一般规则是,兼容更改将允许在更改之前有效的配置文件在更改之后仍然有效。
Hadoop 守护程序和 CLI 生成的日志输出受一组配置文件的控制。这些文件控制 Hadoop 各个组件将输出的日志消息的最低级别,以及这些消息的存储位置和方式。
源代码、制品(源代码和测试)、用户日志、配置文件、输出和作业历史记录都存储在本地文件系统或 HDFS 上的磁盘上。更改这些用户可访问文件的目录结构可能会破坏兼容性,即使在通过符号链接保留原始路径的情况下也是如此(例如,当通过配置为不遵循符号链接的 servlet 访问路径时)。
源代码和构建制品的布局应被视为 私有 和 不稳定。在主要版本中,开发人员社区应保留整体目录结构,尽管可以添加、移动或删除各个文件,而无需警告。
Hadoop 提供了若干客户端工件,应用程序使用这些工件与系统交互。这些工件通常依赖于自己的公共库。在这些依赖项公开给最终用户应用程序或下游使用者(即未混淆)的情况下,对这些依赖项的更改会造成破坏。强烈建议开发人员使用混淆等技术避免向客户端公开依赖项。
关于依赖项,添加依赖项是不兼容的更改,而删除依赖项是兼容的更改。
针对 Hadoop 构建的一些用户应用程序可能会将所有 Hadoop JAR 文件(包括 Hadoop 的库依赖项)添加到应用程序的类路径中。添加新依赖项或更新现有依赖项的版本可能会干扰应用程序类路径中的依赖项,从而影响其正常运行。因此,不建议用户采用此做法。
Hadoop 客户端工件公开的依赖项集应被视为公共且稳定。任何未公开给客户端的依赖项(因为它们被混淆或仅存在于非客户端工件中)应被视为私有且不稳定。
用户和相关项目通常利用 Hadoop 导出的环境变量(例如 HADOOP_CONF_DIR)。因此,删除或重命名环境变量可能会影响最终用户应用程序。
Hadoop 使用的环境变量和通过 YARN 向应用程序公开的环境变量应被视为公共且不断演进。开发人员社区应将更改限制在主要版本中。
Hadoop 使用 Maven 进行项目管理。对生成工件内容的更改可能会影响现有用户应用程序。
Hadoop 测试工件的内容应被视为私有且不稳定。测试工件包括从测试源代码生成的所有 JAR 文件和所有文件名中包含“tests”的 JAR 文件。
Hadoop 客户端工件应被视为 公共 和 稳定。客户端工件如下
为了跟上硬件、操作系统、JVM 和其他软件的最新进展,新的 Hadoop 版本可能包括需要比以前 Hadoop 版本更新的硬件、操作系统版本或 JVM 版本的功能。对于特定环境,升级 Hadoop 可能需要升级其他依赖软件组件。
以下是与该主题相关的一些 JIRA 和页面