Hadoop教程

Hadoop配置

控制Hadoop安装的配置文件有许多,最重要的几个文件已列在表9-1中。

表9-1.Hadoop配置文件

文件名称 格式 描述
hadoop-env.sh Bash脚本 记录脚本要用的环境变量,以运行 Hadoop
core-site.xml Hadoop 配置 XML Hadoop Core比的配置项,例如HDFS和 MapReduce常用的1/0设置等
hdfs-site.xml Hadoop 配置 XML Hadoop守护进程的配置项,包栝 namenode,辅助 namenode 和 datanode 等
mapred-site.xml Hadoop 配置 XML MapReduce守护进程的配置项,包括 jobtracker 和 tasktracker
masters 纯文本 运行辅助namenode的机器列表(每行 一个)
slaves 纯文本 运行datanode和tasktracker的机器列 表(每行一个)
hadoop-metrics.properties Java属性 控制metrics在Hadoop上如何发布的 属性
log4j.properties Java属性 tasktracker子进程的任务日志的属性

上述文件都放在Hadoop分发包的conf目录中。配置目录也可重新放在文件系统的 其他地方(Hadoop安装的外面,以便于升级),但是守护进程启动时需要使用-config选项,以指向本地文件系统的某个目录。

配置管理

Hadoop并没有将所有配置信息放在一个单独的全局位置中。反之,集群的Hadmjp 节点都各自保存一系列配置文件,并由管理员完成这些配置文件的同步工作。 Hadoop提供一个基本工具来进行同步配置,即rsync(参见后文的讨论)。此外,诸 如dsh或pdsh等并行shell工具也可完成该任务。

Hadoop也支持为所有的主机器和工作机器采用同一套配置文件。最大的优势在于 简单,不仅体现在理论上(仅需处理一套配置文件),也体现在可操作性上(使用 Hadoop脚本就能进行管理)。

值得一提的是,这种一体适用的配置模型对某些集群来说并不合适。以扩展集群为 例,当用户增加新机器时,如果新机器的硬件部件与现有机器不同,则需要为新机 器创建一套新的配置文件,以充分利用新硬件的资源。

在这种情况下,需要引入“机器类”的概念,分别为不同机器类分别维护一套配置 文件。Hadoop没有提供执行这个操作的工具,需要借助外部工具来执行该配置操 作,例如Chef、Puppet、cfengine和bcfg2等。

对于大型集群来说,同步化所有机器上的配置文件极具挑战性。例如,假设某台机 器正好处于异常状态,而此时用户正好发出一条更新配置的指令,如何保证这台机 器恢复正常状态之后也能够更新配置?这个问题很严重,可能会导致集群中各机器 的配置不匹配。因此,就算用户能够使用Hadoop控制脚本管理Hadoop,仍然推 荐使用控制管理工具管理集群。这些工具足以顺利完成日常维护,例如为安全漏洞 打补丁、升级系统包等。

控制脚本

Hadoop内置一些脚本来运行指令、在集群内启动和终止守护进程。为了运行这些 脚本(存放在bin目录中),还需要指定集群内的所有机器。有两个文件能达成这个 目标,目口 masters和slaves。各文件逐行记录一些机器的名称或IP地址。masters 文件的名称确实有点误导人,它主要记录拟运行辅助namenode的所有机器。 slaves文件记录了运行datanode和tasktracker的所有机器。这两个文件存放在配置 目录之中。用户也可以改变hadoop-env.sh的HADOOP_SLAVES项的值,将s!aves 文件放在其他地方(也可以改变文件名称)。此外,这些文件无需分发到各个工作节 点,因为只有运行在namenode或jobtracker上的控制脚本能使用这些文件。

用户无需指定究竟masters文件中的哪台(或哪些)机器正在运行namenode和 jobtracker,该操作由运行脚本的机器决定。(实际上,在nwsters女件上指定这些 机器会导致在这些机器上运行一个辅助namenode,而这可能违背用户期望。)例 如,start-dfs.sh脚本用于启动集群中所有的HDFS守护进程,但是该脚本运行时会 在同一机器上运行namenode详细步骤如下。

1.在本地机器上启动一个namenode(脚本所运行的机器)。

2.在slaves文件中记录的各机器上启动一个datanode。

