前言
本文不打算介绍除了Hadoop安装相关外的任何知识,旨在快速引导已经阅读了相关介绍的你,运行起Hadoop版本的"HelloWorld"。
阅读此文,确定的硬件配置为:
- Windows
- VMware
- Linux镜像(Redhat等)
- Hadoop-0.20.2
- JDK1.7 for Linux
Hadoop从三个角度把机器划分为两种角色。
- Master与Slave。这是说得机器在职能上的主从关系,较为抽象,适当理解。
- NameNode与DataNode。这是从HDFS的角度上划分的,NameNode管理DataNode的相关信息,DataNode负责存储、维护数据。
- JobTracker与TastTracker。这是从MapReduce角度划分的,一个Job可以被"拆分"为多个Task;其中JobTracker负责调度任务,TaskTracker负责执行。
Hadoop有三种运行方式:
- 完全分布式。NameNode和DataNode完全由不同机器担任。
- 伪分布式。此文所采用的方式;除了硬件要求低,配置简单外,程序运行方式和完全分布式没有太大差别,非常适用于开发。
- 单节点。不需要配置,将Hadoop作为一个单独的java进程。Hadoop的Eclipse插件默认的运行方式。同样非常适用于开发。
开始安装:
在VMware上安装Linux
安装步骤略,要求:
- 用户名必须为hadoop(其实不必这样,但是刚接触新东西的时候,多一事不如少一事。)
- 将这个虚拟系统和你电脑的网络关系设置为:桥接(Bridged)
给用户"hadoop"指派ROOT权限
日后的所有任务都将由hadoop用户完成,所以我们应该给hadoop指派ROOT权限。
我采用的直接修改/etc/sudoer和password文件。参考(http://jingyan.baidu.com/article/6525d4b11baf2fac7d2e94a1.html)
命令(推荐): usermod –g root Hadoop
指定IP信息
打开/etc/sysconfig/network-script/ifcfg-eth0,添加如下信息:
ipaddr=192.100.212 #设ip地址
netmask=255.255.255.0 #设掩码
network=192.100.1.1 #设网络(不设也可以)
gateway=192.100.1.1 #网关
附上一张我修改过的配置:注意UUID和HWADDR地址不要更改,默认就好。
在新安装的Linux上安装JDK
下载Linux版本的JDK1.7。
拷贝到Linux里。下图是一个快捷方式,大家可以尝试下。以后本文都是基于此方式的。
首先赋予这个文件夹最宽容的权限(任何人都可以操作,777)
cd /mnt/hgfs/
chmod -R 777 PublicData
现在,安装JDK
cd /mnt/hgfs/PublicData
rpm –ivh jdk-7u51-linux-x64.rpm
完成之后:
Java –version
看到版本信息即为安装成功。你可以使用javac和java命令试一试。
安装并配置Hadoop
1,在Windows系统中,将Hadoop发行包解压到共享的那个目录:tar –xvf Hadoop-0.20.2.tar.gz
2,将解压后的hadoop目录复制到你的主目录下:cp –R Hadoop-0.20.2 ~/ (以后~/Hadoop-0.20.2就是hadoop的安装目录了).
3,在和hadoop同级的目录下新建一个hadoop-data目录:mkdir ~/Hadoop-data
4,更改hadoop的默认设置,使之运行在伪分布式环境下:
4.1,进入hadoop安装目录下的conf文件夹: cd ~/Hadoop-0.20.2/conf
4.2,修改core-site.xml,增加如下属性:
<property><name>fds.permissions</name><value>false</value></property>
<property><name>fs.default.name</name><value>hdfs://hadoop:9000</value></property>
<property><name>dfs.name.dir</name><value>/home/hadoop/hadoop-data/name</value> </property>
<property><name>dfs.data.dir</name><value>/home/hadoop/hadoop-data/data</value></property>
<property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/hadoop-data/temp</value> </property>
4.3,修改hdfs.site.xml,增加如下属性:
<property><name>dfs.permissions</name><value>false</value></property>
<property><name>dfs.replication</name><value>1</value></property>
4.4修改mapper.site.xml,增加如下属性:
<property><name>mapred.job.tracker</name><value>hadoop:9001</value></property>
4.5修改hadoop-env.sh,增加如下内容:
# The java implementation to use. Required.
export JAVA_HOME=/usr/java/jdk1.7.0_51
# Extra Java CLASSPATH elements. Optional.
export HADOOP_CLASSPATH=.
# The maximum amount of heap to use, in MB. Default is 1000.
export HADOOP_HEAPSIZE=1024
4.6修改/etc/hosts文件,添加:192.100.1.211 hadoop hadoop到第一行。
4.7安装SSH
这一步虽然是可选的,但这是日后许多Hadoop子项目运行的必备要素。
cd ~/.ssh
ssh-keygen -t rsa
cp id_rsa.pub authorized_keys
完成之后使用 ssh localhost试试看能不能免密码登录,如果不能,自行使用"Hadoop SSH"为关键字Google。
小结:上面的红色hadoop,就是本Linux系统的名称,IP是LinuxIP
初始化、启动Hadoop
进入Hadoop的安装目录,开始初始化Hadoop。
cd ~/Hadoop-0.20.2
bin/hadoop namenode –format
bin/start-all.sh
命令运行完成之后,访问:http://192.100.1.211:50030/jobtracker.jsp,如果有网页出现,证明环境搭建完成。
如果没有,请检查Hadoop安装目录下logs里面的日志文件,百度之,慢慢排查。但是如果你按照上面的步骤,完整不落地走下来,是没问题的。
总结:不要多次执行bin/hadoop namenode –format,如果确实有需要,请先删除hadoop-data文件夹,再建立,再格式化。
运行WordCount
WordCount是Hadoop里面的HelloWorld。下面我们来运行它。
1,进入到Hadoop的安装目录:cd ~/Hadoop-0.20.2
2,在HDFS中创建一个用于存放WordCount所使用的那些文本数据:bin/hadoop fs -mkdir ~/hadoop-data/input
3,往新建那个HDFS文件夹里面塞几(1)个文本文件:
echo "hello hadoop ,see you world" >> /tmp/file1.txt(看了这个,还有人敢学Hadoop么?)
bin/hadoop fs -put /tmp/file1.txt ~/hadoop-data/input
4,运行jar包:bin/hadoop jar ~/hadoop-0.20.2/hadoop-0.20.2-examples.jar wordcount~/hadoop-data/input~/hadoop-data/output
加黑的两个分别表示输入路径和输出路径。另外Hadoop要求每次输出之前,输出文件夹是不存在的。如果我们在本次运行之前已经有过运行经历(不管成功失败),则需要删除输出文件夹:bin/hadoop fs –rm ~/hadoop-data/output
下面是运行本次Job后的结果:
5,查看字数统计结果:bin/hadoop fs -cat ~/hadoop-data/output/*
OK,恭喜你!
在Eclipse3.7(indigo)上编写运行Hadoop程序
每一个苦逼的程序猿,上辈子都是折了翼的天使。下面是Eclipse中配置并运行MapReduce程序的步骤。
准备材料
- Eclipse3.7(运行于Windows下即可)
- 如下路径中的jar包:hadoop-0.20.2\contrib\eclipse-plugin\hadoop-0.20.2-eclipse-plugin.jar
配置插件
1,复制上面的这个Hadoop为Eclipse提供的插件到Eclipse安装目录下的plugins文件夹里,重启Eclipse。
2,windons->show view->other->map/reduce locations
3,new一发~~~
4,填写相关配置(Linux的ip可以用"hadoop"代替):
这一步完成之后,在Eclipse的项目容器里面应该有如下信息了:
如果没有,请做如下操作:
- 关闭linux防火墙
- 修改Windows的用户名为hadoop
- 其他情况请自行谷歌。
编写并运行第一个MapReduce程序
在Eclipse中新建一个map/reduce project,叫做WordCount
添加package并新建一个类,例如:
复制如下代码:
package org.xiaom.hadoop.demo; import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; import org.apache.hadoop.util.Tool; publicclass WordCount implements Tool { private Configuration conf; publicstaticclass TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>// 前两个表述输入的Key和Value,后两个表示输出的Key和Value { privatefinalstatic IntWritable one = new IntWritable(1); private Text word = new Text(); publicvoid map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); String sub_str; while (itr.hasMoreTokens()) { sub_str = itr.nextToken(); word.set(sub_str); context.write(word, one); } } } publicstaticclass IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); publicvoid reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } publicstaticvoid main(String[] args) throws Exception { System.exit(new WordCount().run(args)); } @Override public Configuration getConf() { if (this.conf == null) { this.conf = new Configuration(); } returnconf; } @Override publicvoid setConf(Configuration arg0) { this.conf = arg0; } @Override publicint run(String[] arg0) throws Exception { Job job = new Job(getConf()); job.setJobName("WordCountJob001"); job.setJarByClass(WordCount.class); FileInputFormat.setInputPaths(job, new Path(arg0[0])); FileOutputFormat.setOutputPath(job, new Path(arg0[1])); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); return job.waitForCompletion(true) ? 0 : 1; } }
添加运行参数:右击WordCount,run as->run configuration。添加如下参数:
如同先前一样,需要删除output文件夹:
刷新DFS Location
运行:这回直接将WordCount Run as JavaApplication!
完成之后,刷新DFS,在output文件夹中查看结果。