Mac上的Docker部署一套hadoop+kafka+flink的环境

67 阅读8分钟

第零部分:准备工作

在开始之前,请确保您的Mac上已经安装了Docker Desktop。如果没有,请从官网下载并安装:

安装完成后,请启动Docker Desktop。


第一部分:优化Docker环境(只需操作一次)

为了确保大数据组件流畅运行,我们需要对Docker进行一些一次性的性能优化配置。

步骤1:分配更多系统资源

  1. 点击屏幕顶部菜单栏中的Docker图标,然后选择 Preferences... (或 Settings... )。
  2. 在左侧导航栏中,选择 Resources
  3. CPUs: 将滑块拖动到您Mac处理器核心数的一半。例如,如果您的Mac有8个核心,请选择4。
  4. Memory: 将滑块拖动到至少 8.0 GB。如果您的Mac有16GB或更多内存,强烈建议分配 12 GB 或更多。
  5. 点击右下角的 Apply & Restart 按钮。Docker将会重启以应用这些设置。

步骤2:启用VirtioFS以获得最佳性能

这是在Mac上运行数据密集型应用最关键的一步 1。

  1. 再次打开Docker的 Preferences... / Settings...
  2. 在左侧导航栏中,选择 General
  3. 找到标题为 “Choose file sharing implementation for your containers” 的下拉菜单。
  4. 选择 VirtioFS
  5. 点击右下角的 Apply & Restart 按钮。

至此,您的Docker环境已准备就绪。


第二部分:设置项目文件

现在,我们来创建运行整个系统所需的所有配置文件。

步骤1:创建项目文件夹

  1. 打开 终端 (Terminal) 应用程序。

  2. 执行以下命令,在您的用户主目录下创建一个名为 bigdata_stack 的项目文件夹,并进入该文件夹。

    Bash

    mkdir ~/bigdata_stack
    cd ~/bigdata_stack
    

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

这是我们整个项目的核心文件,它定义了所有服务。

  1. 在终端中(确保您仍在 ~/bigdata_stack 目录下),执行以下命令来创建并编辑 docker-compose.yml 文件:

    Bash

    touch docker-compose.yml && open -e docker-compose.yml
    
  2. 上述命令会用文本编辑器打开一个空白文件。将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。

    YAML

services:
  namenode:
    image: bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8
    container_name: namenode
    restart: always
    ports:
      - "9870:9870"
      - "9000:9000"
    volumes:
      - hadoop_namenode:/hadoop/dfs/name
    environment:
      CLUSTER_NAME: test
      CORE_CONF_fs_defaultFS: hdfs://namenode:9000
      HDFS_CONF_dfs_replication: 2
    networks:
      - bigdata-net

  datanode1:
    image: bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8
    container_name: datanode1
    restart: always
    volumes:
      - hadoop_datanode1:/hadoop/dfs/data
    environment:
      SERVICE_PRECONDITION: "namenode:9870"
      CORE_CONF_fs_defaultFS: hdfs://namenode:9000
    depends_on:
      - namenode
    networks:
      - bigdata-net

  datanode2:
    image: bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8
    container_name: datanode2
    restart: always
    volumes:
      - hadoop_datanode2:/hadoop/dfs/data
    environment:
      SERVICE_PRECONDITION: "namenode:9870"
      CORE_CONF_fs_defaultFS: hdfs://namenode:9000
    depends_on:
      - namenode
    networks:
      - bigdata-net

  kafka:
    image: bitnamilegacy/kafka:3.4.0
    container_name: kafka
    restart: always
    ports:
      - "9094:9094"
    volumes:
      - kafka_data:/bitnami/kafka
    environment:
      # Added this line to fix the plaintext listener error
      ALLOW_PLAINTEXT_LISTENER: "yes"
      KAFKA_CFG_NODE_ID: 0
      KAFKA_CFG_PROCESS_ROLES: controller,broker
      KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
      KAFKA_CFG_LISTENERS: INTERNAL://:9092,EXTERNAL://:9094,CONTROLLER://:9093
      KAFKA_CFG_ADVERTISED_LISTENERS: INTERNAL://kafka:9092,EXTERNAL://localhost:9094
      KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_CFG_INTER_BROKER_LISTENER_NAME: INTERNAL
    networks:
      - bigdata-net

  jobmanager:
    build:
      context: .
      dockerfile: Dockerfile
    image: bigdata-stack-flink
    container_name: jobmanager
    restart: always
    ports:
      - "8081:8081"
    command: jobmanager
    volumes:
      - ./job.sql:/tmp/job.sql
    environment:
      FLINK_PROPERTIES: |
        jobmanager.rpc.address: jobmanager
        fs.defaultFS: hdfs://namenode:9000
    networks:
      - bigdata-net

  taskmanager:
    image: bigdata-stack-flink
    container_name: taskmanager
    restart: always
    command: taskmanager
    depends_on:
      - jobmanager
    environment:
      FLINK_PROPERTIES: |
        jobmanager.rpc.address: jobmanager
        taskmanager.numberOfTaskSlots: 2
        fs.defaultFS: hdfs://namenode:9000
    networks:
      - bigdata-net