3.在masters文件中所记录的各机器上启动一个辅助namenode。

脚本文件start-mapred.sh与start-dfs.sh类似,它启动集群中的所有MapReduce守 护进程。详细步骤如下。

1.在本地机器上启动一个jobtracker。

2.在slaves文件列举的每台机器上启动一个tasktracker。

注意,MApReduce控制脚本不使用masters文件。

此外,stop-dfs.sh和stop-mapred.sh脚本能终止由相关启动脚本启动的守护 进程。上述脚本调用hadoop-daemon.sh脚本来启动和终止Hadoop守护进程。如果用户 已经使用前述脚本,则不宜直接调用hadoop-daemons.sh。但是如果用户需要从其 他系统(或利用自己编写的脚本)控制Hadoop守护进程,则可以调用hadoop- daemon.sh 脚本。类似的,hadoop-daemons.sh(注意,多了 “s”后缀)用于在多 个主机上启动同一守护进程。

主节点场景

由于集群规模差异较大,对于主节点守护进程的配置也差异很大,包括namenode、 辅助namenode和jobtracker。对于一个小型集群来说(几十个节点),可以直接将这 些守护进程放到单独的一台机器上。但是,对于大型集群来说,则最好让这些守护 进程分别运行在不同机器上。

在一个运行大量MapReduce作业的髙负载集群上,jobtracker会使用大量内存和CPU资源,因此它最好运行在一个专用节点上。

