blueyi's notes

Follow Excellence,Success will chase you!

0%

Ubuntu 16.04下配置Hadoop 2.7.3集群

为了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使环境变量生效:

1
source ~/.bashrc

如果环境变量配置都没有问题的话,现在已经可以查看到hadoop的版本等信息了:

1
hadoop version

验证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环境变量配置完成:

1
1	dfsadmin

下面开始配置集群环境

修改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

1
2
3
master
slave1
slave2

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:

1
hdfs namenode -format

在master上执行以下命令启动hadoop:

1
start-dfs.sh

启动完成之后在master上启动jps命令查看其java进程:

1
2
3
4
4949 NameNode
5415 Jps
5289 SecondaryNameNode
5102 DataNode

查看slave1和slave2上进程:
slave1:

1
2
1827 DataNode
1903 Jps

slave2:

1
2
2024 Jps
1950 DataNode

找一个能够访问master的浏览器通过50070端口可以查看namenode和datanode情况http://192.168.1.187:50070/dfshealth.html#tab-overview
如果看到Summary中的Live Nodes显示为3,并且Configured Capacity中显示的DFS总大小刚好为三台机器的可用空间大小,则表示已经配置没有问题

启动yarn

执行以下命令启动yarn:

1
start-yarn.sh

使用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 TotalActive Nodes等内容与你的实际相符,则表示yarn启动成功
通过各节点的8042端口可以查看各节点的资源情况,如查看slave1的节点信息:http://192.168.1.188:8042

也可以通过以下命令查看hdfs的全局信息:

1
hdfs dfsadmin -report

输出:

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中的文件:

1
hdfs dfs -ls /

在hdfs上创建一个文件夹:

1
hdfs dfs -mkdir /test

再次查看:

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,然后:

1
cat word2 >> word.txt

一次增加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

Welcome to my other publishing channels