networks:
  bigdata-net:
    driver: bridge

volumes:
  hadoop_namenode:
  hadoop_datanode1:
  hadoop_datanode2:
  kafka_data:   

步骤3:创建 Dockerfile 文件

这个文件用于构建一个包含所需连接器的自定义Flink镜像。

  1. 在终端中(确保您仍在 ~/bigdata_stack 目录下),执行以下命令来创建并编辑 Dockerfile 文件:

    Bash

    touch Dockerfile && open -e Dockerfile
    
  2. 将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。

    Dockerfile

    # Use an official Flink image as a base
    FROM apache/flink:1.17.1-scala_2.12
    
    # Download connectors for Kafka and HDFS
    RUN wget -P /opt/flink/lib/ https://repo.maven.apache.org/maven2/org/apache/flink/flink-sql-connector-kafka/1.17.1/flink-sql-connector-kafka-1.17.1.jar && \
        wget -P /opt/flink/lib/ https://repo.maven.apache.org/maven2/org/apache/flink/flink-hadoop-fs/1.17.1/flink-hadoop-fs-1.17.1.jar
    

步骤4:创建 job.sql 文件

这是我们最后用来测试整个流程的Flink SQL脚本。

  1. 在终端中(确保您仍在 ~/bigdata_stack 目录下),执行以下命令来创建并编辑 job.sql 文件:

    Bash

    touch job.sql && open -e job.sql
    
  2. 将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。

    SQL

    CREATE TABLE kafka_source (
      `id` INT,
      `product` STRING,
      `amount` INT
    ) WITH (
      'connector' = 'kafka',
      'topic' = 'input-topic',
      'properties.bootstrap.servers' = 'kafka:9092',
      'properties.group.id' = 'test-group',
      'scan.startup.mode' = 'earliest-offset',
      'format' = 'json'
    );
    
    CREATE TABLE hdfs_sink (
      `id` INT,
      `product` STRING,
      `amount` INT
    ) WITH (
      'connector' = 'filesystem',
      'path' = 'hdfs://namenode:9000/output',
      'format' = 'csv'
    );
    
    INSERT INTO hdfs_sink SELECT * FROM kafka_source;
    

现在,您的 ~/bigdata_stack 文件夹下应该有 docker-compose.ymlDockerfilejob.sql 这三个文件。


第三部分:启动并验证整个系统

步骤1:一键启动

  1. 回到您的终端窗口(确保目录是 ~/bigdata_stack)。

  2. 执行以下命令。这个过程会下载所有镜像并构建自定义的Flink镜像,首次运行可能需要几分钟时间,请耐心等待。

    Bash

    docker compose up -d --build
    

