Unix Shell 指南

Apache Hadoop 的许多功能都通过 shell 进行控制。有几种方法可以修改这些命令执行的默认行为。

重要的最终用户环境变量

Apache Hadoop 有许多环境变量,用于控制软件的各个方面。(请参阅 hadoop-env.sh 和相关文件。)其中一些环境变量专门用于帮助最终用户管理其运行时。

HADOOP_CLIENT_OPTS

此环境变量用于所有最终用户非守护程序操作。它可用于通过系统属性定义设置任何 Java 选项以及任何 Apache Hadoop 选项。例如

HADOOP_CLIENT_OPTS="-Xmx1g -Dhadoop.socks.server=localhost:4000" hadoop fs -ls /tmp

将增加内存,并通过 SOCKS 代理服务器发送此命令。

注意:如果定义了“YARN_CLIENT_OPTS”,则在使用“yarn”运行命令时,它将替换“HADOOP_CLIENT_OPTS”。

(command)_(subcommand)_OPTS

还可以逐个子命令设置选项。这允许人们为特定情况创建特殊选项。该模式的第一部分是正在使用的命令,但全部大写。命令的第二部分是正在使用的子命令。然后最后跟上字符串 _OPT

例如,要将 mapred distcp 配置为使用 2GB 堆,可以使用

MAPRED_DISTCP_OPTS="-Xmx2g"

这些选项将在执行期间出现在 HADOOP_CLIENT_OPTS 之后,并且通常会优先。

HADOOP_CLASSPATH

注意:应通过 shellprofile 条目配置全站设置,并应通过 ${HOME}/.hadooprc 使用 hadoop_add_classpath 函数配置永久全用户设置。有关详细信息,请参见下方。

通过设置此环境变量,Apache Hadoop 脚本能够将更多内容注入到正在运行的命令的类路径中。它应为目录、文件或通配符位置的冒号分隔列表。

