Hadoop安装到入门

146 阅读4分钟

一、使用Docker安装hadoop

1、下载 jdk 和 hadoop百度网盘

hadoop

链接: pan.baidu.com/s/1xqUqcDwP… 密码: knid

jdk

链接: pan.baidu.com/s/1cuktDP5l… 密码: 58ai

2、使用Dockerfile创建centos环境

在本机创建一个centos7-base的目录在里面创建Dockerfile用来生成docker image

mkdir centos7-base
vim Dockerfile

按照下面的内容配置Dockerfile

FROM centos7:base

# 安装工具
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.cloud.tencent.com/repo/centos7_base.repo
RUN yum install -y openssh-server
RUN yum install -y openssh-clients
RUN yum install -y vim
RUN yum install -y net-tools


# java
RUN mkdir /module && chmod -R 755 /module
ADD jdk1.8 /module/
ENV JAVA_HOME=/module/jdk1.8
ENV PATH=$JAVA_HOME/bin:$PATH


# ssh 设置
RUN echo "root:peng" | chpasswd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -A
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

使用docker命令创建按照Dockerfile创建镜像

docker build --no-cache -t="centos7-ssh:v1" .

--no-cache参数可以去掉,这个是不使用缓存构建镜像。使用缓存构建镜像速度更快。

2.1、验证docker镜像ssh服务是否启动

需要验证docker镜像ssh 服务启动正常,jdk安装正确。

启动docker容器、并进入容器内部

docker run -itd --name centos7ssh -p222:22 centos7-ssh:v1
docker exec -it centos7ssh /bin/bash

# 看下22端口是否启动
netstat -anp | grep 22
# 使用 ssh 链接下localhost
ssh root@localhost

2.2、安装hadoop到docker中

上面已经将jdk安装到了容器中,下面需要把hadoop安装进去。

FROM centos:7

# 安装工具
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.cloud.tencent.com/repo/centos7_base.repo
RUN yum install -y openssh-server
RUN yum install -y openssh-clients
RUN yum install -y vim
RUN yum install -y net-tools
RUN yum install -y which


# java
RUN mkdir /module && chmod -R 755 /module
ADD jdk1.8 /module/
ENV JAVA_HOME=/module/jdk1.8
ENV PATH=$JAVA_HOME/bin:$PATH

# hadoop
ADD hadoop /module
ENV HADOOP_HOME=/module/hadoop
ENV PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH


# ssh 设置
RUN echo "root:peng" | chpasswd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -A
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

这里可以把安装hadoop的命令加到原来的Dockerfile中也可以,使用2.1中创建的 “centos7-ssh:v1” 这个镜像上面再次加工创建镜像

2.2、创建docker网络

docker默认使用 桥接模式创建网络,桥接模式下会为docker容器分配单独的ip地址。要访问容器需要在容器启动的时候使用 “-p” 命令映射端口

3、创建docker网络、启动docker

3.1.1、创建hadoop专用的网路

docker network create --driver bridge hadoop-br

这里使用桥接模式,还有其他模式参见 blog.csdn.net/ithaibianti…

3.1.2、启动docker,指定网络

docker run -itd --network hadoop-br --name hadoop1 -p 50070:50070 -p 8088:8088 hadoop:v1
docker run -itd --network hadoop-br --name hadoop2 hadoop:v1
docker run -itd --network hadoop-br --name hadoop3 hadoop:v1

启动三台docker容器,网络都指定为 “hadoop-br” hadoop1 映射端口。

3.1.3、配置host、查看网络信息

三台容器都在一个子网内,可以使用docker network 命令查看网络信息

docker network inspect hadoop-br

下面是网络信息,可以看到三台docker的ip地址

