课程 6:Hadoop 回顾与 Docker化集群搭建

本课程简要回顾 Apache Hadoop 的核心组件,并指导您使用 Docker 和 Docker Compose 搭建一个简化的 Hadoop 集群。这种方法非常适合学习和开发目的。

1. Hadoop 生态系统回顾

Apache Hadoop 是一个开源框架,设计用于在商用硬件构建的计算机集群上进行大规模数据集(大数据)的分布式存储和分布式处理。

HDFS (Hadoop Distributed File System)

作用:HDFS 是 Hadoop 的主要存储系统。它是一个设计用于在商用硬件上运行的分布式文件系统。

  • 主要特性:
    • 可伸缩性:可以存储 PB 级别的数据。
    • 容错性:数据在多台机器(DataNode)上复制,以防止硬件故障时数据丢失。默认情况下,数据块复制3次。
    • 数据局部性:通过将计算移动到数据所在位置,而不是将大量数据移动到计算位置,来优化计算。
  • 核心组件:
    • NameNode:管理文件系统命名空间(元数据,如文件名、目录结构、数据块位置)并规定客户端对文件的访问的主服务器。它不存储实际数据。
    • DataNode:存储实际数据块的从节点。它们负责根据客户端或 NameNode 的请求读取和写入数据块,并向 NameNode 报告其状态。

YARN (Yet Another Resource Negotiator)

作用:YARN 是 Hadoop 的集群资源管理框架。它负责为 Hadoop 集群中运行的各种应用程序分配系统资源,并调度任务在不同的集群节点上执行。

  • 核心组件:
    • ResourceManager (RM):管理整个集群全局资源分配的主守护进程。它有两个主要组件:调度器(根据配置的策略为应用程序分配资源)和 ApplicationManager(管理正在运行的 ApplicationMaster)。
    • NodeManager (NM):在集群中每个工作节点上运行的从守护进程。它负责管理该节点上的资源、监控其使用情况并向 ResourceManager 报告。它还管理在该节点上执行任务。
    • ApplicationMaster (AM):一个特定框架库的实例,它从 ResourceManager 协商资源,并与 NodeManager 一起执行和监控任务。

MapReduce

作用:MapReduce 是一种用于大型数据集分布式计算的编程模型和处理引擎。它通过抽象分布式系统的复杂性来简化并行处理。

  • 阶段:
    • Map 阶段:输入数据被分割并通过并行运行的 map 任务进行处理。每个 map 任务将其用户定义的 map 函数应用于其输入数据部分,以产生中间键/值对。
    • Shuffle 和 Sort 阶段:来自 map 阶段的中间结果按键排序和分组。
    • Reduce 阶段:Reduce 任务处理分组的中间数据。每个 reduce 任务将其用户定义的 reduce 函数应用于聚合与键关联的值,从而产生最终输出。

它们如何协同工作

数据被加载到 HDFS 中进行分布式存储。当提交 MapReduce 作业(或其他处理框架如 Spark)时,YARN 会在 DataNode 上分配资源(CPU、内存)。然后,处理任务(例如 mapper 和 reducer)由 YARN 调度在这些节点上运行,理想情况下是在数据所在的位置(数据局部性),以处理来自 HDFS 的数据并将结果存回 HDFS。

2. 搭建 Docker化的 Hadoop 集群

手动搭建 Hadoop 集群可能很复杂。Docker 显著简化了此过程,使其非常适合学习和开发。

使用 Docker 搭建 Hadoop 的好处

  • 易于搭建:无需在多台机器或复杂的虚拟机上手动安装和配置 Hadoop 组件。
  • 隔离性:可以在本地机器上运行不同的 Hadoop 版本或配置而不会发生冲突。
  • 可复现性:Dockerfile 和 Docker Compose 文件确保您的环境易于复现。
  • 清洁的环境:可以轻松启动、停止和重置您的 Hadoop 环境,而不会影响您的主机系统。

前提条件:

  • Docker 引擎:确保 Docker 已在您的系统上安装并正在运行。(请参考课程 5 或 Docker 官方文档)。
  • Docker Compose:强烈建议使用 Docker Compose 来管理像 Hadoop 集群这样的多容器应用程序。安装说明可以在 Docker 官方网站上找到。(通常包含在 Windows/Mac 的 Docker Desktop 中)。

步骤 1:创建 `docker-compose.yml` 文件

我们将使用 `bigdataeurope/hadoop-*` 系列镜像,它们为多容器设置提供了良好的基础。为您的 Hadoop 设置创建一个目录(例如 `my_hadoop_cluster`),并在其中创建一个名为 `docker-compose.yml` 的文件,内容如下:

version: '3.8'