不管主守护进程运行在一个还是多个节点上,以下规则均适用。

  • 在namenode机器上运行HDFS控制脚本。masters文件包含辅助namenode的 地址。
  • 在jobtracker机器上运行MapReduce控制脚本。
  • 当namenode和jobtracker运行在不同节点之上时,集群中的各节点将运行一个 datanode 和一个 tasktracker,以使 slaves 文件同步。


    环境设置

    本节探讨如何设置hadoop-env.sh文件中的变量。

    内存

    在默认情况下,Hadoop为各个守护进程分配1000 MB(lGB)内存。该值由hadoop- env.sh文件的HADOOP_HEAPSIZE参数控制。此外,tasktracker启动独立的子JVM 以运行map和reduce任务。因此,计算一个工作机器的最大内存需求时,需要综 合考虑上述因素。

    一个tasktracker能够同时运行最多多少个map任务,由mapred.tasktracker. map.tasks.maximum属性控制,默认值是2个任务。相应的,一个tasktracker能 够同时运行的最多 reduce 任务数由 mapred.tasktracker.reduce. tasks.maximum属性控制,默认值也是2。分配给每个子JVM的内存量由 mapred.child.java.opts属性决定,默认值是-Xmx200m,表示每个任务分配 200 MB内存。顺便提一句,用户也可以提供其他JVM选项。例如,启用verbose GC Logging工具以调试GC。综上所述,在默认情况下,一个工作机器会占用 2800 MB内存(参见表9-2)。

    表9-2.计算工作节点的内存占用量

    JVM 默认内存占用量(MB) 配备8个处理器的机器的内存占用 量,每个子任务分配400MB(MB)
    datanode 1000 1000
    tasktracker 1000 1000
    tasktracker 的子 map 任务 2 X 200 7 X 400
    tasktracker 的子 reduce 任务 2 X 200 7 X 400
    总计 2800 7600

    在一个tasktracker上能够同时运行的任务数取决于一台机器有多少个处理器。由于 MapReduce作业通常是I/0-bound,因此将任务数设定为超出处理器数也有一定道理,能够获得更好的利用率。至于到底需要运行多少个任务,则依赖于相关作业 的CPU使用情况,但经验法则是任务数(包括map和reduce任务)与处理器数的比 值最好在1和2之间。

    例如,假设客户拥有8个处理器,并计划在各处理器上分别跑2个进程,则可以将 mapred.tasktracker.map.tasks.maximum和mapred.tasktracker.reduce.tasks.maximum的值分别设为7(考虑到还有datanode和tasktracker这两个进程,这两项值不可设 为8)。如果各个子任务的可用内存增至400 MB,则总内存开销将高达7600MB(参见表9-2)。

    对于配备8 GB物理内存的机器,该Java内存分配方案是否合理还取决于同时运行 在这台机器上的其他进程。如果这台机器还运行着Streaming和Pipes程序等,由 于无法为这些进程(包括Streaming和Pipes)分配足够内存,这个分配方案并不合理 (而且分配到子节点的内存将会减少)。此时,各进程在系统中不断切换,导致服务 性能恶化。精准的内存设置极度依赖于集群自身的特性。用户可以使用一些工具监 控集群的内存使用情况,以优化分配方案。Ganglia就是采集此类信息的有效工具。

    Java

    需要设置Hadoop系统的Java安装的位置。方法一是在hadoop-env.sh文件中设 置]AVA_HOME项,方法二是在shell中设置JAVA_HOME环境变量。相比之下,方 法一更好,因为只需操作一次就能够保证整个集群使用同一版本的Java。

    系统日志文件

    默认情况下,Hadoop生成的系统日志文件存放在$HADOOP_INSTALL/logs目录之 中,也可以通过hadoop-env.sh文件中的HADOOP_LOG_DIR来进行修改。建议修改 默认设置,使之独立于Hadoop的安装目录。这样的话,即使Hadoop升级之后安 装路径发生变化,也不会影响日志文件的位置。通常可以将日志文件存放在 /var/log/hadoopS..。实现的方法很简单,就是在^^^^职力中加入以下一行。 export HADOOP_LOG_DIR=/var/log/hadoop

    如果日志目录并不存在,则会首先创建该目录(如果操作失败,请确认Hadoop用户 是否有权创建该目录)。运行在各台机器上的各个Hadoop守护进程均会产生两类日 志文件。第一类日志文件(以.10^作为后缀名)是通过log4j记录的。鉴于大部分应 用程序的日志消息都写到该日志文件中,所以在对问题进行故障诊断时需要先查看 这个文件。标准的Hadoop log4j配置采用日常滚动文件后缀策略(Daily Rolling File Appender)来命名日志文件(即:首先设定一个日期模式,例如“yyyy-mm-dd” ,在 某一天产生的日志文件就在名称前缀后面添加一个遵循日期模式的后缀名)。系统 并不自动删除过期的日志文件,而是留待用户定期删除或存档,以节约本地磁盘 空间。

    第二类日志文件后缀名为.out,记录标准输出和标准错误日志。由于Hadoop使用 log4j记录日志,所以这个文件通常只包含少量记录,甚至为空。重启守护进程 时,系统会创建一个新文件来记录此类日志。系统仅保留最新的5个日志文件。旧 的日志文件会附加一个数字后缀,值在1和5之间,5表示最旧的文件。

    日志文件的名称(两种类型)包含运行守护进程的用户名称、守护进程名称和本地主 机名等信息。例如,hadoop-tomdatanode-sturges.local.log.2008-07-04 就是一个日志 文件的名称。这种命名方法保证集群内所有机器的日志文件名称各不相同,从而可 以将所有日志文件存档到一个目录中。

    日志文件名称中的“用户名称”部分实际对应hadoop-env.sh文件中的 HADOOP_IDENT_STRING 项。若想采用其他名称,可以修改 HADOOP_IDENT_STRING 项。


    Hadoop守护进程的关键属性

    Hadoop的配置属性简直让人眼花缭乱。本节讨论对实际工作集群非常关键的一些 属性(或至少能够理解默认属性的含义),这些属性分散在三个文件中,包括core- site.xml, hdfs-site.xml和mapred-site•xml。例9-1列举了这些文件的典型 设置。值得一提的是,这些属性大多被标记为final从而无法被作业配置覆盖。

    <?xml vension="1.0"?>;<!-- cone-site.xml -->;<configuration><property><name>fs.default.name</name><value>hdfs://namenode/</value><final>tnue</final></property></configuration><?xml vension="1.0"?><!-- hdfs-site.xml --><configuration><property><name>dfs.name.din</name><value>/diskl/hdfs/name,/nemote/hdfs/name</value><final>tnue</final></property><property><name>dfs.data.din</name><value>/diskl/hdfs/data,/disk2/hdfs/data</value><final>tnue</final></property></property><name>fs.checkpoint.din</name><value>/diskl/hdfs/namesecondany,/disk2/hdfs/naniGSGcondany</value><final>tnue</final></property></configuration><?xml vension="1.0"?><!-- mapned-site.xml --><configucation><property><name>mapned.job.tracker</name><value>jobtnacken:8021</value><final>tnue</final></property><property><name>mapned.local.din</name><value>/diskl/mapnGd/local,/disk2/mapned/local</value><final>true</final></property><property><name>mapred.system.dir</name><value>/tmp/hadoop/mapred/system</value >;<final>true</final></property><property><name>mapred.tasktracker.map.tasks.maximum</name><value>7</value><final>true</final></property><property><name>mapred.tasktracker.reduce.tasks.maximum</name><value>7</value><final>true</final></property><property><name>mapred.child.java.opts</name><value>-Xmx400m</value><!-- Not marked as final so jobs can include JVM debugging options --></property></configuration>

    HDFS

    运行HDFS需要将一台机器指定为namenode。在例9-1中,属性fs.default.name描述HDFS文件系统的URI,其主机是namenode的主机名称或IP地址,端口号是namenode监听RPC的端口,如果没有指定端口,默认端口是8020。

    属性fs.default.name也指定了默认文件系统,可以解析相对路径。相对路径的 长度更短,使用更便捷(不需要了解特定namenode的地址)。例如,假设默认文件 系统如例9-1所示的那样,则相对路径/a/A被解析为hdfs://namenode/afb。

    还需要配置HDFS以决定namenode和datanode的存储目录。属性项dfs.name.dir 指定一系列目录来供namenode存储永久性的文件系统元数据(编辑日志和文件系统 映像)。这些元数据文件会同时备份在所有指定的目录中。通常情况下,配置 dfs.name.din,将namenode的元数据写到一个(或两个)本地磁盘和一个远程磁盘 (例如NFS挂载的目录)之中。这样的话,即使本地磁盘发生故障,甚至整个 namenode发生故障,都可以恢复元数据文件,并且重构新的namenode。辅助 namenode只是定期保存namenode的检查点,不提供namenode的最新备份。

    属性项dfs.data.dir指定存储数据的目录。前面提到,dfs.name.dir 描述一系列目录,其目的是支持冗余备份。虽然dfs.data.dir>也描述了一系列 目录,但是其目的是循环地在各个目录中写数据。因此,为了提髙性能,最好分别 为各个本地磁盘指定一个存储目录。这样一来,数据块跨磁盘分布,针对不同数据 块的读操作可以并发执行,从而提升读性能。

    最后,还需要指定辅助namenode存储文件系统的检查点的目录。属性项 fs.checkpoint.dir指定一系列目录来保存检查点。与namenode类似,检查点 映像文件会分别存储在各个目录之中,以支持冗余备份。

    表9-3总结了 HDFS的关键配置属性。

    属性名称 类型 默认值 说明
    fs.default.name URI file:/// 默认文件系统。URI定 义主机名称和namenode 的RPC服务器工作的端 口号,默认值是8020。
    dfs.name.dir 以逗号分隔的目录名 ${hadoop.tmp.dir}/dfs/name namenode存储永久性的 元数据的目录列表。 namenode在列表上的各 个目录中均存放相同的 元数据文件
    dfs.data.dir 以逗号分隔的目录名称 ${hadoop.tmp.dir}/dfs/data datanode存放数据块的 目录列表。各个数据块 分别存放于某一个目录中
    fs.checkpoint.dir 以逗号分隔 ${hadoop.tmp.dir}/dfs/namesecondary 辅助namenode存放检查 点的目录列表。在所列 的各个目录中分别存放一份检查点文件的

    MapReduce

    用户需要指派一台机器为jobtracker,以运行MapReduce。在小型集群中, jobtracker可以和namenode同处一台机器上。设置mapred.job.tracker属性, 指定jobtracker的主机名或IP地址,以及它在监听的端口。该属性并非URI格 式,而是“主机:端口”格式。通常情况下,端口号被设为8021。

    在执行MapReduce作业的过程中所产生的中间数据和工作文件被写到临时本地文 件之中。由于这些数据包括map任务的输出数据,数据量可能非常大,因此必须 保证本地临时存储空间(由mapred.local.dir属性设置)的容量足够大。 mapred.local.dir属性使用一个逗号分隔的目录名称列表,用户最好将这些目录 分散到所有本地磁盘,以提升磁盘I/O效率。通常情况下,会使用与datanode相同 的磁盘和分区(但是不同的目录)存储MapReduce的临时数据。如前所述,datanode 的数据块存储目录由dfs.data.dir属性项指定。

    MapReduce使用分布式文件系统来和运行MapReduce任务的各个tasktracker共享 文件(例如作业JAR文件)。属性项mapred.system.dir指定这些文件的存储目 录,可以是针对默认文件系统的相对路径。(默认文件系统由fs.default.name 属性设定,一般为HDFS。)

    最后,属性 mapred.tasktracker.map.tasks.maximumfp mapred.tasktracker. neduce.tasks.maximum表示在tasktracker机器上有多少核是可用的, mapned .child. java. opts表示tasktracker子JVM的有效内存大小。

    表9-4总结了 HDFS的关键配置属性。

    表9-4. MapReduce守护进程的关键属性

    属性名称 类型 默认值 说明
    mapred.job.tracker 主机名和端口 local jobtracker 的 RPC 服务器 所在的主机名称和端口 号。如果设为默认值local则运行一个MapReduce 作业时, jobtracker即时以处理时 模式运行(换言之,用户 无需启动jobtracker,实际 上试图在该模式下启动 jobtracker会引发错误)
    mapred.local.dir 逗号分隔的目录名称 ${hadoop.tmp.din}/mapred/local 存储作业中间数据的一 个目录列表。作业终止 时,数据被清除
    mapned.system.dir URI ${hadoop.tmp.dir}/mapred/system 在作业运行期间存储共享 文件的目录、相对于 fs.default.name
    mapred.task tracken. map.tasks.maximum int 2 在任一时刻,运行在 tasktracker 之上的 map 任 务的最大数
    mapred.task tracker. neduce.tasks.maximum int 2 在任一时刻,运行在 tasktracker 之上的 reduce 任务的最大数
    mapred.child.java.opts String -Xmx200m JVM选项,用于启动运 行map和reduce任务的 tasktracker子进程。该属 性可以针对每个作业进 行设置。例如,可以设置JVM的属性,以支持调试

    Hadoop守护进程的地址和端口

    Hadoop守护进程一般同时运行RPC和HTTP两个服务器,RPC服务器(表9-5)支 持守护进程间的通信,HTTP服务器则提供与用户交互的Web页面(表9-6)。需要 分别为各个服务器配置网络地址和端口号。当网络地址被设为0.0.0.0时, Hadoop将与本机上的所有地址绑定。用户也可以将服务器与某个指定的地址相绑.定。端口号0表示服务器会选择一个空闲的端口号:但由于这种做法与集群范围的防火墙策略不兼容,通常不推荐。

    表9-5. RPC服务器的属性

    属性名称 默认值 说明
    fs.default.name file:/// 被设为一个HDFS的URI W,该属娃描述namenode 的RPC服务器地址和端 口。若未指定端口号,默 认的端口号便是8020
    dfs.datanode.ipc.address 0.0.0.0:50020 datanode的RPC服务器 的地址和端口
    mapred.job.tracker local 被设为主机名称和端口号 时,该属性指定jobtracker的RPC服务器地址和端 口。常用的端口号是8021
    mapred.task.tracker.report.address 127.0.0.1:0 tasktracker 的 RPC 服务 器地址和端口号。 tasktracker 的丰 JVM利用它和tasktracker通信。在本例中,可以使用任一 空闲端口,因为服务器仅 对回送地址隐蔽。如果本 机器没有回送地址,则需变更默认设置

    除了RPC服务器之外,datanode也运行TCP/IP服务器以支持块传输。服务器地址 和端口 由属性 dfs.datanode.address 设定,默认值是 0.0.0.0:50010。

    表9-6.HTTP服务器的属性

    属性名称 默认值 说明
    mapned.job.tracker.http.address 0.0.0.0:50030 jobtracker 的 HTTP 服务 器地址和端口
    mapred.task.tracker.http.address 0.0.0.0:50060 tasktracker 的 HTTP 服务 器地址和端口
    dfs.http.address 0.0.0.0:50070 namenode 的 HTTP 服务 器地址和端口
    dfs.datanode.http.address 0.0.0.0:50075 datanode的HTTP服务器 地址和端口
    dfs.secondary.http.address 0.0.0.0:50090 辅助 namenode 的 HTTP 服务器地址和端口

    有多个网络接口时,还可以选择某一个网络接口作为各个datanode和tasktracker 的IP地址(针对HTTP和RPC服务器)。相关属性项包括dfs.datanode.dns.interface 和 mapred.tasktracker.dns.interface,默认值都是 default,表示使用默认 的网络接口。可以修改这两个属性项来变更网络接口的地址(例如,eth0)。


    Hadoop的其他属性

    本节讨论其他一些可能会用到的Hadoop属性。

    集群成员

    为了便于在将来添加或移除节点,用户可以通过文件来指定一些即将作为datanode 或tasktracker加入集群的经过认证的机器。属性项dfs.hosts记录即将作为 datanode加入集群机器列表;属性项mapred.hosts记录即将作为tasktrackerW 入集群的机器列表。与之相对应的,属性项dfs.hosts.exclude和 mapred.hosts.exclude所指定的文件分别包含待移除的机器列表。

    缓冲区大小

    Hadoop使用一个4KB大小的缓冲区辅助I/0操作。但是,对于现代硬件和操作系 统来说,这个容量实在过于保守了。增大缓冲区容量会显著提高性能,例如 64KB(65 536字节)或128 KB(131 072字节)更为常用。可以通过core-site.xml jtf+ 中的io.file.buffer.size属性项来设置缓冲区大小。

    HDFS块大小

    默认情况下,HDFS块大小是64 MB,但是许多集群把块大小设为128 MB(134 217 728 字节)或256 MB(268 435 456字节) 以降低namenode的内存压力,并向mapper传输 更多数据。可以通过core-site.xml文件中的dfs.block.size属性项设置块的大小。

    保留的存储空间

    默认情况下,datanode能够使用存储目录上的所有闲置空间,这可能导致没有空间 可供其他应用程序使用。如果计划将部分空间留给其他应用程序(非HDFS),则需 要设置dfs.datanode.du.reserved属性项来指定待保留的空间大小(以字节为单位)。

    回收站

    Hadoop文件系统也有回收站设施,被删除的文件并未被真正删除,仅只转移到回 收站(一个特定文件夹)中。回收站中的文件在被永久删除之前仍会至少保留一段时 间。该信息由core-site.xml文件中的fs.trash.interval属性项(以分钟为单位) 设置。默认情况下,该属性项的值是0,表示回收站特性无效。

    与其他操作系统类似,Hadoop的回收站是用户级特性,换句话说,只舍由文件 系统shell直接删除的文件才会放到回收站中,用程序删€的文件会被直接删 除。当然,也有例外的情况——就是使用Trash类。构造一个Trash实例,调用moveToTrash()方法会把指定路径的文件移到垃圾箱中。如果操作成功,该方法 返回一个值,否则,如果回收站特性未被启动,或该文件已经在回收站中,该方法 返回false。

    任务的内存限制

    在共享集群上,不允许由于存在有纰漏的MapReduce程序而影响集群中各个节点 的正常工作。然而,如果map或reduce任务出现内存泄露,则这种情况很可能会 发生。例如,假设一台运行tasktracker的机器的可用内存耗尽,则会影响其他正在 运行的进程。为了防止此类事故,需要设置mapred.child.ulimit项,限制由 tasktracker发起的子进程的最大虚拟内存(单位是千字节)。值得一提的是,该值应 该明显高于JMV内存(由mapred.child.java.opts设置),否则子JVM可能无 法启动。也可以采用另一种方法,即使用limits.conf在操作系统层面限制进程所耗的资源。

    业调度器

    在多用户的MapReduce设置中,若考虑将默认的F1F0作业调度方案改变为功能更 强的调度方案,


    创建用户帐号

    Hadoop集群创建完毕,并且正常工作之后,还需要授予用户访问权限。具体而言,就是分别为各用户创建home目录,并相应地赋予用户拥有者权限。

    % hadoop fs -mkdir /user/username% hadoop fs -chown username: username /user/username

    设定各目录的空间容量限制非常有必要。以下指令设定各用户的目录容量不超过1TB:

    % hadoop dfsadmin -setSpaceQuota lt /user/username

    关注微信获取最新动态