MapReduce 应用程序框架对通过分布式缓存部署新版 MapReduce 框架提供基本支持。通过设置适当的配置属性,用户可以运行与最初部署到集群中不同的 MapReduce 版本。例如,集群管理员可以在 HDFS 中放置多个 MapReduce 版本,并配置 mapred-site.xml
以指定作业将默认使用哪个版本。这允许管理员在特定条件下对 MapReduce 框架执行滚动升级。
目前,通过分布式缓存部署 MapReduce 框架的支持不适用于用于提交和查询作业的作业客户端代码。它也不适用于在每个 NodeManager 中作为辅助服务运行的 ShuffleHandler
代码。因此,以下限制适用于可以通过分布式缓存以滚动升级方式成功部署的 MapReduce 版本
MapReduce 版本必须与用于提交和查询作业的作业客户端代码兼容。如果它不兼容,则必须在提交或查询使用新 MapReduce 版本的作业的任何节点上单独升级作业客户端。
MapReduce 版本必须与提交作业的作业客户端使用的配置文件兼容。如果它与该配置不兼容(例如:必须设置新属性或更改现有属性值),则必须首先更新配置。
MapReduce 版本必须与群集中的节点上运行的 ShuffleHandler
版本兼容。如果它不兼容,则必须将新的 ShuffleHandler
代码部署到群集中的所有节点,并且必须重新启动 NodeManager 以获取新的 ShuffleHandler
代码。
部署新 MapReduce 版本包括三个步骤
将 MapReduce 存档上传到作业提交客户端可以访问的位置。理想情况下,存档应位于群集的默认文件系统中的公开可读路径上。有关更多详细信息,请参阅下面的存档位置讨论。您可以使用框架上传工具执行此步骤,例如 mapred frameworkuploader -target hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar#mrframework
。它将选择 classpath 中的 jar 文件,并将它们放入由 -target 和 -fs 选项指定的 tar 存档中。然后,该工具会返回有关如何设置 mapreduce.application.framework.path
和 mapreduce.application.classpath
的建议。
-fs
:目标文件系统。默认为由 fs.defaultFS
设置的默认文件系统。
-target
是框架 tarball 的目标位置,后面可以跟一个 # 和本地化别名。然后,它将 tar 上传到指定目录。由于 jar 文件已经压缩,因此不需要 gzip。确保目标目录对所有用户可读,但管理员以外的人不可写,以保护群集安全。
将 mapreduce.application.framework.path
配置为指向存档所在的位置。与为作业指定分布式缓存文件时一样,这是一个 URL,如果指定了 URL 片段,它还支持为存档创建别名。例如,hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar.gz#mrframework
将被本地化为 mrframework
而不是 hadoop-mapreduce-3.3.6.tar.gz
。
配置 mapreduce.application.classpath
以设置与上面配置的 MapReduce 存档一起使用的正确类路径。如果使用 frameworkuploader
工具,它会上传所有依赖项并返回需要在此处配置的值。注意:如果配置了 mapreduce.application.framework.path
但 mapreduce.application.classpath
未引用存档路径的基本名称或别名(如果指定了别名),则会发生错误。
请注意,MapReduce 存档的位置对作业提交和作业启动性能至关重要。如果存档未位于集群的默认文件系统上,则会将其复制到每个作业的作业暂存目录,并将其本地化到作业任务运行的每个节点。这会降低作业提交和任务启动性能。
如果存档位于默认文件系统上,则作业客户端不会将存档上传到每个作业提交的作业暂存目录。但是,如果所有集群用户都无法读取存档路径,则会为任务执行的每个节点上的每个用户单独本地化存档。这可能会在分布式缓存中造成不必要的重复。
在使用大型集群时,提高存档的复制因子以提高其可用性非常重要。当集群中的节点首次本地化存档时,这将分散负载。
上面提到的 frameworkuploader
工具具有其他参数,有助于调整性能
-initialReplication
:这是创建框架 tarball 时使用的复制计数。将此值保留为默认值 3 是安全的。这是经过测试的方案。
-finalReplication
:在收集并上传所有块后,上传工具会设置复制。如果需要快速初始启动,建议将其设置为已委托节点数除以 2,但不得超过 512。这将利用 HDFS 以分布式方式传播 tarball。作业一旦开始,它们可能会命中本地 HDFS 节点以从中进行本地化,或者它们可以选择从广泛的附加源节点中进行选择。如果将其设置为较低的值(例如 10),则这些复制节点的输出带宽将影响第一个作业的运行速度。在群集中启动所有作业以节省磁盘空间后,可以将复制计数手动减少到较低的值(例如 10)。
-acceptableReplication
:该工具将等待 tarball 被复制到该次数后才会退出。这应小于或等于 finalReplication
中的值的复制计数。这通常是 finalReplication
中值的 90%,以适应故障节点。
-timeout
:在工具退出之前等待达到 acceptableReplication
的超时(以秒为单位)。否则,该工具会记录错误并返回。
为 MapReduce 归档设置适当的类路径取决于归档的组成以及它是否具有任何其他依赖项。例如,归档不仅可以包含 MapReduce jar,还可以包含必要的 YARN、HDFS 和 Hadoop Common jar 以及所有其他依赖项。在这种情况下,mapreduce.application.classpath
将配置为类似于以下示例的内容,其中归档基名是 hadoop-mapreduce-3.3.6.tar.gz,并且归档的内部组织类似于标准 Hadoop 分发归档
$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/lib/*
另一种可能的方法是让归档仅包含 MapReduce jar,并从安装在节点上的 Hadoop 分发中获取剩余的依赖项。在这种情况下,上述示例将更改为类似于以下内容
$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$HADOOP_COMMON_HOME/share/hadoop/common/*,$HADOOP_COMMON_HOME/share/hadoop/common/lib/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*,$HADOOP_YARN_HOME/share/hadoop/yarn/*,$HADOOP_YARN_HOME/share/hadoop/yarn/lib/*
frameworkuploader
工具具有以下参数来控制哪些 jar 最终进入框架 tarball
-input
:这是遍历的输入类路径。找到的 jar 文件将添加到 tarball 中。它默认为 hadoop classpath
命令返回的类路径。
-blacklist
:这是一个逗号分隔的正则表达式数组,用于过滤要从类路径中排除的 jar 文件名。例如,它可用于排除测试 jar 或不需要本地化的 Hadoop 服务。
-whitelist
:这是一个逗号分隔的正则表达式数组,用于包含某些 jar 文件。这可用于提供额外的安全性,以便在工具运行时,任何外部来源都无法在类路径中包含恶意代码。
-nosymlink
:此标志可用于排除指向同一目录的符号链接。这并不是广泛使用。例如,/a/foo.jar
和指向 /a/foo.jar
的符号链接 /a/bar.jar
通常会将 foo.jar
和 bar.jar
作为单独的文件添加到 tarball 中,尽管它们实际上是同一个文件。此标志将使工具排除 /a/bar.jar
,因此只会添加该文件的一个副本。
如果群集中还启用了 shuffle 加密,那么我们可能会遇到 MR 作业因出现如下异常而失败的问题
2014-10-10 02:17:16,600 WARN [fetcher#1] org.apache.hadoop.mapreduce.task.reduce.Fetcher: Failed to connect to junpingdu-centos5-3.cs1cloud.internal:13562 with 1 map outputs javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:81) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:61) at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:584) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1193) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318) at org.apache.hadoop.mapreduce.task.reduce.Fetcher.verifyConnection(Fetcher.java:427) ....
这是因为 MR 客户端(从 HDFS 部署)无法访问 $HADOOP_CONF_DIR 目录下的本地 FS 中的 ssl-client.xml。要解决此问题,我们可以将包含 ssl-client.xml 的目录添加到 MR 的类路径中,该类路径在上述“mapreduce.application.classpath”中指定。为了避免 MR 应用程序受到其他本地配置的影响,最好创建一个专门的目录来放置 ssl-client.xml,例如 $HADOOP_CONF_DIR 下的子目录,如:$HADOOP_CONF_DIR/security。
框架上传工具可用于收集 MapReduce AM、映射器和归约器将使用的群集 jar。它返回提供建议配置值的日志
INFO uploader.FrameworkUploader: Uploaded hdfs://mynamenode/mapred/framework/mr-framework.tar#mr-framework INFO uploader.FrameworkUploader: Suggested mapreduce.application.classpath $PWD/mr-framework/*
将 mapreduce.application.framework.path
设置为上面记录的第一个值,将 mapreduce.application.classpath
设置为第二个记录的值。