为了Spark使用HDFS,所以先配置Hadoop集群,系统参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS" NAME="Ubuntu" VERSION="16.04.2 LTS (Xenial Xerus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 16.04.2 LTS" VERSION_ID="16.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" VERSION_CODENAME=xenial UBUNTU_CODENAME=xenial
|
Hadoop版本为官方当前最新的2.7.3:http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
基础准备
配置Java环境
可以参见这里:http://notes.maxwi.com/2016/10/01/java-env-set/
配置SSH免密登录
可以参见这里:http://notes.maxwi.com/2017/03/09/linux-ssh-nopasswd/
配置hosts映射
首先准备三台机器,可以是虚拟机。三台机器根据其ip将分别命名为:
主机名 |
ip |
master |
192.168.1.187 |
slave1 |
192.168.1.188 |
slave2 |
192.168.1.188 |
修改各主机名,主机名文件为:/etc/hostname
,分别将三台主机的名称修改为对应的名称。
修改hosts文件映射,hosts文件路径为/etc/hosts
,修改三台主机的hosts内容为:
1 2 3 4 5
| 127.0.0.1 localhost
192.168.1.187 master 192.168.1.188 slave1 192.168.1.189 slave2
|
注意:一定要删除ubuntu系统自动添加的那行127.0.1.1 master
上面这里是每一台机器都需要进行的配置,也可以配置其中一台的java环境,然后直接克隆后再修改其他内容
然后重启机器,主机名就可以生效了,这里面其实主机名的修改并不是必须的,包括hosts映射也非必须,只是为了后面方便配置,同时也为了避免由于ip变动而需要修改各配置文件。
推荐先根据官方的单节点配置方法走一遍,熟悉一下过程:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html
当然也可以直接看下面的内容。
配置Hadoop
下载并配置hadoop环境变量
这里将hadoop安装在/usr/hadoop目录,下面的操作非特殊说明都是在master上进行操作,为了避免权限问题,在root用户下操作,其实普通用户也是一样的。
下载hadoop 2.7.3
1
| wget http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
|
这里选择的是清华的源,可以根据需要选择
解压并进入到hadoop目录
1 2 3
| tar -zxvf hadoop-2.7.3.tar.gz mv hadoop-2.7.3 /usr/hadoop cd /usr/hadoop
|
将以下环境变量添加到自己的~/.bashrc
或者/etc/profile
中,这里为了方便就直接放到~/.bashrc
:
1 2 3 4 5 6 7 8 9 10 11
| # for Hadoop export HADOOP_HOME=/usr/hadoop PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin CLASSPATH=$CLASSPATH:$HADOOP_HOME/share/hadoop/common/hadoop-common-2.7.3.jar:$HADOOP_HOME/share/hadoop/common/lib/commons-cli-1.2.jar:$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.7.3.jar
export HADOOP_PREFIX=/usr/hadoop export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HADOOP_HOME/lib/native/
PATH=$PATH:$HOME/bin export PATH export CLASSPATH
|
PATH变量中最好不要添加sbin目录,因为会与spark的sbin目录下的脚本冲突,需要启动的时候直接手动到相应目录下启动相应服务
scp到其他机器:
1 2
| scp ~/.bashrc slave1:~ scp ~/.bashrc slave2:~
|
分别在三台机器上执行source使环境变量生效:
如果环境变量配置都没有问题的话,现在已经可以查看到hadoop的版本等信息了:
验证Hadoop单机配置
修改/usr/hadoop
目录下的etc/hadoop/hadoop-env.sh
文件,修改Java路径:
1
| export JAVA_HOME=/usr/lib/jvm/java-8-oracle
|
通过拷贝hadoop的配置文件,并在调用hadoop自带示例中的正则表达式来搜索配置文件,并将结果输出到output:
1 2 3 4
| cd /usr/hadoop cp etc/hadoop/*.xml input hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar grep input output 'dfs[a-z.]+' cat output/*
|
如果执行中没有报错,并且输出如下,则表示hadoop环境变量配置完成:
下面开始配置集群环境
修改Hadoop配置文件
下面的操作都是在hadoop目录之中的etc/hadoop
路径下,即/usr/hadoop/etc/hadoop
,该文件夹存放了hadoop所需要的几乎所有配置文件。
需要修改的配置文件主要有:hadoop-env.sh
, core-site.xml
, hdfs-site.xml
, mapred-site.xml
, yarn-env.sh
, yarn-site.xml
, slaves
hadoop-env.sh
除了上面需要在其中添加JAVA_HOME之外,还需要增加HADOOP_PREFIX变量:
1
| export HADOOP_PREFIX=/usr/hadoop
|
core-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13
| <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://master:9000</value> <description>HDFS的URL,文件系统://namenode标识:端口号</description> </property>
<property> <name>hadoop.tmp.dir</name> <value>/usr/hadoop/tmp</value> <description>namenode上本地的hadoop临时文件夹</description> </property> </configuration>
|
这里指定master为namenode及相应端口号,并设置本地的临时文件夹为hadoop安装目录下的tmp,该目录需要手动创建
hdfs-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <configuration> <property> <name>dfs.name.dir</name> <value>/usr/hadoop/hdfs/name</value> <description>namenode上存储hdfs名字空间元数据</description> </property>
<property> <name>dfs.data.dir</name> <value>/usr/hadoop/hdfs/data</value> <description>datanode上数据块的物理存储位置</description> </property>
<property> <name>dfs.replication</name> <value>3</value> <description>副本个数,配置默认是3,应小于datanode机器数量</description> </property> </configuration>
|
指定namenode和datanode数据的存储位置(需要手动创建),以及副本个数
mapred-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
<property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property>
<property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> </configuration>
|
yarn-env.sh
1 2
| # export JAVA_HOME=/home/y/libexec/jdk1.6.0/ export JAVA_HOME=/usr/lib/jvm/java-8-oracle
|
修改JAVA_HOME
yarn-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <configuration>
<!-- Site specific YARN configuration properties --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
<property> <name>yarn.resourcemanager.hostname</name> <value>master</value> </property>
<property> <name>yarn.resourcemanager.webapp.address</name> <value>master:8099</value> </property>
<property> <name>yarn.resourcemanager.address</name> <value>master:8032</value> </property>
<property> <name>yarn.resourcemanager.scheduler.address</name> <value>master:8030</value> </property>
<property> <name>yarn.resourcemanager.resource-tracker.address</name> <value>master:8031</value> </property> </configuration>
|
指定resourcemanager为master,并修改相应端口,这些端口如果不修改都有默认值,可以根据自己的网络情况进行修改
slaves
master即是namenode,同时也是datanode
创建刚才配置中用到的文件夹:
1
| mkdir -p /usr/hadoop/hdfs/data /usr/hadoop/hdfs/name /usr/hadoop/tmp
|
配置完成之后将该配置复制到slave1和slave2上:
1 2
| scp -r /usr/hadoop slave1:/usr/ scp -r /usr/hadoop slave2:/usr/
|
启动Hadoop集群
启动hdfs
记得其他2个slave上的环境变量都已经生效
在master上格式化namenode:
在master上执行以下命令启动hadoop:
启动完成之后在master上启动jps命令查看其java进程:
1 2 3 4
| 4949 NameNode 5415 Jps 5289 SecondaryNameNode 5102 DataNode
|
查看slave1和slave2上进程:
slave1:
slave2:
找一个能够访问master的浏览器通过50070端口可以查看namenode和datanode情况http://192.168.1.187:50070/dfshealth.html#tab-overview
如果看到Summary中的Live Nodes显示为3,并且Configured Capacity
中显示的DFS总大小刚好为三台机器的可用空间大小,则表示已经配置没有问题
启动yarn
执行以下命令启动yarn:
使用jps查看master及2个slave:
master:
1 2 3 4 5 6
| 5476 ResourceManager 4949 NameNode 5289 SecondaryNameNode 5883 Jps 5102 DataNode 5775 NodeManager
|
slave1:
1 2 3
| 1827 DataNode 1971 NodeManager 2079 Jps
|
slave2:
1 2 3
| 2198 Jps 1950 DataNode 2095 NodeManager
|
根据我们的配置,通过master的端口8099端口可以在web端查看集群的内存、CPU、及任务调度情况http://192.168.1.187:8099/cluster,如果显示的Memory Total
、Active Nodes
等内容与你的实际相符,则表示yarn启动成功
通过各节点的8042端口可以查看各节点的资源情况,如查看slave1的节点信息:http://192.168.1.188:8042
也可以通过以下命令查看hdfs的全局信息:
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| Configured Capacity: 59837042688 (55.73 GB) Present Capacity: 41174982656 (38.35 GB) DFS Remaining: 40219471872 (37.46 GB) DFS Used: 955510784 (911.25 MB) DFS Used%: 2.32% Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 Missing blocks (with replication factor 1): 0
------------------------------------------------- Live datanodes (3):
Name: 192.168.1.188:50010 (slave1) Hostname: slave1 Decommission Status : Normal Configured Capacity: 19945680896 (18.58 GB) DFS Used: 318500864 (303.75 MB) Non DFS Used: 6454030336 (6.01 GB) DFS Remaining: 13173149696 (12.27 GB) DFS Used%: 1.60% DFS Remaining%: 66.05% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Fri Mar 10 00:57:51 CST 2017
Name: 192.168.1.187:50010 (master) Hostname: master Decommission Status : Normal Configured Capacity: 19945680896 (18.58 GB) DFS Used: 318500864 (303.75 MB) Non DFS Used: 6287228928 (5.86 GB) DFS Remaining: 13339951104 (12.42 GB) DFS Used%: 1.60% DFS Remaining%: 66.88% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Fri Mar 10 00:57:51 CST 2017
Name: 192.168.1.189:50010 (slave2) Hostname: slave2 Decommission Status : Normal Configured Capacity: 19945680896 (18.58 GB) DFS Used: 318509056 (303.75 MB) Non DFS Used: 5920800768 (5.51 GB) DFS Remaining: 13706371072 (12.77 GB) DFS Used%: 1.60% DFS Remaining%: 68.72% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Fri Mar 10 00:57:49 CST 2017
|
启动Job History
1
| mr-jobhistory-daemon.sh start historyserver
|
master上的jps进程:
1 2 3 4 5 6 7
| 8720 Jps 7809 DataNode 8628 JobHistoryServer 7656 NameNode 8155 ResourceManager 8285 NodeManager 7999 SecondaryNameNode
|
查看web页面:http://192.168.1.187:19888
至此整个Hadoop集群已经启动成功
Job history并不是必须的
验证HDFS
查看当前hdfs中的文件:
在hdfs上创建一个文件夹:
再次查看:
1 2 3
| root@master:/usr/hadoop# hdfs dfs -ls / Found 1 items drwxr-xr-x - root supergroup 0 2017-03-09 23:44 /test
|
将hadoop目录下的README.txt存储到hdfs上刚刚创建的test文件夹:
1
| hdfs dfs -put README.txt /test
|
查看:
1 2 3
| hdfs dfs -ls /test Found 1 items -rw-r--r-- 3 root supergroup 1366 2017-03-09 23:47 /test/README.txt
|
也可以通过web页面查看刚刚在hdfs上创建的文件:http://192.168.1.187:50070/explorer.html
查看hadoop目录下我们创建的hdfs文件夹name和data中的文件也可以看到其中有了变化,因为我们的副本数为3,所以各节点上应该都会有数据:
master:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| hdfs/ ├── data │ ├── current │ │ ├── BP-109196317-192.168.1.187-1489073016129 │ │ │ ├── current │ │ │ │ ├── finalized │ │ │ │ │ └── subdir0 │ │ │ │ │ └── subdir0 │ │ │ │ │ ├── blk_1073741825 │ │ │ │ │ └── blk_1073741825_1001.meta │ │ │ │ ├── rbw │ │ │ │ └── VERSION │ │ │ ├── scanner.cursor │ │ │ └── tmp │ │ └── VERSION │ └── in_use.lock └── name ├── current │ ├── edits_inprogress_0000000000000000001 │ ├── fsimage_0000000000000000000 │ ├── fsimage_0000000000000000000.md5 │ ├── seen_txid │ └── VERSION └── in_use.lock
11 directories, 12 files
|
2个slave中的文件内容完全一致:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| hdfs/ ├── data │ ├── current │ │ ├── BP-109196317-192.168.1.187-1489073016129 │ │ │ ├── current │ │ │ │ ├── finalized │ │ │ │ │ └── subdir0 │ │ │ │ │ └── subdir0 │ │ │ │ │ ├── blk_1073741825 │ │ │ │ │ └── blk_1073741825_1001.meta │ │ │ │ ├── rbw │ │ │ │ └── VERSION │ │ │ ├── scanner.cursor │ │ │ └── tmp │ │ └── VERSION │ └── in_use.lock └── name
10 directories, 6 files
|
更多HDFS命令参考这里:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/FileSystemShell.html#ls
验证Hadoop集群
使用hadoop自带的一个wordcount程序来验证集群的运行情况
通过hadoop程序目录下的三个文件创建文本:
1
| cat NOTICE.txt LICENSE.txt README.txt >> word.txt
|
为了能够在网页端看到执行进度,可以多执行几次,或者手动上传一个较大的文件,我这里通过vim的p命令,连点了几次,产生了一个60多M的文件后,再将其复制一份word2,然后:
一次增加60M,可以多执行几次,我这里增加到300M
将word.txt上传的hdfs的test目录:
1
| hdfs dfs -put word.txt /test
|
查看hdfs的test目录:
1 2 3 4
| root@slave1:/usr/hadoop# hdfs dfs -ls /test Found 2 items -rw-r--r-- 3 root supergroup 1366 2017-03-09 23:47 /test/README.txt -rw-r--r-- 3 root supergroup 315737315 2017-03-10 00:06 /test/word.txt
|
注意此时我的操作是在slave1中,当hadoop集群配置完成之后,可以在任意通过连通namenode的节点上访问HDFS。
运行hadoop分布式运算,这里为了测试,我们在slave2节点上提交任务:
1
| hadoop jar /usr/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /test /out
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 17/03/10 00:11:15 INFO client.RMProxy: Connecting to ResourceManager at master/192.168.1.187:8032 17/03/10 00:11:15 INFO input.FileInputFormat: Total input paths to process : 2 17/03/10 00:11:16 INFO mapreduce.JobSubmitter: number of splits:4 17/03/10 00:11:16 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1489073635090_0001 17/03/10 00:11:16 INFO impl.YarnClientImpl: Submitted application application_1489073635090_0001 17/03/10 00:11:16 INFO mapreduce.Job: The url to track the job: http://master:8099/proxy/application_1489073635090_0001/ 17/03/10 00:11:16 INFO mapreduce.Job: Running job: job_1489073635090_0001 17/03/10 00:11:23 INFO mapreduce.Job: Job job_1489073635090_0001 running in uber mode : false 17/03/10 00:11:23 INFO mapreduce.Job: map 0% reduce 0% 17/03/10 00:11:31 INFO mapreduce.Job: map 25% reduce 0% 17/03/10 00:11:36 INFO mapreduce.Job: map 41% reduce 0% 17/03/10 00:11:39 INFO mapreduce.Job: map 42% reduce 0% 17/03/10 00:11:42 INFO mapreduce.Job: map 54% reduce 0% 17/03/10 00:11:43 INFO mapreduce.Job: map 54% reduce 8% 17/03/10 00:11:45 INFO mapreduce.Job: map 55% reduce 8% 17/03/10 00:11:46 INFO mapreduce.Job: map 63% reduce 8% 17/03/10 00:11:48 INFO mapreduce.Job: map 68% reduce 8% 17/03/10 00:11:49 INFO mapreduce.Job: map 68% reduce 17% 17/03/10 00:11:51 INFO mapreduce.Job: map 73% reduce 17% 17/03/10 00:11:54 INFO mapreduce.Job: map 78% reduce 17% 17/03/10 00:11:58 INFO mapreduce.Job: map 83% reduce 17% 17/03/10 00:12:01 INFO mapreduce.Job: map 92% reduce 17% 17/03/10 00:12:02 INFO mapreduce.Job: map 100% reduce 100% 17/03/10 00:12:03 INFO mapreduce.Job: Job job_1489073635090_0001 completed successfully
|
可以看到首先连接了ResourceManager,即master节点
现在可以在http://192.168.1.187:8099/cluster通过浏览器查看任务进度,如果你的word.txt文件太小,可能progress已经为100%
查看hdfs上的运行结果:
1
| hdfs dfs -cat /out/part-r-00000
|
输出中会有大量单词的统计,如果都没有报错,则表示Hadoop集群已经配置成功
问题
各节点通过jps命令查看运行正常,但网页端显示Live Nodes并不是3
确保hosts中没有将自己的hostname映射到127.0.0.1或127.0.1.1,并且防火墙设置没有问题
50070端口的web无法访问
有可能是格式化namenode之后,hdfs目录下的文件依然存在,可以删除之前创建的namenode和datanode物理存储位置以及tmp文件夹,然后重新创建,并重新格式化namenode之后再执行,记得其他各节点也需要删除相应的目录并重新创建
配置文件放在单独的文件夹
为了便于修改配置文件之后进行不同节点之间的同步,可以将配置文件放在单独的用户文件夹下,然后通过以下环境变量指定配置文件路径即可:
1
| export HADOOP_CONF_DIR=/home/user/conf
|
注意:最好将hadoop根据目录下的配置文件夹下的所有文件都拷贝进去,至少根据我们上面的配置文件需要有capacity-scheduler.xml,否则将导致ResourceManager无法启动
重要的几个环境变量
export HADOOP_CONF_DIR=/home/user/conf
用于指定Hadoop配置文件夹
export HADOOP_USER_NAME=root
指定当前shell访问HDFS的用户名,以免权限不足
HADOOP_PATH=hdfs://127.0.0.1:8020/user/root
指定Hadoop访问路径
参考
1.Hadoop Cluster Setup
2.Connection Refused
3.Hadoop: Setting up a Single Node Cluster
4.Hadoop Commands Guide
5.HDFS Commands Guide
6.FileSystemShell