services:
  namenode:
    image: bigdataeurope/hadoop-namenode:2.0.0-hadoop3.2.1-java8
    container_name: namenode
    hostname: namenode
    volumes:
      - namenode_data:/hadoop/dfs/name
    environment:
      - CLUSTER_NAME=testcluster
    ports:
      - "9870:9870"  # NameNode Web UI
      - "9000:9000"  # NameNode RPC (供 DataNode 和 HDFS 客户端使用)
    networks:
      - hadoop_network

  datanode1:
    image: bigdataeurope/hadoop-datanode:2.0.0-hadoop3.2.1-java8
    container_name: datanode1
    hostname: datanode1
    depends_on:
      - namenode
    volumes:
      - datanode1_data:/hadoop/dfs/data
    environment:
      - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
    ports:
      - "9864:9864" # DataNode Web UI (可选)
    networks:
      - hadoop_network

  # 可选:添加第二个 DataNode 以获得更真实的设置
  # datanode2:
  #   image: bigdataeurope/hadoop-datanode:2.0.0-hadoop3.2.1-java8
  #   container_name: datanode2
  #   hostname: datanode2
  #   depends_on:
  #     - namenode
  #   volumes:
  #     - datanode2_data:/hadoop/dfs/data
  #   environment:
  #     - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
  #   ports:
  #     - "9865:9864" # 如果运行多个 datanode,则映射到不同的主机端口
  #   networks:
  #     - hadoop_network

  resourcemanager: # YARN ResourceManager
    image: bigdataeurope/hadoop-resourcemanager:2.0.0-hadoop3.2.1-java8
    container_name: resourcemanager
    hostname: resourcemanager
    depends_on:
      - namenode
      - datanode1 # 如果使用,则添加 datanode2
    ports:
      - "8088:8088"  # YARN ResourceManager Web UI
    networks:
      - hadoop_network

  nodemanager1: # YARN NodeManager
    image: bigdataeurope/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8
    container_name: nodemanager1
    hostname: nodemanager1
    depends_on:
      - namenode
      - resourcemanager
    environment:
      - YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
    ports:
      - "8042:8042" # NodeManager Web UI
    networks:
      - hadoop_network

volumes:
  namenode_data:
  datanode1_data:
  # datanode2_data:

networks:
  hadoop_network:
    driver: bridge

说明:

  • namenode:配置 HDFS NameNode。端口 9870 用于其 Web UI,9000 用于 HDFS 通信。
  • datanode1:配置一个 HDFS DataNode。它依赖于 NameNode。
  • resourcemanager:配置 YARN ResourceManager。端口 8088 用于其 Web UI。
  • nodemanager1:配置一个 YARN NodeManager,它在工作节点上运行(此处与 datanode 一起模拟)。
  • volumes:定义命名卷以持久化 HDFS 数据,即使容器被移除和重新创建。
  • networks:创建一个自定义桥接网络 `hadoop_network`,以便容器之间使用其服务名作为主机名轻松通信。

步骤 2:启动 Hadoop 集群

在终端中导航到您的 `my_hadoop_cluster` 目录并运行:

docker-compose up -d

此命令将下载镜像(如果尚不存在)并在分离模式 (-d) 下启动所有定义的服务。

检查容器状态:

docker-compose ps
# 或者直接使用 docker 命令
docker ps

您应该看到 namenodedatanode1resourcemanagernodemanager1 正在运行。

步骤 3:访问 Web UI

一旦容器启动并运行(给它们一两分钟完全初始化):

  • HDFS NameNode UI:打开浏览器并转到 http://localhost:9870。您应该会看到 NameNode 仪表板,包括有关活动 DataNode 的信息。
  • YARN ResourceManager UI:打开浏览器并转到 http://localhost:8088。您可以看到集群指标、正在运行的应用程序和节点信息。
  • DataNode UI (可选):对于 datanode1,映射到 http://localhost:9864
  • NodeManager UI (可选):对于 nodemanager1,映射到 http://localhost:8042

所有服务可能需要一些时间来初始化,DataNode 也需要时间向 NameNode 注册。如果 UI 没有立即显示 DataNode,请稍等片刻并刷新。

步骤 4:基本 HDFS 命令

要与 HDFS 交互,您将使用 docker execnamenode 容器内运行 HDFS 命令(因为它配置了 HDFS 客户端工具)。

  1. 列出根目录:
    docker exec namenode hdfs dfs -ls /

    您可能会看到一些默认目录。

  2. 创建用户目录(常见做法):
    docker exec namenode hdfs dfs -mkdir -p /user/myuser

    (将 myuser 替换为您想要的用户名或任何目录名)。

  3. 创建一个本地测试文件:
    echo "你好 Docker化的 Hadoop!" > mytestfile.txt
  4. 将本地文件复制到 NameNode 容器中:
    docker cp mytestfile.txt namenode:/tmp/mytestfile.txt
  5. 将文件从容器的本地文件系统放入 HDFS:
    docker exec namenode hdfs dfs -put /tmp/mytestfile.txt /user/myuser/
  6. 验证 HDFS 中的文件:
    docker exec namenode hdfs dfs -ls /user/myuser/

    您应该会看到列出的 mytestfile.txt

  7. 查看 HDFS 中的文件内容:
    docker exec namenode hdfs dfs -cat /user/myuser/mytestfile.txt
  8. 将文件从 HDFS 获取回 NameNode 容器的本地文件系统:
    docker exec namenode hdfs dfs -get /user/myuser/mytestfile.txt /tmp/mytestfile_from_hdfs.txt
  9. 将文件从 NameNode 容器复制回您的主机:
    docker cp namenode:/tmp/mytestfile_from_hdfs.txt ./

    现在您应该在主机的当前目录中拥有 mytestfile_from_hdfs.txt

步骤 5:停止集群

要停止并移除 `docker-compose.yml` 中定义的所有容器、网络和卷:

docker-compose down

如果您想停止而不移除卷(以便数据持久化):

docker-compose stop

结论

使用 Docker 和 Docker Compose 搭建 Hadoop 集群为学习和开发提供了一个易于管理和可复现的环境。您可以轻松地试验 HDFS 命令,提交 MapReduce 作业(尽管运行作业是一个更高级的步骤,此处未完全涵盖),并了解 Hadoop 组件如何交互,而无需手动安装的开销。此设置为探索分布式数据处理奠定了良好的基础。