步骤2:验证所有服务是否正常运行

  1. 等待大约一分钟,让所有服务完成启动。

  2. 在终端中执行以下命令:

    Bash

    docker compose ps
    
  3. 您应该看到类似下面的输出,所有服务的 STATUS 都应该是 runningup

    NAME          IMAGE                                     COMMAND                  SERVICE       CREATED         STATUS         PORTS
    datanode1     bde2020/hadoop-datanode:2.0.0-hadoop3...   "/entrypoint.sh /run…"   datanode1     2 minutes ago   Up 2 minutes
    datanode2     bde2020/hadoop-datanode:2.0.0-hadoop3...   "/entrypoint.sh /run…"   datanode2     2 minutes ago   Up 2 minutes
    jobmanager    bigdata_stack-jobmanager                  "/docker-entrypoint.…"   jobmanager    2 minutes ago   Up 2 minutes   0.0.0.0:8081->8081/tcp, :::8081->8081/tcp, 6123/tcp
    kafka         bitnami/kafka:latest                      "/opt/bitnami/script…"   kafka         2 minutes ago   Up 2 minutes   0.0.0.0:9094->9094/tcp, :::9094->9094/tcp
    namenode      bde2020/hadoop-namenode:2.0.0-hadoop3...   "/entrypoint.sh /run…"   namenode      2 minutes ago   Up 2 minutes   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 0.0.0.0:9870->9870/tcp, :::9870->9870/tcp
    taskmanager   jobmanager                                "/docker-entrypoint.…"   taskmanager   2 minutes ago   Up 2 minutes   6121-6122/tcp
    

步骤3:通过Web界面检查

  1. Hadoop HDFS: 打开浏览器,访问 http://localhost:9870。您应该能看到Hadoop的界面,并且在 "Datanode Information" 标签页下,"Live Nodes" 的数量应为 2 6。
  2. Flink: 打开浏览器,访问 http://localhost:8081。您应该能看到Flink的仪表盘,并且 "Available Task Slots" 的数量应为 2 (或更多) 8。

如果以上检查都通过,说明您的基础环境已经成功启动!


第四部分:端到端数据流测试

现在,我们将通过一个完整的例子来验证所有组件都已正确连接。

步骤1:创建Kafka主题

在终端中执行以下命令,创建一个名为 input-topic 的主题,用于接收数据。

Bash

docker compose exec kafka kafka-topics.sh --bootstrap-server kafka:9092 --create --topic input-topic --partitions 1 --replication-factor 1

您应该会看到 Created topic input-topic. 的确认信息。

步骤2:向Kafka发送数据

  1. 执行下面的命令,启动一个可以向Kafka发送消息的工具:

    Bash

    docker compose exec kafka kafka-console-producer.sh --bootstrap-server kafka:9092 --topic input-topic
    
  2. 命令执行后,终端会停在一个 > 符号处,等待您输入。请将下面的三行JSON数据逐行复制并粘贴到终端中,每粘贴一行就按一次回车:

    JSON

    {"id": 1, "product": "apple", "amount": 10}
    

    (按回车)

    JSON

    {"id": 2, "product": "banana", "amount": 20}
    

    (按回车)

    JSON

    {"id": 3, "product": "cherry", "amount": 30}
    

    (按回车)

  3. 发送完毕后,按 Ctrl + C 组合键退出。

步骤3:提交Flink SQL作业

现在,我们让Flink去处理刚刚发送到Kafka的数据。

  1. 在终端中执行以下命令,提交我们之前创建的 job.sql 脚本:

    Bash

    docker compose exec jobmanager /opt/flink/bin/sql-client.sh -f /tmp/job.sql
    
  2. 作业提交后,您可以再次访问Flink UI (http://localhost:8081),在 "Running Jobs" 下应该能看到一个新启动的作业。

步骤4:在HDFS中验证最终结果

最后,我们检查Flink是否已将处理结果成功写入HDFS。

  1. 在终端中执行以下命令,查看HDFS的 /output 目录:

    Bash

    docker compose exec namenode hdfs dfs -ls /output
    
  2. 您会看到一个或多个由Flink创建的文件。复制其中一个文件名(例如 c7a01e30-2429-461b-b391-2becb8c4748f-0-0),然后用下面的命令查看其内容,记得替换 <filename> 部分

    Bash

    docker compose exec namenode hdfs dfs -cat /output/<filename>
    
  3. 如果看到类似下面的CSV格式数据,那么恭喜您!整个数据管道已成功打通!

    1,apple,10
    2,banana,20
    3,cherry,30
    

第五部分:日常管理

  • 停止所有服务 (不删除数据):

    Bash

    docker compose stop
    
  • 重新启动已停止的服务:

    Bash

    docker compose start
    
  • 彻底关闭并删除所有容器 (不删除数据):

    Bash

    docker compose down
    
  • 彻底关闭、删除容器,并删除所有数据 (HDFS中的数据和Kafka的数据都会被清空):

    Bash

    docker compose down -v
    

您已成功在Mac上部署并验证了一套完整的大数据处理系统。