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 命令验证运行命令的用户是否为 hdfs 用户,方法是检查 USER 环境变量。这也适用于非守护程序。设置 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 檔案可能會被忽略,如果最終用戶在運行時更改了配置目錄。

一個示例 shell 檔案位於 libexec 目錄中。

Shell API

Apache Hadoop 的 shell 代碼有一個功能庫,供管理員和開發人員使用,以協助配置和高級功能管理。這些 API 遵循標準的 Apache Hadoop 接口分類,只是增加了一個:可替換。

Shell code允許覆蓋核心功能。然而,並非所有功能都可以或應該被替換。如果一個功能不安全可被替換,它將具有屬性 Replaceable: No。如果一個功能可以安全替換,它將具有屬性 Replaceable: Yes。

要替換一個功能,請在 ${HADOOP_CONF_DIR} 目錄中創建一個名為 hadoop-user-functions.sh 的文件。只需在此文件中定義新的替換功能,系統將自動採用它。此文件中可以包含所需數量的替換功能。功能替換的示例位於 hadoop-user-functions.sh.example 文件中。

標記為公共和穩定的功能在shell配置文件中使用是安全的。其他功能可能在次要版本中更改。

用戶級API訪問

除了 .hadoop-env 允許個別用戶覆蓋 hadoop-env.sh 外,用戶還可以使用 .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

我們將子命令類型設置為“客戶端”,因為沒有特殊限制、額外功能等。這個功能也可以用來覆蓋內置命令。例如,定義

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,則必須繼續執行程式,以便使用 Apache Hadoop 特定參數的 Java 將根據給定的 Java 類別啟動。另一個例子是在發生無法恢復的錯誤時。函數的責任是輸出適當的訊息(最好使用 hadoop_error API 呼叫)並適當退出。

以特權執行(安全模式)

某些守護程序,例如 DataNode 和 NFS 網關,可以以特權模式運行。這意味著它們預期以 root 身份啟動,並(默認情況下)通過 jsvc 切換到另一個使用者ID。這允許這些守護程序在正常執行期間抓取低特權端口,然後放棄超級使用者權限。對於使用動態子指令的第三方來說,也可以以特權模式運行。如果以下條件為真

  • (command)_(subcommand)_SECURE_USER 環境變數被定義且指向有效的使用者名稱
  • HADOOP_SECURE_CLASSNAME 被定義且指向有效的 Java 類別

然後 shell 腳本將嘗試以特權運行類別作為命令,就像內建命令一樣。一般來說,使用者應該定義 _SECURE_USER 變數,而開發者應該在他們的 shell 腳本啟動腳本中定義 _CLASSNAME。