目标是在3台虚拟机上搭建一个Hadoop完全分布式集群。
集群规划如下:
? |
192.168.56.107 |
192.168.56.108 |
192.168.56.109 |
HDFS |
NameNode |
SecondaryNameNode |
|
YARN |
|
|
ResourceManager |
?
?
刚创建好的虚拟机默认不能ssh登陆,通过如下命令设置:
# 安装openssh $ sudo apt-get install openssh-server openssh-client # 启动 $ service ssh start
在mac上可以ssh登陆3台虚拟机,但是需要密码
注意:
这个时候使用iTerm工具,可以在mac上同步分发命令到多个会话,效果如下:
我们后续的命令默认都是操作三个节点,如果需要只在一个节点执行的命令,会单独说明
?
刚创建好的系统默认安装的是vim tiny版本,按键与显示不符,解决办法如下:
# Ubuntu预装的是vim tiny版本,需要删除后安装完整版 $ sudo apt-get remove vim-common $ sudo apt-get install vim
?
# 因为我是下载到mac上了,因此需要上传java到ubuntu $ scp mouse@192.168.1.12:/Users/mouse/Downloads/jdk-8u291-linux-x64.tar.gz /home/mouse/java
配置Java环境
$ vi ~/.bash_profile
加入如下2行代码
export JAVA_HOME=/home/mouse/java/jdk1.8.0_291 export PATH=$PATH:$JAVA_HOME/bin
使得代码生效,需要source一下
$ source ~/.bash_profile
验证java
$ java -version
?
ubuntu可以在"设置"->"共享"里更改主机名hostname
这三台虚拟机分别命名为
此外,在配置下host
# 修改hosts文件 $ vi /etc/hosts
加入如下内容
192.168.56.107 master 192.168.56.108 slave1 192.168.56.109 slave2
生成文件
$ ssh-keygen -t rsa -P ‘‘ -f ~/.ssh/id_rsa
复制到其他节点
$ ssh-copy-id -i master $ ssh-copy-id -i slave1 $ ssh-copy-id -i slave2
?
Hadoop有4个包含所有配置的配置文件,分别是:
但有一些配置是需要我们设置的,这4个文件如下:
?
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://master:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/mouse/hadoop/log/hadoop_dir</value> </property> </configuration>
<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/home/mouse/hadoop/log/hadoop_dir/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/mouse/hadoop/log/hadoop_dir/dfs/data</value> </property> <property> <name>dfs.namenode.http-address</name> <value>master:9870</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>slave1:9868</value> </property> </configuration>
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>slave2</value> </property> <!-- 命令行执行hadoop classpath得到的值--> <property> <name>yarn.application.classpath</name> <value>$hadoop classpath</value> </property> </configuration>
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
export JAVA_HOME=/home/mouse/java/jdk1.8.0_291
master slave1 slave2
首次启动需要格式化namenode(注意:只在namenode服务器执行)
$ hadoop namenode -format
# 在namenode服务器执行 $ start-dfs.sh # 在resourcemanager服务器执行 $ start-yarn.sh
停止
# 在namenode服务器执行 $ stop-yarn.sh # 在resourcemanager服务器执行 $ stop-dfs.sh
快捷命令(不推荐)
$ start-all.sh $ stop-all.sh
$ jps
结果如下图,说明全部启动成功了,符合预期
?
# NameNode http://master:9870 # ResourceManager http://slave2:8042
?
只在namenode节点上执行
# /home/mouse/test.txt是本地路径 /是hdfs路径 $ hadoop dfs -put /home/mouse/test.txt /
访问http://master:9870/查看我们上传的文件,可以发现有3个副本,分别位于三个节点:
?
程序很简单,代码如下:
public class WordCount { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { if (args.length != 2) { System.err.println("Usage: WordCount <input path> <output path>"); System.exit(-1); } //指定作业执行规范 控制整个作业的运行 Job job = new Job(); job.setJarByClass(WordCount.class); job.setJobName("Word Count"); //输入数据的路径 FileInputFormat.addInputPath(job, new Path(args[0])); //输出数据的路径 必须不存在 FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); System.exit(job.waitForCompletion(true) ? 0 : 1); } static class WordCountMapper extends Mapper<LongWritable, Text, Text, LongWritable> { @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] words = line.split(","); for (String w : words) { context.write(new Text(w), new LongWritable(1)); } } } static class WordCountReducer extends Reducer<Text, LongWritable, Text, LongWritable> { @Override protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException { long counter = 0; for (LongWritable l : values) { counter += l.get(); } context.write(key, new LongWritable(counter)); } } }
使用IDEA工具
打包设置,参考如下截图:
配置完成后,在"Build"->"Build Artifacts"即可
?
上传jar包
# 上传jar包 $ hdfs dfs -put [jar path] /
执行
# 必须使用全路径类名 # 输出目录必须不存在 $ hadoop jar word-count.jar com.mouse.word.count.WordCount /test.txt /user/mouse/wordcount
?
Done~
?
https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/ClusterSetup.html
?
原文:https://blog.51cto.com/u_15323863/3289655