下面的教程把它们合并至 multi-node cluster 。
1. 合并 single-node 至 multi-node cluster
修改 master 的 hadoop/conf/core-site.xml :
<property>
<name>hadoop.tmp.dir</name>
<value>/root/hadoop_tmp/hadoop_${user.name}</value>
</property>
<property>
<name>fs.default.name</name>
<value>hdfs://master :54310</value>
</property>
<property>
<name>io.sort.mb</name>
<value>1024</value>
</property>
修改 conf/mapred-site.xml ,在 <configuration> 节中添加如下内容:
<property>
<name>mapred.job.tracker</name>
<value>master :54311</value>
</property>
<property>
<name>mapred.map.child.java.opts</name>
<value>-Xmx4096m</value>
</property>
<property>
<name>mapred.reduce.child.java.opts</name>
<value>-Xmx4096m</value>
</property>
修改 conf/hdfs -site.xml ,在 <configuration> 节中添加如下内容:
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
把这三个文件复制至 slave1 相应的目录 hadoop/conf 中 ( 即 master 和 slave1 的内容完全一致 )
修改所有节点的 hadoop/conf/masters ,把文件内容改成: master
修改所有节点的 hadoop/conf/slaves ,把文件内容改成:
master
slave1
分别删除 master 和 slave1 的 dfs/data 文件:
rm –rf /root/hadoop_tmp/hadoop_root/dfs/data
重新格式化 namenode :
hadoop/bin/hadoop namenode -format
测试,在 master 上运行:
hadoop/bin/start-all.sh
在 master 上运行 jps 命令
此时输出应类似于:
11648 TaskTracker
11166 NameNode
11433 SecondaryNameNode
12552 Jps
11282 DataNode
11525 JobTracker
在 slave1 上运行 jps
此时输出应包含 ( 即至少有 DataNode, 否则即为出错 ) :
3950 Jps
3121 TaskTracker
3044 DataNode
2. 测试一个 JOB
首先升级 python( 可选,如果 JOB 是 python 写的 ) :
cd /etc/yum.repos.d/
wget http://mirrors.geekymedia.com/centos/geekymedia.repo
yum makecache
yum -y install python26
升级 python 的教程,见另外一篇文档。如果已经通过以上方法安装了 python2.6 ,那需要先卸载:
yum remove python26 python26-devel
CentOS 的 yum 依赖于 python2.4 ,而 /usr/bin 中 python 程序即为 python2.4 。我们需要把它修改成 python2.6 。
cd /usr/bin/
编辑 yum 文件,把第一行的
#!/usr/bin/python à #!/usr/bin/python2.4
保存文件。
删除旧版本的 python 可执行文件(这个文件跟该目录下 python2.4 其实是一样的,所以可以直接删除)
rm -f python
让 python 指向 python2.6 的可执行程序。
ln -s python26 python
3. Word count python 版本
Map.py
#! /usr/bin/python
import sys;
for line in sys.stdin:
line = line.strip();
words = line.split();
for word in words:
print '%s/t%s' % (word,1);
Reduce.py
#!/usr/bin/python
import sys;
wc = {};
for line in sys.stdin:
line = line.strip();
word,count = line.split('/t',1);
try:
count = int(count);
except Error:
pass;
if wc.has_key(word):
wc[word] += count;
else: wc[word] = count;
for key in wc.keys():
print '%s/t%s' % (key, wc[key]);
本机测试:
echo "foo foo bar bar foo abc" | map.py
echo "foo foo bar bar foo abc" | map.py | sort | reduce.py
在 hadoop 中测试:
hadoop jar /usr/local/hadoop/contrib/streaming/hadoop-streaming-0.20.203.0.jar -file mapper.py -mapper mapper.py -file reducer.py -reducer reducer.py -input wc/* -output wc-out
Job 成功后,会在 HDFS 中生成 wc-out 目录。
查看结果:
hadoop fs –ls wc-out
hadoop fs –cat wc-out/part-00000
4. 集群增加新节点
a. 执行步骤 1 , 2.
b. 修改 hosts 文件,将集群中的 hosts 加入本身 /etc/hosts 中。并修改集群中其他节点的 hosts ,将新节点加入。
c. master 的 conf/slaves 文件中,添加新节点。
d. 启动 datanode 和 task tracker 。
hadoop-daemon.sh start datanode
hadoop-daemon.sh start tasktracker
5. Trouble-shooting
hadoop 的日志在 hadoop/logs 中。
其中, logs 根目录包含的是 namenode, datanode, jobtracker, tasktracker 等的日志。分别以 hadoop-{username}-namenode/datanode/jobtracker/tasktracker-hostname.log 命名。
userlogs 目录里包含了具体的 job 日志,每个 job 有一个单独的目录,以 job_YYYYmmddHHmm_xxxx 命名。里面包含数个 attempt_{jobname}_m_xxxxx 或 attempt_{jobname}_r_xxxx 等数个目录。其中目录名中的 m 表示 map 任务的日志, r 表示 reduce 任务的日志。因此,出错时,可以有针对性地查看特定的日志。
常见错误:
1. 出现类似:
ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Incompatible namespaceIDs …
的异常,是因为先格式化了 namenode ,后来又修改了配置导致。将 dfs/data 文件夹内容删除,再重新格式化 namenode 即可。
2. 出现类似:
INFO org.apache.hadoop.ipc.Client: Retrying connect to server:…
的异常,首先确认 name node 是否启动。如果已经启动,有可能是 master 或 slave1 中的配置出错,集群配置参考步骤 11 。也有可能是防火墙问题,需添加以下例外:
50010 端口用于数据传输, 50020 用于 RPC 调用, 50030 是 WEB 版的 JOB 状态监控, 54311 是 job tracker , 54310 是与 master 通信的端口。
完整的端口列表见:
http://www.cloudera.com/blog/2009/08/hadoop-default-ports-quick-reference/
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 50010 -j ACCEPT
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 50020 -j ACCEPT
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 50030 -j ACCEPT
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 50060 -j ACCEPT
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 54310 -j ACCEPT
iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 54311 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 50010 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 50020 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 50010 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 50020 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 50030 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 50030 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 50060 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 50060 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 54310 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 54310 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 54311 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 54311 -j ACCEPT
保存规则:
/etc/init.d/iptables save
重启 iptables 服务:
service iptables restart
如果还是出现问题 2 的错误,那可能需要手工修改 /etc/sysconfig/iptables 的规则。手动添加这些规则。若有 ”reject-with icmp-host-prohibited” 的规则,需将规则加到它的前面。注意修改配置文件的时候,不需要带 iptables 命令。直接为类似于:
-A OUTPUT -p tcp -m tcp --sport 54311 -j ACCEPT
或关闭防火墙 ( 建议,因为端口太多,要加的例外很多 )
service iptables stop
3. 在 /etc/hosts 文件中,确保一个 host 只对应一个 IP ,否则会出错(如同时将 slave1 指向 127.0.0.1 和 192.168.225.66 ),可能导致数据无法从一个节点复制至另一节点。
4. 出现类似:
FATAL org.apache.hadoop.mapred.TaskTracker: Error running child : java.lang.OutOfMemoryError: Java heap space…
的异常,是因为堆内存不够。有以下几个地方可以考虑配置:
a. conf/hadoop-env.sh 中, export HADOOP_HEAPSIZE=1000 这一行,默认为注释掉,堆大小为 1000M ,可以取消注释,将这个值调大一些(对于 16G 的内存,可以调至 8G )。
b. conf/mapred-site.xml 中,添加 mapred.map.child.java.opts 属性,手动指定 JAVA 堆的参数值为 -Xmx2048m 或更大。这个值调整 map 任务的堆大小。即:
<property>
<name>mapred.map.child.java.opts </name>
<value>-Xmx2048m</value>
</property>
c. conf/mapred-site.xml 中,添加 mapred.reduce.child.java.opts 属性,手动指定 JAVA 堆的参数值为 -Xmx2048m 或更大。这个值调整 reduce 任务的堆大小。即:
<property>
<name>mapred.reduce.child.java.opts </name>
<value>-Xmx2048m</value>
</property>
注意调整这些值之后,要重启 name node 。
5. 出现类似: java.io.IOException: File /user/root/pv_product_110124 could only be replicated to 0 nodes, instead of 1…
的异常,首先确保 hadoop 临时文件夹中有足够的空间,空间不够会导致这个错误。
如果空间没问题,那就尝试把临时文件夹中 dfs/data 目录删除,然后重新格式化 name node :
hadoop namenode -format
注意:此命令会删除 hdfs 上的文件
6. 出现类似: java.io.IOException: Broken pipe…
的异常,检查你的程序吧,没准输出了不该输出的信息,如调试信息等。