基于docker的hadoop集群搭建

Posted 小何又沐风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于docker的hadoop集群搭建相关的知识,希望对你有一定的参考价值。

最近想学习如何使用hdfs来存储文件,在网上学习了一下,明确了HDFS(Hadoop Distribute File System 分布式存储)、mapReduce(分布式计算)、YARN(Yet Another Resource Negotiator资源管理)是hadoop的三大组成部分,要想使用hdfs,必须搭建hadoop集群,为此展开了近一个星期的摸索。
网上的教程有很多,但很多都写的不全,自己也是一直踩坑,无奈之下只好对着官方文档一个个看,逐渐理解并明确了部署方法,在经过反复测试确保正常之后,决定在此记录一下,以便与大家交流分享。

1、集群规划

1.1 hadoop版本

hadoop版本不同,配置的内容也不同,本文使用的是hadopp-3.3.2,同样适用3的其他版本,安装包链接见2.1节

1.2 节点数量

只为测试学习,节点不用太多,计划使用3个节点,即构建3个docker容器,1个namenode节点,2个datanode节点,其中1个datanode作为second namenode

1.3 hostname与ip

hadoop集群要求节点具有固定的hostname和ip,在此做如下规划:
namenode的hostname为master,ip为192.168.0.10
第1个datanode的hostname为slave1,ip为192.168.0.11
第2个datanode的hostname为slave2,ip为192.168.0.12

1.4 端口

hadoop集群提供了网页管理界面,主要包括hdfs(文件系统)、cluster(集群)、jobhistory(历史任务)三大部分,每个部分都有访问的端口号。通过查阅官方文档确认了默认的端口号分别为9870、8088、19888,我们直接使用这些默认的端口号

2、hadoop镜像构建

2.1 安装包

hadoop-3.3.2.tar.gz
jdk-8u321-linux-x64.tar.gz hadoop需要java的环境,此包下载需要oracle账号,没有账号的可以免费注册,如果有使用M1 MacOS系统的请下载aarch64版本的

2.2 Dockerfile

构建镜像我们使用Dockerfile,注意这个文件的内容大家可以根据自己的情况修改,如
镜像源:使用centos7,大家可以换
LABEL:元数据这里列了作者和日期,大家可以改成自己的信息
ssh:用于节点直接相互访问用
which:hadoop命令执行需要which,不然会报错
jdk:不是8u321版本的,可以修改下面这两行中的版本信息

ADD jdk-8u321-linux-x64.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_321 /usr/local/jdk1.8

hadoop:不是3.3.2版本的,可以修改下面这两行中的版本信息

ADD hadoop-3.3.2.tar.gz /usr/local
RUN mv /usr/local/hadoop-3.3.2 /usr/local/hadoop

下面是完整的文件内容

# 镜像源
FROM centos:7

# 添加元数据  
LABEL author="hjq" date="2022/03/05"

# 安装openssh-server和sudo软件包,并且将sshd的UsePAM参数设置成no
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config

# 安装openssh-clients
RUN yum install -y openssh-clients

# 安装which
RUN yum install -y which

# 添加测试用户root,密码root,并且将此用户添加到sudoers里
RUN echo "root:root" | chpasswd
RUN echo "root ALL=(ALL) ALL" >> /etc/sudoers
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

# 启动sshd服务并且暴露22端口
RUN mkdir /var/run/sshd
EXPOSE 22

# 拷贝并解压jdk,根据自己的版本修改
ADD jdk-8u321-linux-x64.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_321 /usr/local/jdk1.8
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $JAVA_HOME/bin:$PATH

# 拷贝并解压hadoop,根据自己的版本修改
ADD hadoop-3.3.2.tar.gz /usr/local
RUN mv /usr/local/hadoop-3.3.2 /usr/local/hadoop
ENV HADOOP_HOME /usr/local/hadoop
ENV PATH $HADOOP_HOME/bin:$PATH

# 设置容器启动命令
CMD ["/usr/sbin/sshd", "-D"]

2.3 构建