HADOOP_CLASSPATH=${HOME}/lib/myjars/*.jar hadoop classpath

用户可以通过 HADOOP_USER_CLASSPATH_FIRST 变量提供路径位置的提示。将其设置为任何值都将指示系统尝试将这些路径推送到前面。

自动设置变量

如果用户有一组通用设置,则可以将它们放入 ${HOME}/.hadoop-env 文件中。此文件始终被读取以初始化和覆盖用户可能希望自定义的任何变量。它使用 bash 语法,类似于 .bashrc 文件

例如

#
# my custom Apache Hadoop settings!
#

HADOOP_CLIENT_OPTS="-Xmx1g"
MAPRED_DISTCP_OPTS="-Xmx2g"
HADOOP_DISTCP_OPTS="-Xmx2g"

.hadoop-env 文件还可以用于扩展功能并教授 Apache Hadoop 新技巧。例如,若要运行访问环境变量 ${HADOOP_SERVER} 中引用的服务器的 hadoop 命令,则 .hadoop-env 中的以下内容将执行此操作

if [[ -n ${HADOOP_SERVER} ]]; then
  HADOOP_CONF_DIR=/etc/hadoop.${HADOOP_SERVER}
fi

警告:并非所有 Unix Shell API 例程都可以在 .hadoop-env 中使用或正常工作。有关 .hadooprc 的详细信息,请参见下方。

管理员环境

除了各种 XML 文件之外,管理员在使用 Unix Shell 时还有两个关键功能可用于配置 Apache Hadoop

  • 许多环境变量会影响系统运行方式。本指南将仅重点介绍一些关键变量。通常在各种 *-env.sh 文件中提供更多信息。

  • 补充或对现有脚本进行一些特定于平台的更改。Apache Hadoop 提供了执行函数覆盖的功能,以便可以在不进行所有这些工作的情况下就地更改现有代码库。稍后将在 Shell API 文档中介绍替换函数。

(command)_(subcommand)_OPTS

到目前为止,最重要的变量是控制守护进程工作方式的 _OPTS 变量系列。这些变量应包含所有与这些守护进程相关的设置。

与上述用户命令类似,所有守护进程都将遵守 (command)_(subcommand)_OPTS 模式。通常建议在 hadoop-env.sh 中设置这些模式,以确保系统在重启时知道应使用哪些设置。与面向用户的子命令不同,守护进程不会遵守 HADOOP_CLIENT_OPTS

此外,以额外安全模式运行的守护进程还支持 (command)_(subcommand)_SECURE_EXTRA_OPTS。这些选项是通用 *_OPTS补充,将出现在后面,因此通常具有优先权。

(command)_(subcommand)_USER

Apache Hadoop 提供了一种按子命令执行用户检查的方法。虽然这种方法很容易规避,并且不应被视为安全功能,但它确实提供了一种防止意外的方法。例如,设置 HDFS_NAMENODE_USER=hdfs 将使 hdfs namenodehdfs --daemon start namenode 命令通过检查 USER 环境变量来验证运行这些命令的用户是否是 hdfs 用户。这同样适用于非守护进程。设置 HADOOP_DISTCP_USER=jane 将验证 USER 是否设置为 jane,然后才能执行 hadoop distcp 命令。

如果存在 _USER 环境变量并且以特权运行命令(例如,作为 root;请参阅 API 文档中的 hadoop_privilege_check),则执行将首先切换到指定用户。对于出于安全原因支持用户帐户切换并因此具有 SECURE_USER 变量的命令(请参阅下文),基础 _USER 变量需要是预期用于切换到 SECURE_USER 帐户的用户。例如

HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs

将强制“hdfs –daemon start datanode”成为 root,但在完成特权工作后最终将切换到 hdfs 用户。

请注意,如果使用了 --workers 标志,则用户切换会在调用 ssh 之后 发生。但是,sbin 中的多守护进程启动和停止命令将在之前切换(如果合适),因此将使用指定 _USER 的密钥。

开发人员和高级管理员环境

Shell 配置文件

Apache Hadoop 允许第三方通过各种可插入接口轻松添加新功能。这包括一个 shell 代码子系统,该子系统可以轻松地将必要的内容注入到基本安装中。

此功能的核心是 shell 配置文件概念。Shell 配置文件是 shell 代码段,可以执行诸如将 jar 添加到类路径、配置 Java 系统属性等操作。

Shell 配置文件可以安装在 ${HADOOP_CONF_DIR}/shellprofile.d${HADOOP_HOME}/libexec/shellprofile.d 中。libexec 目录中的 shell 配置文件是基本安装的一部分,用户无法覆盖它们。如果最终用户在运行时更改了配置文件目录,则配置文件目录中的 shell 配置文件可能会被忽略。

libexec 目录中有一个 shell 配置文件示例。

Shell API

Apache Hadoop 的 shell 代码有一个 函数库,管理员和开发人员可以使用该函数库来帮助他们进行配置和高级功能管理。这些 API 遵循标准 Apache Hadoop 接口分类,并增加了一项:可替换。

shell 代码允许覆盖核心函数。但是,并非所有函数都可以或应该被替换。如果某个函数不能安全替换,则它将具有可替换性:否属性。如果某个函数可以安全替换,则它将具有可替换性:是属性。

要替换某个函数,请在 ${HADOOP_CONF_DIR} 目录中创建一个名为 hadoop-user-functions.sh 的文件。只需在此文件中定义新的替换函数,系统将自动选取它。此文件中可以有多个替换函数。函数替换示例位于 hadoop-user-functions.sh.example 文件中。

标记为公共且稳定的函数可以安全地按原样在 shell 配置文件中使用。其他函数可能会在次要版本中发生更改。

用户级 API 访问

除了允许各个用户覆盖 hadoop-env.sh.hadoop-env 之外,用户还可以使用 .hadooprc。在配置 Apache Hadoop shell 环境之后调用此文件,并允许使用完整的 shell API 函数调用。

例如

hadoop_add_classpath /some/path/custom.jar

将进入 .hadooprc

动态子命令

利用 Shell API,第三方可以将自己的子命令添加到主 Hadoop shell 脚本(hadoop、hdfs、mapred、yarn)中。

在执行子命令之前,主脚本将检查是否存在 (scriptname)_subcommand_(subcommand) 函数。此函数使用所有剩余命令行参数设置的参数执行。例如,如果定义了以下函数

function yarn_subcommand_hello
{
  echo "$@"
  exit $?
}

然后执行 yarn --debug hello world I see you 将激活脚本调试并调用 yarn_subcommand_hello 函数,如下所示

yarn_subcommand_hello world I see you

这将导致输出

world I see you

还可以将新子命令添加到用法输出中。hadoop_add_subcommand 函数向用法输出中添加文本。利用标准 HADOOP_SHELL_EXECNAME 变量,我们可以限制哪个命令获取我们的新函数。

if [[ "${HADOOP_SHELL_EXECNAME}" = "yarn" ]]; then
  hadoop_add_subcommand "hello" client "Print some text to the screen"
fi

我们将子命令类型设置为“client”,因为没有特殊限制、额外功能等。此功能还可以用于覆盖内置功能。例如,定义

function hdfs_subcommand_fetchdt
{
  ...
}

… 将使用自定义子命令替换现有的 hdfs fetchdt 子命令。

动态子命令的一些关键环境变量

  • HADOOP_CLASSNAME

这是当程序执行继续时要使用的 Java 类的名称。

  • HADOOP_PRIV_CLASSNAME

这是当希望以特权模式运行守护进程时要使用的 Java 类的名称。(请参见下文。)

  • HADOOP_SHELL_EXECNAME

这是正在执行的脚本的名称。它将是 hadoop、hdfs、mapred 或 yarn 之一。

  • HADOOP_SUBCMD

这是在命令行中传递的子命令。

  • HADOOP_SUBCMD_ARGS

此数组包含在 Apache Hadoop 公共参数处理发生之后的参数列表,并且与作为参数传递给子命令函数的列表相同。例如,如果在命令行中执行了 hadoop --debug subcmd 1 2 3,则 ${HADOOP_SUBCMD_ARGS[0]} 将为 1,并且 hadoop_subcommand_subcmd 的 $1 也将等于 1。此数组列表可能会被子命令函数修改,以向参数列表中添加或删除值以进行进一步处理。

  • HADOOP_SECURE_CLASSNAME

如果此子命令运行支持安全模式的服务,此变量应设置为安全版本的类名。

  • HADOOP_SUBCMD_SECURESERVICE

将其设置为 true 将强制子命令在安全模式下运行,而不管 hadoop_detect_priv_subcmd。HADOOP_SECURE_USER 预计将设置为将执行最终进程的用户。请参阅有关安全模式的更多信息。

  • HADOOP_SUBCMD_SUPPORTDAEMONIZATION

如果此命令可以作为守护进程执行,请将其设置为 true。

  • HADOOP_USER_PARAMS

这是命令行的全部内容,在进行任何解析之前。它将包含诸如 --debug 的标志。它可能不会被操纵。

Apache Hadoop 运行时设施需要函数退出,如果不需要进一步处理。例如,在上面的 hello 示例中,不需要 Java 和其他设施,因此一个简单的 exit $? 就足够了。但是,如果函数要利用 HADOOP_CLASSNAME,则程序执行必须继续,以便针对给定的 Java 类启动具有 Apache Hadoop 特定参数的 Java。另一个示例是不可恢复错误的情况。函数负责打印适当的消息(最好使用 hadoop_error API 调用),并适当地退出。

使用特权运行(安全模式)

某些守护进程(例如 DataNode 和 NFS 网关)可以在特权模式下运行。这意味着它们应该以 root 身份启动,并且(默认情况下)通过 jsvc 切换到另一个用户 ID。这允许这些守护进程获取低特权端口,然后在正常执行期间放弃超级用户特权。对于利用动态子命令的第三方,也可以使用特权运行。如果以下情况为真

  • (command)_(subcommand)_SECURE_USER 环境变量已定义并指向有效的用户名
  • HADOOP_SECURE_CLASSNAME 已定义并指向有效的 Java 类

那么 shell 脚本将尝试以特权方式将类作为命令运行,就像内置命令一样。通常,用户需要定义 _SECURE_USER 变量,而开发人员在他们的 shell 脚本引导程序中定义 _CLASSNAME。