Hadoop兼容性
大数据
Hadoop
原文:http://hadoop.apache.org/docs/r2.6.4/hadoop-project-dist/hadoop-common/Compatibility.html
兼容性类型
Java API
Hadoop的接口和类都有对应的标注,注解说明了为了维持兼容性而与之前版本的受众和稳定性方面的变化。参见Hadoop接口分类。
- 接口受众: 获取有意向的受众,可能的值包括Public(对应终端用户和附加的项目),LimitedPrivate(对应Hadoop组件和紧密相关的项目比如YARN,MapReduce,HBase等),Private(对应内部组件使用)。
- 接口稳定性: 描述哪种类型的接口变动是允许的。可能的值包括:Stable, Evolving, Unstable, 和 Deprecated。
用例
Public-Stable的API兼容性,对于端用户和下游系统不做修改持续运行是非常必要的。
LimitedPrivate-Stable的API兼容性,对于允许通过镜像发布版升级的单体组件来说是必须的。
Private-Stable的API对于滚动升级是必须的。
策略
- Public-Stable的APIs在一个新的主发布版本中被移除,那么针对老的,就必须要被标记deprecated。
- LimitedPrivate-Stable的APIs可以在多个主发布版本中变更,但是在一个主发布版本中不允许。
- Private-Stable的APIs可以在多个主发布版本中变更,但是在一个主发布版本中不允许。
- 没有标注的类隐式表现为“Private”。类成员不用标注继承所在类的注解。
- 注意:通过proto文件生成的API需要兼容滚动升级。更多细节参考wire-compatibility。API和通信的兼容性策略需要协同来解决。
语义兼容性
Apache Hadoop 努力保证API的跨版本一致性,尽管对于正确性的修正可能导致行为的不一致。Tests和javadoc声明了API的行为。社区也在更严格的推进对一些API的声明以及增强测试用例来校验API是否满足声明要求,有效地为一些可以容易得被测试的API行为创建一个正规的声明。
策略
API的行为发生不正确的情况下可以被修正,这样的修正需要更新已存在的bug测试或者在之前不存在时添加新的测试。
通信兼容性
通信兼容性关注的是数据在Hadoop进程之间被传输的问题。Hadoop对于大多数的RPC通信使用Protocal Buffers。保持兼容性需要禁止修改如下所述。非RPC通信也需要被考虑,比如使用HTTP来传输一个HDFS镜像用来快照,或者传输MapTask的输出。潜在的通信分类如下:
- Client-Server: Hadoop客户端和服务端之间的通信(比如HDFS客户端连接NameNode,YARN客户端连接ResourceManager)。
- Client-Server (Admin): 为客户端服务端通信协议区分是否是管理员命令是有意义的,因为这些协议(比如HAAdmin协议)只影响管理员而端用户可能根本不需要感知变化。
- Server-Server: 服务端之间的通信(比如DataNode和NameNode之间,NodeManager和ResourceManager之间)。
用例
- Client-Server 兼容性允许用户在服务端更新为新版本后继续使用老客户端。比如,一个Hadoop 2.1.0的客户端与Hadoop 2.3.0的集群通信。
- Client-Server 兼容性允许用户在升级服务端之前升级客户端。比如一个Hadoop 2.4.0的客户端与Hadoop 2.3.0的服务端通信。这个允许客户端侧的bugfix部署领先于完整的集群升级。注意此情况下新的集群特性允许新的客户端或者shell命令调用,老的无效。YARN应用程序如果试图使用一个还没有在集部署的新的API(包括新的数据结构中的字段),会导致一个连接异常。
- Client-Server 兼容性同时允许升级个体组件而不需要升级其他。比如,升级HDFS从2.1.0到2.2.0而不用升级MapReduce。
- Server-Server 兼容性允许集群内部的混合版本,这样集群升级不需要停机,可以做到滚动。
策略
- Client-Server 和 Server-Server 的兼容性在一个主发布版本内保持。
- 兼容性只能在主发行版本被打破,但打破主发行版本的兼容性有严重的后果,这种兼容性的破坏应在Hadoop社区进行讨论。
- Hadoop协议用.proto文件定义。Client-Server协议和服务端协议被标记为稳定的。当一个.proto文件被标记为稳定的,那就意味着新的变更要在下面描述的兼容性范围内做到:
- 下面对于兼容性的变更在任意时刻都是允许的:
- 添加一个可选的field,这个field相关的代码有和老版本miss的field代码通信的需要。
- 为服务添加一个新的 rpc/method。
- 为一个消息新家一个可选的请求。
- 重命名一个field。
- 重命名一个.proto文件。
- 改变.proto的标注,这种改变会影响代码生成(比如改变java package的名字)。
- 下面的变更是不保证兼容的,但是在一个主发行版本里可以考虑支持:
- 改变 rpc/method的名字
- 改变 rpc/method的参数类型或者返回值类型
- 删除一个 rpc/method
- 修改一个service的名字
- 修改一个消息的名字
- 通过不兼容的方式(比如递归定义)来修改一个field的类型
- 修改一个field从可选optional变为必须required
- 添加或者删除一个必须的field
- 删除一个可选的field,而这个field的默认是允许删除的
- 下面的变更是不保证兼容的,换句话说是被禁止的:
- 改变一个field的id
- 重新使用一个之前被删掉的老的field。
- 修改和重用一个field的数值也是不建议的。
端用户程序使用的Java Binary的兼容性,比如Apache Hadoop ABI
在Hadoop版本升级过程,端用户合理的期望他们的应用程序不需要任何修改可以持续运行。这是通过支持API兼容性、语义兼容性和通信兼容性来实现的。
然而,Hadoop非常复杂的分布式系统,它提供了对广泛的用例场景的支持。特别的,Hadoop MapReduce是一套使用广泛的API;在此意义上,用户可以假设他们的MapReduce任务运行、他们的任务的环境变量像在本地磁盘上布局一样。在此情况下,这就很难来完整地声明并支持绝对的兼容性。
用例
- MapReduce程序,包含端用户程序和项目打包的jar。比如Pig,HiveCascading等。在指定一个升级后的Hadoop集群主发行版本上,应该支持任务运行而不用做修改。
- YARN程序,包含端用户程序和项目打包的jar。比如Apache Tez等。在指定一个升级后的Hadoop集群主发行版本上,应该支持任务运行而不用做修改。
- HDFS读写数据的程序,包含端用户的程序和框架的jar。比如Apache Flume。在指定一个升级后的Hadoop集群主发行版本上,应该支持任务运行而不用做修改。
策略
- MapReduce, YARN & HDFS程序和框架应该可以在一个主发行版本内不做更改就能运行。比如支持Hadoop ABI。
- 一小部分的程序可以被磁盘布局的变动影响。开发者社区在极力最小化这些变动,尽量不在小版本中做这些变动。在某些恶劣的场景,我们考虑恢复这些破坏性的变动,必要时使这些违规的变动失效。
- 对于MapReduce程序,开发者社区会尽最大努力支持主版本之间的binary的兼容性。比如程序使用org.apahce.hadoop.mapred。
- hadoop-1.x和2.x之间的API支持兼容。参考Hadoop 1.x和2.x之间的兼容性。
REST APIs
REST API的兼容性对应了请求和响应。Hadoop REST APIs被声明在读个主版本间兼容。以下是暴露出来的REST APIs:
- WebHDFS - Stable
- ResourceManager
- NodeManager
- MR Application Master
- History Server
策略
被标注为stable的API支持至少一个主版本间的兼容性,也可能在新的版本中的REST API被deprecated。
Metrics/JMX
Metric API的兼容性由Java API的兼容性决定。实际由Hadoop暴露的metric需要和用户的兼容以便用户可以自动(通过脚本)使用。添加额外的metric也是兼容的。修改和删除已有的Metric会破坏兼容性。类似的,改变JMX MBean对象的名字也会破坏兼容性。
策略
Metrics要保证主版本内的兼容性。
文件格式&元数据
用户和系统层面的数据(包含元数据)都存储在不同格式的文件里。对于元数据或者存储数据和元数据的文件格式的变动会导致不同版本间的不兼容。
用户级别的文件格式
对于端用户存储数据文件格式的变更可以防止访问更新发布版本中的数据,因此对于保持这些文件格式兼容非常重要。可以添加一种新的格式来改善已有的文件格式。这类文件格式的例子包括har, war, SequenceFileFormat等。
Policy
- Non-forward-compatible用户文件格式变动被限制在主发行版本中。当用户文件的格式变动了,新的发行版本被期望可以读已有的格式,但是写数据到该格式可能不兼容。同时社区也希望可以创建一种新的格式——程序必须遵守,以此来代替导致不兼容的格式变动。
系统内部文件格式
Hadoop内部数据也被存储在文件里并且改变这些文件的格式会导致不兼容。当然这样的变动不像用户文件格式变动那么灾难性,但是对于兼容性被破坏的策略也是很重要的。
MapReduce
MapReduce使用类似I-File格式的文件来存储MapReduce数据。
策略
MapReduce内部格式类似IFile在一个主发行版本内保持兼容性。对于此格式的改变会导致在运行的作业失败,因此我们应该保证版本更新的客户端可以以老版本服务端支持的兼容行为来获取shuffle数据。
HDFS 元数据
HDFS将元数据(镜像和edit日志)持久化为特定格式的文件。对于文件格式或者元数据做不兼容的变更会防止后续的发行版本读取老版本的元数据。这样的不兼容的变更可能需要一个HDFS的升级来转换元数据以达到元数据可访问的目的。而一些变化可能需要更多的“升级”。
依赖于不兼容性变化的程度,包含以下潜在的场景:
- Automatic: 镜像自动升级,不需要一个显式的升级。
- Direct: 镜像可升级,但是可能需要一个显式的版本升级。
- Indirect: 镜像可升级,但是可能需要先升级到一个中间版本。
- Not upgradeable: 镜像不能升级。
策略
- 一个发行版本的升级必须允许集群回滚到老版本和老的磁盘文件格式。回滚需要能恢复原始数据,但是不要求一定可以恢复更新后的数据。
- HDFS元数据的变化必须是可升级的——通过任何升级途径——自动、直接和间接。
- 基于升级种类的更细节的策略还在设计中。
命令行界面(CLI)
Hadoop命令行程序可以被系统shell直接使用也可以通过脚本使用。改变一个命令的路径,删除或者重命名命令行选项、参数的顺序或者命令返回的code和输出output都会破坏兼容性并影响用户。
策略
CLI命令在主版本后续升级不再支持或者兼容性发生变动时要被标记为deprecated。
Web UI
Web UI, 页面布局和内容的变化会潜在影响试图抓取页面内容的动作。
策略
网站页面不建议被抓取,因此任何时刻做不兼容的变动都是可以接受的。用户应该通过REST API来获取信息而不是通过抓页面。
Hadoop配置文件
用户会使用Hadoop提供的属性来配置Hadoop集群,也会自定义一些属性文件来传递信息给作业。因此配置文件的兼容性从两方面来考虑:
- 修改key名字,值的单位,以及Hadoop定义的默认值。
- 自定义的配置属性的key应该与Hadoop定义的名字空间下的key不冲突。用户应该避免使用Hadoop使用的一般前缀:hadoop, io, ipc, fs, net, file, ftp, s3, kfs, ha, file, dfs, mapred, mapreduce, yarn。
策略
- Hadoop定义的属性在主发行版本中移除前一定会被先标记为deprecated。修改已有属性的单位是不允许的。
- Hadoop定义的属性的默认值可以跨主/次版本修改,但是在次版本里的小本之间要保持一致。
- 当前没有明确的策略限制对于属性前缀的添加和移除,也没有明确的前缀列表是禁止自定义配置属性使用的。然而像之前提到的,用户应该避免使用Hadoop使用的一般前缀:hadoop, io, ipc, fs, net, file, ftp, s3, kfs, ha, file, dfs, mapred, mapreduce, yarn。
目录结构
源代码,artifacts(源和测试),用户日志,配置文件,输出和作业历史都是存储到磁盘上的,或者在HDFS上或者在本地文件系统。改变这些用户可访问的文件的目录结构会破坏兼容性,极端情况下某些原始路径是通过符号连接来创建的(有时候一个路径如果被一个servlet访问,那这个servlet其实是不允许follow符号连接的)。
Policy
- 源代码和构建artifacts的布局可以在任意时刻修改,跨主发行版本也可以。在一个主版本内,可以尝试(单不保证)保留目录结构;然而个体的文件是可以被添加、移动和删除的。最好的保持代码同步状态的方式是将其提交到Apache的源码树。
- 配置文件,用户日志和作业历史的目录结构会在一个主版本内或者跨次版本保留。
Java类路径
基于Hadoop构建的用户程序需要添加所有的Hadoop jar到应用程序类路径下(包括Hadoop本身依赖的库)。添加新的依赖或者改变已有依赖的版本可能会影响应用程序的类路径。
策略
当前没有策略关于Hadoop的依赖可以被改变。
环境变量
用户以及相关的项目经常使用被导出的环境变量(比如HADOOP_CONF_DIR),因此移除或者重命名环境变量会导致不兼容。
策略
当前没有策略关于环境变量可以被改变。开发者应该限制在Hadoop主发行版本中修改。
构建artifacts
Hadoop使用maven做项目管理,对于artifacts的变更会影响已有的用户工作流。
策略
- Test artifacts: 测试相关的jar呗严格限制到在内部使用,不建议在Hadoop外部使用,类似于标注了@Private, @Unstable的API。
- Built artifacts: hadoop客户端artifact (maven groupId:artifactId) 在一个主发行版本内保持兼容,但是其他的artifacts变更会导致不兼容。
硬件/软件的需求
为保持硬件、操作系统、JVM和其他软件上的最新特性和优势,新的Hadoop发行版或者部分feature也需要更新版本的依赖。特定环境下,对于Hadoop版本的升级可能需要升级依赖的软件组件。
策略
- 硬件
- 架构: 社区并没有计划限制hadoop到特定的架构下,但是可能有相关的优化与架构家族系列相关。
- 最小资源: 虽然没有对Hadoop程序有最小资源的限制保证。社区尝试不在次要发行版本内增加需求。
- 操作系统: 社区会尝试在次要版本内维护相同的OS需求(OS内核版本)。当前社区官方支持的是GNU/Linux和Microsoft Windows,在其他操作系统比如Apple MacOSX, Solaris等也是运行良好的。
- JVM需求在次要版本内部的跨小版本不会发生变化除非JVM版本本身不再支持。对于某些支持的操作系统,主要/次要版本可能需要更新版本的JVM。
- 其他软件: 社区尽量维持Hadoop所需的软件的最低版本。比如ssh和Kerberos等。
引用
这里是一些主题相关的JIRAs和页面:
- 文档的进化 - HADOOP-9517
- 二进制的兼容性 for MapReduce end-user applications between hadoop-1.x and hadoop-2.x - MapReduce Compatibility between hadoop-1.x and hadoop-2.x
- 每个接口分类计划的标注 - HADOOP-7391 Hadoop Interface Classification
- 兼容性 for Hadoop 1.x releases - HADOOP-5071
- Hadoop获取其他发布策略的路线图