之前已经在七台物理机上以全分布模式安装了Hadoop集群,除了制动NameNode、JobTracker、DataNode、TaskTracker及相关的端口号外,并没有对集群配置做进一步的设定,都保留了默认值。而要想使Hadoop集群发挥更大的作用则需要根据实际情况对配置做修改,下面将介绍如何在Hadoop集群中对一些配置项做修改,由于运维Hadoop集群的经验尚浅难免有所遗漏或者不足。
Hadoop默认的配置文件为${HADOOP_HOME}\src\core\core-default.xml、${HADOOP_HOME}\src\hdfs\hdfs-default.xml、${HADOOP_HOME}\src\mapred\mapred-default.xml。而定制的配置文件则位为${HADOOP_HOME}\conf\core-site.xml、${HADOOP_HOME}\conf\hdfs-site.xml、${HADOOP_HOME}\conf\mapred-site.xml。在对定制配置文件不做修改的情况下,Hadoop使用默认配置文件的默认选项。另外还可以修改${HADOOP_HOME}\conf\hadoop-env.sh中的特定值来控制${HADOOP_HOME}\bin\hadoop脚本的执行行为。
Hadoop的定制配置主要包括两个方面,一是Hadoop守护进程的运行环境,二是Hadoop守护进程的配置参数。Hadoop守护进程分别为NameNode、JobTracker、DataNode、TaskTracker。
首先看看Hadoop守护进程运行环境的管理,可以通过修改${HADOOP_HOME}\conf\hadoop-env.sh中的特定值达到管理运行环境的目的。每台节点上的hadoop-env.sh都要正确指设置JAVA_HOME的值,多数情况下需要指定HADOOP_PID_DIR的值,该值为某个目录,其含义是只有运行Hadoop守护进程的用户可以在该目录中执行写操作,否则存在潜在的符号链接攻击。管理员可以使用选项HADOOP_*_OPTS管理不同的守护进程,下表展示了各种选项:
守护进程 |
管理选项 |
NameNode |
HADOOP_NAMENODE_OPTS |
DataNode |
HADOOP_DATANODE_OPTS |
SecondaryNamenode |
HADOOP_SECONDARYNAMENODE_OPTS |
JobTracker |
HADOOP_JOBTRACKER_OPTS |
TaskTracker |
HADOOP_TASKTRACKER_OPTS |
例如,配置NameNode守护进程使用parallelGC需要在hadoop-env.sh 添加如下的语句:export HADOOP_NAMENODE_OPTS="-XX:+UseParallelGC${HADOOP_NAMENODE_OPTS}"。
其它有用的、可定制的配置参数包括:HADOOP_LOG_DIR,存储守护进程日志的目录,默认为$HADOOP_HOME/logs。HADOOP_HEAPSIZE,堆使用的最大大小,单位为MB,例如1000,该选项用于管理Hadoop守护进程的堆大小,默认大小为1000MB。
接下来看看Hadoop守护进程的配置参数,这些参数主要集中在core-site.xml、hdfs-site.xml、mapred-site.xml中。
首先是core-site.xml,该文件中的重要参数为fs.default.name,值为NameNode的URI。一个URI由两部分组成,分别为scheme和权限,scheme决定了文件系统的实现类,如file对应org.apache.hadoop.fs.LocalFileSystem,hdfs对应org.apache.hadoop.hdfs.DistributedFileSystem,权限指定了文件的主机和端口等,如localhost:9000。完整的例子如:hdfs:// localhost:9000。hdfs-site.xml中的重要参数包括dfs.name.dir和dfs.data.dir,分别指定了NameNode在本地文件系统存储名称表(fsimage)的目录和DataNode在本地文件系统存储块的路径。如果dfs.name.dir的值是以逗号分隔的目录表,则为了冗余,名称表(fsimage)会复制到所有这些目录中。如果dfs.data.dir的值是以逗号分隔的目录表,则数据块会存储到所有目录中,若目录不存在则忽略。它们的默认值分别为${hadoop.tmp.dir}/dfs/name和${hadoop.tmp.dir}/dfs/data,其中${hadoop.tmp.dir}为/tmp/hadoop-${user.name}(该值在core-site.xml中定义)。接下来是mapred-site.xml的重要参数,由于参数较多,将以表格的形式展现:
参数 |
值 |
描述 |
mapred.job.tracker |
JobTracker的主机名或者IP与端口号。 |
Localhost:8020 |
mapred.system.dir |
MapReduce 在HDFS上存储文件系统文件的路径,如hadoop/mapred/system/,默认值为${hadoop.tmp.dir}/mapred/system |
该路径必须能够被服务端和客户端访问 |
mapred.local.dir |
MapReduce在本地文件系统上临时写入数据的目录,多个目录可以用多个逗号分开,默认值为${hadoop.tmp.dir}/mapred/local |
不同设备上的多个目录有助于分散磁盘的i/o 操作。 |
mapred.tasktracker.{map|reduce}.tasks.maximum |
一个TaskTracker 中,map或者reduce 任务可以同时运行的最大数量 |
默认值是2,但可依据硬件条件调整。 |
mapred.hosts |
包含可以连接jobtracker的节点的文件 |
该值若为空,则所有的节点都允许连接jobtracker |
mapred.hosts.exclude |
包含jobtracker拒绝连接的节点的文件 |
若该值为空,则所有节点都不被拒绝。 |
mapred.queue.names |
以逗号分隔的队列名称,作业可以被提交给这些队列。 |
调度器可以为各种队列管理不同的调度属性,为了管理某个队列的属性,队列的名称必须与这里指定的队列名称匹配。队列属性对所有的调度器是通用的,遵循mapred.queue.$QUEUE-NAME.$PROPERTY-NAME命名约定,比如 mapred.queue.default.submit-job-acl。该参数指定的队列的数量依赖于使用的调度器,调度器由 mapred.jobtracker.taskScheduler.指定。比如,JobQueueTaskScheduler 是默认的调度器,仅支持一个队列,而CapacityTaskScheduler支持多个队列。MapReduce 总是至少支持名为default的队列,因此该参数的值应该总是包含default字符串。用户可以向参数mapred.job.queue.name指定的队列提交作业。 |
mapred.acls.enabled |
True或者false,该参数指定是否检查队列的ACLs(访问控制列表)和作业的ACLs,并根据ACLs授权用户进行队列和作业操作。默认值为false。 |
如果为 true,当提交和实施作业时,队列的ACLs和作业的ACLs被检查用于授权作业的查看和修改。队列ACLs在mapred-queue-acls.xml文件中以mapred.queue.queue-name.acl-name 的形式指定。作业ACLs 会在以后进行介绍。 |
上面提到了用于管理队列ACLs的mapred-queue-acls.xml文件,现在就来看看该文件。该文件同样位于${HADOOP_HOME}\conf\目录中,其参数主要有mapred.queue.default.acl-submit-job和mapred.queue.default.acl-administer-jobs。mapred.queue.default.acl-submit-job指定了可以向“default”队列提交作业的用户和组,用户列表和组列表内部用逗号分隔,两个列表之间用空格分隔,例如user1,user2 group1,group2。如果该值设置为*,则所有用户允许提交作业,如果设置为空格,则任何用户都不允许提交作业。只有在mapred.acls.enabled设置为true时该参数的值才会被使用。不考虑ACL管理的话,启动集群的用户和使用mapreduce.cluster.administrators参数管理的集群管理员可以提交作业。
mapred.queue.default.acl-administer-jobs参数值的形式与mapred.queue.default.acl-submit-job相同,指定了可以在 “default”队列中进行查看作业细节、杀死作业或者修改所有作业优先级的用户和组。不考虑ACL管理的话,启动集群的用户和使用mapreduce.cluster.administrators参数管理的集群管理员可以对所有队列中的所有作业执行上述操作,作业拥有者可以对自己的作业执行上述所有操作而不用考虑ACL的配置。
通常所有上述参数均通过<final>true</final>标记为final,这样可以确保它们的值不会被用户程序覆盖。
在介绍了上述的配置文件及重要的配置选项后,来看看实际生产中一些参数的取值。这些参数的值在运行排序基准测试程序的非常大的集群中使用,可以根据这些从经验中得来的值对自己生产环境中的参数值进行调整。
首先是sort900,也就是在900个节点的集群中排序9TB的数据。
配置文件 |
参数 |
值 |
描述 |
hdfs-site.xml |
dfs.block.size |
134217728 |
对于大的文件系统,HDFS的块大小为128MB |
hdfs-site.xml |
dfs.namenode.handler.count |
40 |
NameNode处理来自DataNodes的RPCs的服务线程数量。 |
mapred-site.xml |
mapred.reduce.parallel.copies |
20 |
reduces 运行的并行传送map输出的数量,当map的数量非常大时,需要增大该值。 |
mapred-site.xml |
mapred.map.child.java.opts |
-Xmx512M |
map的子JVM需要更大的堆大小。 |
mapred-site.xml |
mapred.reduce.child.java.opts |
-Xmx512M |
reduce的子JVM需要更大的堆大小。 |
core-site.xml |
fs.inmemory.size.mb |
200 |
reduces 用于合并maps输出的内存大小 |
core-site.xml |
io.sort.factor |
100 |
排序文件时立刻合并的流的数量 |
core-site.xml |
io.sort.mb |
200 |
排序数据时内存的限制 |
core-site.xml |
io.file.buffer.size |
131072 |
SequenceFiles 使用的读写缓冲区的大小。 |
其次是sort1400和sort2000,也就是在1400个节点的集群中排序14TB的数据和在2000个节点的集群中排序20TB的数据,对上述一些参数的值进行了调整。
配置文件 |
参数 |
值 |
描述 |
mapred-site.xml |
mapred.job.tracker.handler.count |
60 |
非常大数量的TaskTrackers 存在时,需要更多的JobTracker 服务线程处理RPCs 。 |
mapred-site.xml |
mapred.reduce.parallel.copies |
50 |
reduces 运行的并行传送map输出的数量,当map的数量非常大时,需要增大该值。 |
mapred-site.xml |
tasktracker.http.threads |
50 |
TaskTracker的http服务器需要更多的线程更多的工作线程。http服务器被reduces 用来提取map输出的中间产物。 |
mapred-site.xml |
mapred.map.child.java.opts |
-Xmx512M |
map的子JVM需要更大的堆大小 |
mapred-site.xml |
mapred.reduce.child.java.opts |
-Xmx1024M |
reduce的子JVM需要更大的堆大小 |