第零部分:准备工作
在开始之前,请确保您的Mac上已经安装了Docker Desktop。如果没有,请从官网下载并安装:
- Docker Desktop for Mac: www.docker.com/products/do…
安装完成后,请启动Docker Desktop。
第一部分:优化Docker环境(只需操作一次)
为了确保大数据组件流畅运行,我们需要对Docker进行一些一次性的性能优化配置。
步骤1:分配更多系统资源
- 点击屏幕顶部菜单栏中的Docker图标,然后选择 Preferences... (或 Settings... )。
- 在左侧导航栏中,选择 Resources。
- CPUs: 将滑块拖动到您Mac处理器核心数的一半。例如,如果您的Mac有8个核心,请选择4。
- Memory: 将滑块拖动到至少 8.0 GB。如果您的Mac有16GB或更多内存,强烈建议分配 12 GB 或更多。
- 点击右下角的 Apply & Restart 按钮。Docker将会重启以应用这些设置。
步骤2:启用VirtioFS以获得最佳性能
这是在Mac上运行数据密集型应用最关键的一步 1。
- 再次打开Docker的 Preferences... / Settings... 。
- 在左侧导航栏中,选择 General。
- 找到标题为 “Choose file sharing implementation for your containers” 的下拉菜单。
- 选择 VirtioFS。
- 点击右下角的 Apply & Restart 按钮。
至此,您的Docker环境已准备就绪。
第二部分:设置项目文件
现在,我们来创建运行整个系统所需的所有配置文件。
步骤1:创建项目文件夹
-
打开 终端 (Terminal) 应用程序。
-
执行以下命令,在您的用户主目录下创建一个名为
bigdata_stack的项目文件夹,并进入该文件夹。Bash
mkdir ~/bigdata_stack cd ~/bigdata_stack
步骤2:创建 docker-compose.yml 文件
这是我们整个项目的核心文件,它定义了所有服务。
-
在终端中(确保您仍在
~/bigdata_stack目录下),执行以下命令来创建并编辑docker-compose.yml文件:Bash
touch docker-compose.yml && open -e docker-compose.yml -
上述命令会用文本编辑器打开一个空白文件。将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。
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镜像。
-
在终端中(确保您仍在
~/bigdata_stack目录下),执行以下命令来创建并编辑Dockerfile文件:Bash
touch Dockerfile && open -e Dockerfile -
将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。
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脚本。
-
在终端中(确保您仍在
~/bigdata_stack目录下),执行以下命令来创建并编辑job.sql文件:Bash
touch job.sql && open -e job.sql -
将下面的所有内容完整地复制并粘贴到这个文件中,然后保存并关闭文件。
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.yml、Dockerfile 和 job.sql 这三个文件。
第三部分:启动并验证整个系统
步骤1:一键启动
-
回到您的终端窗口(确保目录是
~/bigdata_stack)。 -
执行以下命令。这个过程会下载所有镜像并构建自定义的Flink镜像,首次运行可能需要几分钟时间,请耐心等待。
Bash
docker compose up -d --build
步骤2:验证所有服务是否正常运行
-
等待大约一分钟,让所有服务完成启动。
-
在终端中执行以下命令:
Bash
docker compose ps -
您应该看到类似下面的输出,所有服务的
STATUS都应该是running或up。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界面检查
- Hadoop HDFS: 打开浏览器,访问
http://localhost:9870。您应该能看到Hadoop的界面,并且在 "Datanode Information" 标签页下,"Live Nodes" 的数量应为 2 6。 - 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发送数据
-
执行下面的命令,启动一个可以向Kafka发送消息的工具:
Bash
docker compose exec kafka kafka-console-producer.sh --bootstrap-server kafka:9092 --topic input-topic -
命令执行后,终端会停在一个
>符号处,等待您输入。请将下面的三行JSON数据逐行复制并粘贴到终端中,每粘贴一行就按一次回车:JSON
{"id": 1, "product": "apple", "amount": 10}(按回车)
JSON
{"id": 2, "product": "banana", "amount": 20}(按回车)
JSON
{"id": 3, "product": "cherry", "amount": 30}(按回车)
-
发送完毕后,按
Ctrl + C组合键退出。
步骤3:提交Flink SQL作业
现在,我们让Flink去处理刚刚发送到Kafka的数据。
-
在终端中执行以下命令,提交我们之前创建的
job.sql脚本:Bash
docker compose exec jobmanager /opt/flink/bin/sql-client.sh -f /tmp/job.sql -
作业提交后,您可以再次访问Flink UI (
http://localhost:8081),在 "Running Jobs" 下应该能看到一个新启动的作业。
步骤4:在HDFS中验证最终结果
最后,我们检查Flink是否已将处理结果成功写入HDFS。
-
在终端中执行以下命令,查看HDFS的
/output目录:Bash
docker compose exec namenode hdfs dfs -ls /output -
您会看到一个或多个由Flink创建的文件。复制其中一个文件名(例如
c7a01e30-2429-461b-b391-2becb8c4748f-0-0),然后用下面的命令查看其内容,记得替换<filename>部分:Bash
docker compose exec namenode hdfs dfs -cat /output/<filename> -
如果看到类似下面的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上部署并验证了一套完整的大数据处理系统。