在本地新建一个自定义名称的文件夹,将上述的Dockerfile、hadoop-3.3.2.tar.gz、jdk-8u321-linux-x64.tar.gz拷贝到该文件夹下,然后使用终端进入该目录,并运行docker build -t hadoop-test .别忘了后面的.

等待运行结束,包含ssh、jdk、hadoop的镜像就构建完成了

3、hadoop镜像配置

我们先用上述构建好的镜像运行一个测试容器,在此容器中配置好参数后,保存为新的镜像,这样以后构建node容器就不用重新配置了

  1. 构建容器 docker run -d --name hadoop-test hadoop-test
  2. 进入容器 docker exec -it hadoop-test bash
  3. 进入hadoop配置目录 cd /usr/local/hadoop/etc/hadoop/
  4. 配置hadoop环境变量 vi hadoop-env.sh
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
export JAVA_HOME=/usr/local/jdk1.8
  1. 配置核心参数 vi core-site.xml
    io.file.buffer.size:文件缓冲区大小,默认为4096(4MB),可以按需修改
    fs.trash.interval:清理回收站的间隔,单位为分钟,默认为0,表示hdfs里删除的文件不会进入回收站,而是直接删除,可以按需修改
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>file:/usr/local/hadoop/tmp</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131702</value>
    </property>
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>
</configuration>
  1. 配置hdfs vi hdfs-site.xml
    dfs.namenode.name.dir:namenode存储表信息的路径
    dfs.datanode.data.dir:datanode存储实际文件数据块的路径
    dfs.replication:文件副本个数,不超过datanode的个数
    dfs.namenode.secondary.http-address:secondary namenode服务网址,端口号默认为9868,可按需修改
<configuration>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/usr/local/hadoop/hdfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/usr/local/hadoop/hdfs/data</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>master:9001</value>
    </property>
</configuration>
  1. 配置资源管理 vi yarn-site.xml
    yarn.resourcemanager.hostname:yarn管理的主机名
    yarn.nodemanager.aux-services:默认
    yarn.log-aggregation-enable:是否聚合各子节点的日志信息到主节点,设置为是,不然在web上看不到日志
    yarn.log-aggregation.retain-seconds:日志保存时长,单位秒,默认为-1,不删除,可按需设置
<configuration>

<!-- Site specific YARN configuration properties -->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>master</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>640800</value>
    </property>

</configuration>
  1. 配置分布式计算 vi mapred-site.xml
    mapreduce.framework.name:用于执行MapReduce作业的运行时框架,可选项是local、classic、yarn,默认为local,我们选yarn
    mapreduce.jobhistory.address:日志历史服务器地址,默认为0.0.0.0:10020,可按需修改
    mapreduce.jobhistory.webapp.address:日志历史网页地址,默认为0.0.0.0:19888,可按需修改
<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>
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>
    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>
    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>
</configuration>
  1. 配置子节点 vi workers hadoop2配置的slaves,这是2与3的一大差别
    将文中的localhost用我们的datanode的hostname替换
slave1
slave2
  1. 到此hadoop的配置基本搞定,退出并关闭容器
    将此容器保存为新的镜像 docker commit hadoop-test hadoop:base

4、集群搭建

有了上述配置好的hadoop镜像,我们可以快速构建 node 容器

4.1 构建docker网桥

之前说过,hadoop要求节点具有固定ip,docker可以通过network为容器配置固定ip

docker network create --subnet=192.168.0.0/24 hadoop

其中24表示ip的前24位为固定,后8为可用,即192.168.0.1-192.168.0.254可用,hadoop为network的名称,此部分可按需修改

4.2 构建node容器

分别运行如下命令构建masterslave1slave2三个容器,其中–hostname用于设置node的主机名称,–ip用于配置固定ip

我们为master绑定8088、9870、19888端口号,便于在本地访问

需要注意的是,我们在构建镜像时为容器设置了启动命令CMD ["/usr/sbin/sshd", "-D"](Dockerfile最后一行,使容器启动时自动启动ssh服务),所以不要使用docker run -itd来构建容器,否则会被后面自定义的命令(如bash)替换,导致ssh未启动,从而出现22端口无法访问的问题