[
    {
        "ConfigOnly": false,
        "Containers": {
            "b789945a3b826df2538d62b07d278f6c9fe4de0724d0b77130ba405a6c3ceede": {
                "Name": "hadoop1",
                "EndpointID": "77eb6974a90d772e253f1e475e3fb0d31d5ddc05b4d3269415d325bac92d753f",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            },
            "d7687c345b564c1825b51e6507c7a68ce2993655c242e77b6388fe3e120ac146": {
                "Name": "hadoop2",
                "EndpointID": "b1fc988f7dddc90e328a79e159bf69fb4cd11597f85f8eeec1e560405ebec454",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            },
            "edb171046992a8858e26ecb0c56280e31f6fb0f0b0bbcfebcdf89c0139019fa1": {
                "Name": "hadoop3",
                "EndpointID": "da88ae3d089e81f8564201473d1362222bfb2f77390e06c7c205fae33c5b981f",
                "MacAddress": "02:42:ac:13:00:04",
                "IPv4Address": "172.19.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

配置host

vim /etc/hosts
# 将ip地址和主机名配置上

172.19.0.2 hadoop1
172.19.0.3 hadoop2
172.19.0.4 hadoop3

登录容器验证是否可以ping通

docker exec -it hadoop1 bash
ping hadoop2
ping hadoop3

3.2、配置ssh免密登录

ssh-keygen
#一路回车,生成ssh的公钥和私钥

ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop1
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop2
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop3
# 输入自己的密码,这个命令是将当前容器root用户的公钥给到其他服务器,实现免密登录

这个命令需要在三台服务器上都执行一遍

二、伪分布式运行

hadoop分为三种启动方式

  • 本地模式
  • 伪分布式模式
  • 完全分布式模式

1、本地模式

- 不对配置文件进行修改。

- 使用本地文件系统,而不是分布式文件系统。

- Hadoop不会启动NameNode、DataNode、ResourceManager、NodeManager等守护进程,Map()和Reduce()任务作为同一个进程的不同部分来执行的。

2、伪分布式模式

等同于分布式模式,不过有所的进程都在一个节点上。

- 分为在HDFS上执行和在YARN上执行

- Hadoop启动NameNode、DataNode、ResourceManager、NodeManager这些守护进程都在同一台机器上运行,是相互独立的Java进程。

3、完全分布模式

多个节点共同运行,NameNode和ResourceManager等运行在不同的节点上

- Hadoop的守护进程运行在由多台主机搭建的集群上,是真正的生产环境。

- 在所有的主机上安装JDK和Hadoop,组成相互连通的网络。

- 在主机间设置SSH免密码登录,把各从节点生成的公钥添加到主节点的信任列表。

- 分布式文件系统

1、这里采用伪分布式模式运行学习

上面发现在Dockerfile文件中指定的java和hadoop环境变量在进行ssh登录之后会失效,这里需要重新配置下

1、在/etc/profile.d下面创建自己的 myenv.sh 用来设置环境变量

vim /etc/profile.d/myenv.sh
#复制为下面的内容,路径不同记的记的修改
export JAVA_HOME="/module/jdk1.8"
export HADOOP_HOME="/module/hadoop"

export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

2、linux创建用户hadoop,运行hadoop

由于hadoop不能使用root用户启动,所以这里需要单独创建用户来启动

# 创建hadoop用户
useradd hadoop
# 将hadoop添加到root属组
usermod -g root hadoop
# 将hadoop目录的权限改成775
chmod -R 775 /module/hadoop

3、启动hdfs和yarn

第一次启动的时候需要创建NameNode

hdfs namenode -format

启动hdfs和yarn

# 分别启动
sbin/start-dfs.sh
sbin/start-yarn.sh
#执行jps 查看运行的java进行
[hadoop@526fd3cf9fef hadoop]$ jps
1797 DataNode
1642 NameNode
2284 ResourceManager
2796 Jps
1999 SecondaryNameNode
2415 NodeManager

可以看到 hdfs相关的进程 NameNode、SecondaryNameNode、DataNode启动,yarn相关的进程 ResourceManager、NodeManager启动。

4、配置日志收集

在yarn-site.xml中添加下面的内容

<!-- 开启日志聚集功能 -->
<property>
  <name>yarn.log-aggregation-enable</name>
  <value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>  
  <name>yarn.log.server.url</name>  
  <value>http://hadoop1:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7天 -->
<property>
  <name>yarn.log-aggregation.retain-seconds</name>
  <value>604800</value>
</property>

启动historyserver

mapred --daemon start historyserver

5、将当前的Docker容器生成image重新运行

由于上面的端口没有做端口映射,所以的宿主机上面没有办法访问。这里将当前的容器做成镜像,然后重新运行设置端口映射。

# 先停止当前的Docker
docker ps
docker stop ${CONTAINER ID}
# 将容器提交成镜像
docker commit -a "lupeng" -m "hadoop的dfs、yarn已经启动" ${CONTAINER ID} hadoop:v3

# 使用上面的镜像重新启动docker容器,设置端口映射
docker run -itd --network hadoop-br --name hadoop1 -p2201:22 -p8020:8020 -p9870:9870 -p8088:8088 -p19888:19888 hadoop:v3

使用下面的链接进行访问,查看hadoop的状态

链接名称备注
http://localhost:19888/历史服务,可用来查看历史任务
http://localhost:9870/查看hdfs的信息
http://localhost:8088/cluster查看yarn的信息

三、使用java代码链接hadoop HDFS

使用Intellij IDEA创建空项目

1、Maven依赖

<dependencies>
  <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>3.1.3</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.30</version>
  </dependency>
</dependencies>

2、代码

这里只简单写了下类似 “ls” 的代码,通过java链接hdfs也可以实现上传、下载、移动文件等等操作。

package com.peng;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * HdfsClientTest
 *
 * @author lupeng10
 * @create 2025-03-17 16:43
 */
public class HdfsClientTest {

    private FileSystem fs;

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration = new Configuration();
        this.fs = FileSystem.get(new URI("hdfs://localhost:8020"), configuration, "hadoop");
    }

    @After
    public void after() throws IOException {
        this.fs.close();
    }

    @Test
    public void testMkdirs() throws IOException {
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();
            System.out.println("path: " + fileStatus.getPath());
        }
    }
}

输出

path: hdfs://localhost:8020/input/word.txt
path: hdfs://localhost:8020/output/_SUCCESS
path: hdfs://localhost:8020/output/part-r-00000
path: hdfs://localhost:8020/sanguo/shuguo.txt
path: hdfs://localhost:8020/sanguo/weiguo.txt
path: hdfs://localhost:8020/sanguo/wuguo.txt
path: hdfs://localhost:8020/tmp/hadoop-yarn/staging/history/done/2025/03/14/000000/job_1741942379626_0001-1741942732636-hadoop-word+count-1741942748243-1-1-SUCCEEDED-default-1741942739151.jhist
path: hdfs://localhost:8020/tmp/hadoop-yarn/staging/history/done/2025/03/14/000000/job_1741942379626_0001_conf.xml
path: hdfs://localhost:8020/tmp/logs/hadoop/logs-tfile/application_1741942379626_0001/526fd3cf9fef_39043