学习Hadoop首先要安装环境,可以在笔记本或台式机上安装虚拟机搭建分布式测试环境。VM虚拟机占用资源多,而docker可以像VM一样创建虚拟机,但占用资源少,单机也能实现多机分布式环境。
之前,写过一篇docker实现HDFS,包括创建docker image、Volume、entry_point.sh等细节。但随着对HDFS的理解,发现那篇文章中有关docker持久化、免密码登录等设置都是多余的,而这篇文章尽力简化docker配置,内容还包括搭建HDFS系统、演示求pi的MapReduce程序、YARN web演示和mapred收集日志。
1. build docker 镜像
(1)在mac 系统下,安装Docker Toolbox,参考以下官方网址。
https://docs.docker.com/toolbox/toolbox_install_mac/
安装好Toolbox后,同时会安装Kitematic软件,这是一个轻量级的docker管理工具。
抱歉没有安装过程,安装成功后启动,界面如图。
在Kitematic界面中,点击左下角的'Docker CLI'按钮,可以打开一个命令行工具(我的电脑安装了Iterm,默认打开Iterm),在打开的iterm中可以执行docker命令。
docker shell
通过Dockfile构建虚拟机
在一个空的目录下创建Dockerfile文件,构造一个Ubuntu 16.04系统镜像。 cd到这个目录,执行下面的命令。命令执行完毕可以在Kitematic中查看结果,如上图在MyImages中多出一个wsn/base镜像。
注:先启动DockerCLI,在这个CLI中才能执行docker命令。
## DockerCLI
docker build -t wsn/base .
保存文件名为Dockerfile(在这里粘源码,大家可以拿过去用):
FROM ubuntu:16.04
MAINTAINER wsn
RUN apt-get update
RUN apt-get install -y openjdk-8-jdk
RUN apt-get install -y vim
RUN apt install -y net-tools
RUN apt install -y iputils-ping
RUN echo 'root:root' |chpasswd
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
ENV JRE_HOME /usr/lib/jvm/java-8-openjdk-amd64/jre
ENV PATH /usr/lib/jvm/java-8-openjdk-amd64/bin:$PATH
ENV CLASSPATH ./:/usr/lib/jvm/java-8-openjdk-amd64/lib:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib
2.为docker虚拟机创建网络
## docker cli
docker network create --subnet=172.18.0.0/16 hadoopnet
如果mac系统版本在10.13 以上,还会遇到创建网卡失败的问题,要注意关闭系统安全特性设置。
sudo spctl --master-disable
感谢作者@ 仰望神的光,《macOS 10.13 安装Virtualbox失败,https://blog.csdn.net/u013247765/article/details/78176079
在主机中添加路由(不用DockerCli,mac的shell命令)
## mac shell
sudo route -n add 172.18.0.0/24 192.168.99.100
3. 创建第一个docker虚拟机
设置主机名为master、域名也为master。
## DockerCLI
docker run --name master --hostname master --network hadoopnet --ip 172.18.0.81 -d -it wsn/base /bin/bash
可以在Kitematic中看到,多出一个虚拟机(重启一下Kitematic)。也可以在dockerCLI中运行docker ps
查看虚拟机。
docker 操作虚拟机的命令有启动、停止、重启docker start/stop/restart
。也可以直接在Kitematic中对操作虚拟机。docker stop和VM中关机的效果是一样的。
4.拷贝hadoop安装文件到虚拟机
docker cp /Users/wangsen/hadoop/hadoop-2.7.3.tar.gz master:/opt
将宿主机的tar包防在master虚拟机的/opt目录。
5. 获取虚拟机Shell
获取master虚拟机的shell,在docker CLI 中运行下面的命令,获取master的shell。后面的shell操作都是虚拟机中的操作,如果需要拷贝文件到虚拟机中,可以参考4拷贝文件。
## docker cli
docker exec -it master /bin/bash
6. 配置HDFS系统
(1) core-site.xml(/opt/hadoop-2.7.3/etc/hadoop/core-site.xml),配置默认文件系统。
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
</configuration>
(2) hdfs-site.xml(/opt/hadoop-2.7.3/etc/hadoop/hdfs-site.xml),配置hdfs。
<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/data/namedir</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/data/datadir</value>
</property>
</configuration>
name.dir:namenode节点存放文件的位置。(包括fsimage和editlog,fsimage包含命名空间文件目录树,节点和block对应的关系。在namenode内存中,还包含了block和节点对应信息,但这部分不会持久化到内存。)
data.dir:datanode保存block的路径。
(3) 格式化namenode节点
## 创建name.dir data.dir的根路径
mkdir /data
## format namenode
bin/hadoop namenode -format
(4) 启动hdfs
sbin/hadoop-daemon.sh start namenode
sbin/hadoop-daemon.sh start datanode
(5) Web UI查看HDFS
修改本地hosts,方便查看,添加 master 172.26.0.81
。
在浏览器中输入 http://master:50070
(6) 上传文件到HDFS
bin/hdfs dfs -mkdir /jianshu
bin/hdfs dfs -put /opt/hadoop-2.7.3/README.txt /jianshu
bin/hdfs dfs -cat /jianshu/README.txtt
测试文件上传和读取
7.配置YARN
(1) 修改yarn-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:18040</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:18030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:18025</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>master:18141</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>master:18088</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
</configuration>
(2) 修改mapred.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>/user/history/done</value>
</property>
<property>
<name>mapreduce.jobhistory.intermediate-done-dir</name>
<value>/user/history/done_intermediate</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>
(3) 启动服务
sbin/yarn-daemon.sh start resourcemanager
sbin/yarn-daemon.sh start nodemanager
sbin/mr-jobhistory-daemon.sh start historyserver
可以用jps命令查看进程。用web ui查看yarn集群情况,可以查看节点和作业情况。
yarn集群
(4) 提交mapreduce作业
hadoop安装包中,包含示例jar,可以通过hadoop jar 提交 mapreduce作业。
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar \
pi 100 10000
控制台输出结果
第一阶段,Wrote input for Map 0~99
Number of Maps = 100
Samples per Map = 10000
Wrote input for Map #0
Wrote input for Map #1
Wrote input for Map #2
...
Wrote input for Map #99
执行mapreduce任务0~99
18/11/05 23:21:29 INFO client.RMProxy: Connecting to ResourceManager at master/172.18.0.81:18040
18/11/05 23:21:30 INFO input.FileInputFormat: Total input paths to process : 100
18/11/05 23:21:30 INFO mapreduce.JobSubmitter: number of splits:100
18/11/05 23:21:31 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1541459403717_0001
18/11/05 23:21:32 INFO impl.YarnClientImpl: Submitted application application_1541459403717_0001
18/11/05 23:21:32 INFO mapreduce.Job: The url to track the job: http://master:18088/proxy/application_1541459403717_0001/
18/11/05 23:21:32 INFO mapreduce.Job: Running job: job_1541459403717_0001
18/11/05 23:21:44 INFO mapreduce.Job: Job job_1541459403717_0001 running in uber mode : false
18/11/05 23:21:44 INFO mapreduce.Job: map 0% reduce 0%
18/11/05 23:22:12 INFO mapreduce.Job: map 4% reduce 0%
18/11/05 23:22:13 INFO mapreduce.Job: map 6% reduce 0%
...
执行完毕输出结果
18/11/05 23:28:36 INFO mapreduce.Job: map 100% reduce 33%
18/11/05 23:28:37 INFO mapreduce.Job: map 100% reduce 100%
18/11/05 23:28:37 INFO mapreduce.Job: Job job_1541459403717_0001 completed successfully
18/11/05 23:28:37 INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=2206
FILE: Number of bytes written=11990913
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=26090
HDFS: Number of bytes written=215
HDFS: Number of read operations=403
HDFS: Number of large read operations=0
HDFS: Number of write operations=3
Job Counters
Launched map tasks=100
Launched reduce tasks=1
Data-local map tasks=100
Total time spent by all maps in occupied slots (ms)=2013035
Total time spent by all reduces in occupied slots (ms)=327678
Total time spent by all map tasks (ms)=2013035
Total time spent by all reduce tasks (ms)=327678
Total vcore-milliseconds taken by all map tasks=2013035
Total vcore-milliseconds taken by all reduce tasks=327678
Total megabyte-milliseconds taken by all map tasks=2061347840
Total megabyte-milliseconds taken by all reduce tasks=335542272
Map-Reduce Framework
Map input records=100
Map output records=200
Map output bytes=1800
Map output materialized bytes=2800
Input split bytes=14290
Combine input records=0
Combine output records=0
Reduce input groups=2
Reduce shuffle bytes=2800
Reduce input records=200
Reduce output records=0
Spilled Records=400
Shuffled Maps =100
Failed Shuffles=0
Merged Map outputs=100
GC time elapsed (ms)=30536
CPU time spent (ms)=38390
Physical memory (bytes) snapshot=20298399744
Virtual memory (bytes) snapshot=194468679680
Total committed heap usage (bytes)=13775880192
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=11800
File Output Format Counters
Bytes Written=97
Job Finished in 427.752 seconds
Estimated value of Pi is 3.14155200000000000000
(5) yarn web ui查看信息
打开 http://master:18088。(在配置文件yarn-site.xml,yarn.resourcemanager.webapp.address中配置url)
左边菜单栏可以选择Nodes或者Application,Application标签页可以看到提交了2个任务。
job_1541459403717_0001
是我们提交的任务,可以对应上一节console的输出。查看job信息
点击History查看信息
mapreduce日志
从日志信息中可以看到:shuffle过程最耗时,共启动了100个map任务,1个reduce任务。
6. 添加节点实现分布式
创建节点
#docker cli
docker run --name node1 --hostname node1 --network hadoopnet --ip 172.18.0.82 -d -it wsn/base /bin/bash
拷贝hadoop文件
docker cp /Users/wangsen/hadoop/hadoop-2.7.3.tar.gz node1:/opt
获取node1 shell
docker exec -it node1 /bin/bash
导出master 中的配置文件etc文件中全部内容,拷贝到node1:/opt/hadoop-2.7.3/etc/hadoop目录中。
docker cp master:/opt/hadoop-2.7.3/etc/hadoop ~/backetc
docker cp ~/backetc/hadoop/ node1:/opt/hadoop-2.7.3/etc
启动datanode
sbin/hadoop-deamon.sh start datanode
通过web ui查看datanode
Web ui 查看添加的datanode
上传文件NOTICE.txt到hdfs,通过Web UI查看信息,看到NOTICE.txt文件保存在node1和master两个节点上:
文件信息
7. 添加nodemanager
在node1中执行下面的命令
sbin/yarn-daemon.sh start nodemanager
2个node节点
提交pi任务:
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar \
pi 100 10000
2个Nodemanager
注:从结果看有4个map任务failed,可以通过日志进行检查。而且2个节点比1个节点的运行时间更长,可能是系统Memory资源不足,反复调入调出内存。
总结
用docker搭建学习环境比较方便,docker系统内置了DNS服务,设置好docker虚拟机的name,可以自动实现域名解析。
在配置hdfs的时候,通常要配置证书和免密码登录,当namenode要启动datanode节点上进程的时候才需要。如果手动配置启动,datanode主动连接namenode。
本文用hadoop jar运行了mapreduce任务,jar包含在hadoop 实例程序中,演示了yarn web ui使用。
本文希望读者可以按照步骤自己实现环境的搭建,如果遇到HDFS搭建环境问题,请留言一起讨论。
网友评论