docker run -d --name master --hostname master --network hadoop --ip 192.168.0.10 -P -p 8088:8088 -p 9870:9870 -p 19888:19888 hadoop:base
docker run -d --name slave1 --hostname slave1 --network hadoop --ip 192.168.0.11 -P hadoop:base
docker run -d --name slave2 --hostname slave2 --network hadoop --ip 192.168.0.12 -P hadoop:base

4.3 配置node免密登录

进入master容器 docker exec -it master bash
生成密钥 ssh-keygen 一直回车就行
将密钥分发给其他node,此过程需要输入 yes 和 密码(Dockerfile里设置的是root

ssh-copy-id master
ssh-copy-id slave1
ssh-copy-id slave2

进入其他datanode节点做上述同样的操作

4.4 启动服务

ok,终于全都配置好了,回到master容器去启动服务

  1. 格式化hdfs hdfs namenode -format注意,第一次格式化就行,以后慎用,格式化会导致namenode的clusterID和datanode的clusterID不一致,以致datanode无法启动
  2. 启动服务 $HADOOP_HOME/sbin/start-all.sh
  3. 启动历史日志服务 $HADOOP_HOME/bin/mapred --daemon start historyserver
  4. 查看启动的服务 jps,master节点有如下服务表示正常
  5. 进入slave1slave2容器,运行 jps,slave节点有如下服务表示正常

4.5 关闭服务

如果需要关闭服务,可执行以下命令

  1. 关闭历史任务服务 $HADOOP_HOME/bin/mapred --daemon stop historyserver
  2. 关闭服务 $HADOOP_HOME/sbin/stop-all.sh

5、hadoop测试

5.1 hdfs服务测试

  1. 在master容器中新建一个文件 vi test.txt,随便输入一些字符,并保存退出
  2. 将文件保存到hdfs的根目录 hdfs dfs -put test.txt /
  3. 查看hdfs的根目录内容 hadoop fs -ls /,可以看到文件已保存到hdfs
  4. 我们也可以通过浏览器访问hdfs管理界面,在浏览器中输入localhost:9870,并在Utilities中点击Browse the file system,即可看到文件存储情况,网址端口号根据自己的配置来

5.2 mapReduce服务测试

  1. 进入hadoop计算样例目录 cd $HADOOP_HOME/share/hadoop/mapreduce
  2. 运行测试样例 hadoop jar hadoop-mapreduce-examples-3.3.2.jar pi 3 100 调用jar包计算pi的值,计算100次(根据自己的hadoop版本修改命令)
  3. 通过浏览器查看,在浏览器中输入localhost:8088,可以查看任务情况以及日志等,网址端口号根据自己的配置来
  4. 运行完的任务过一段时间会清除,此时可以去历史任务页面查看,网址为localhost:19888,网址端口号根据自己的配置来

结语

写了一晚上终于写完了,最近一周没算白忙活,后面还得继续深入学习,加油~

参考文献

  1. https://www.cnblogs.com/rmxd/p/12051866.html
  2. https://www.lousenjay.top/2018/08/21/hadoop3.0%E5%85%A8%E5%88%86%E5%B8%83%E5%BC%8F%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA/#%E5%89%8D%E6%8F%90%E5%87%86%E5%A4%87
  3. https://blog.csdn.net/qq_45744501/article/details/112175428
  4. 官方文档

以上是关于基于docker的hadoop集群搭建的主要内容,如果未能解决你的问题,请参考以下文章

基于Docker快速搭建Hadoop集群和Flink运行环境

基于Docker快速搭建Hadoop集群和Flink运行环境

Hadoop集群+Spark集群搭建基于VMware虚拟机教程+安装运行Docker

Hadoop集群+Spark集群搭建基于VMware虚拟机教程+安装运行Docker

Hadoop集群+Spark集群搭建基于VMware虚拟机教程+安装运行Docker

基于docker的hadoop集群搭建