Kafka + Flume 实操详情记录(略繁琐,包含错误和排查记录)

Kafka基础

定义 :分布式发布/订阅消息队列系统

核心概念

  • 生产者→Topic→消费者
  • Broker:Kafka服务器节点
  • Partition:Topic的分区(提高并发)
  • Replication:副本(保证可靠性)

消息队列价值

  1. 解耦生产消费
  2. 流量削峰(如秒杀系统)
  3. 异步通信
  4. 数据缓冲

排错要点

  1. Topic不匹配:Flume配置的topic必须与消费者一致
  2. 服务未启动:确保ZooKeeper和Kafka已运行(jps检查)
  3. 配置文件路径:所有路径需使用绝对路径
  4. 网络地址:建议统一使用localhost避免解析问题

关键理解

  • Flume作用:自动化数据采集(文件→Kafka)
  • Kafka直接通信:适合手动测试
  • 配置一致性:Topic名称、服务器地址必须匹配

注:实际环境需根据具体路径和主机名调整配置

Kafka + Flume 实操详情记录(略繁琐,包含错误和排查记录)


以下是为你整理的Kafka课堂笔记完整梳理与补充,结构清晰、内容详实,适合学生复习使用。


Kafka 课堂笔记


一、Kafka 定义

Kafka 是一个分布式 的、基于发布/订阅模式的消息队列系统。

数据流转过程

生产者 → 消息队列(MQ) → 消费者

  • 生产者不断产生数据

  • 数据被放入消息队列

  • 消费者从队列中读取并处理数据


二、消息队列的作用

以"双11秒杀"为例:

商品库存仅 1000 件,但每秒并发请求可达数万甚至数十万。

所有请求进入队列,先进先出,前 1000 个成功处理,其余直接返回"库存不足"。

消息队列的优点:
特点 说明
解耦 生产者和消费者可独立变化,只需遵循相同接口
可恢复性 部分组件失效不影响整体,降低耦合度
缓冲 生产速率与消费速率可以不一致,队列起到缓冲作用
灵活性 & 峰值处理能力 生产速率过高时,数据堆积在队列中,后期慢慢消费,系统不会崩溃
异步通信 任务拆分为多个步骤并行执行,互不影响;即使消息未被及时消费,仍保留在队列中,随时可拉取

三、消息队列的模式

1. 点对点模式
  • 一个生产者 → 一个队列 → 一个消费者

  • 消息被消费后通常从队列中移除

2. 发布/订阅模式(点对组模式)
  • 一个生产者 → 一个队列 → 多个消费者(消费组)

  • 消息消费后仍保留在队列中,可被多个消费者重复消费


四、Kafka 核心角色

角色 说明
Producer 消息生产者,将数据发送到 Kafka 集群
Consumer 消息消费者,从 Kafka 读取数据
Consumer Group (CG) 多个消费者组成一个组,共同消费某个 Topic
Broker 一台 Kafka 服务器就是一个 Broker,多个 Broker 组成集群
Topic 消息队列,生产者发送数据的目标,消费者订阅的对象
Partition Topic 的分区,用于水平扩展,提高并发能力
Replication 副本,保证数据可靠性,防止 Broker 宕机导致数据丢失
Leader 分区的主节点,负责读写
Follower 分区的从节点,同步 Leader 数据,Leader 宕机后可选举为新 Leader

五、Kafka 启动(前置条件)

1. 启动 Hadoop(可选,某些环境依赖)
2. 启动 ZooKeeper

bash

bash 复制代码
cd $ZOOKEEPER_HOME
bin/zkServer.sh start
3. 启动 Kafka

bash

bash 复制代码
cd $KAFKA_HOME
bin/kafka-server-start.sh -daemon config/server.properties
4. 验证启动

bash

bash 复制代码
jps
# 应看到 Kafka 进程

六、Kafka 常用命令(面向 Topic)

操作 命令示例
创建 Topic bin/kafka-topics.sh --zookeeper localhost:2181 --create --replication-factor 1 --partitions 1 --topic a2608
查看所有 Topic bin/kafka-topics.sh --zookeeper localhost:2181 --list
删除 Topic bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic a2608
修改 Topic(如增加分区) bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic a2608 --partitions 3
查看 Topic 详情 bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic a2608
生产与消费消息
操作 命令
生产者(发送消息) bin/kafka-console-producer.sh --broker-list localhost:9092 --topic a2608
消费者(接收消息) bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

笔记原文


往队列中发送消息:--a窗口

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic a2608

消费指定队列中的消息:--b窗口

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608
✅ 在一个窗口输入消息,另一个窗口应能实时看到消息


七、Kafka + Flume 整合实战(生产 → 消费)

目标:通过 Flume 监控日志文件,将数据发送到 Kafka,再由 Kafka 消费者实时消费
步骤:
1. 创建模拟日志文件

bash

bash 复制代码
mkdir -p /opt/module/flume/data/
touch /opt/module/flume/data/flume.log

创建模拟日志文件 在哪创建呢


我的意思在是Linux中创建,还是Hadoop中创建。还是哪里呢


明白了!你的问题是:在哪个系统/环境中执行创建命令


答案:在 Linux 系统 中创建


具体来说:

执行位置

  • Linux 操作系统(通常是 CentOS、Ubuntu 等发行版)

  • 通过 终端 / Shell 命令行 执行

  • 就是你安装 Kafka、Flume 的那台 Linux 服务器

详细说明

环境 是否在这里创建 说明
Linux ✅ 是 直接在 Linux 终端执行 mkdirtouchecho 命令
Hadoop ❌ 否 Hadoop 是分布式文件系统(HDFS),这里的文件是普通的 Linux 本地文件,不是 HDFS 上的文件
ZooKeeper ❌ 否 ZooKeeper 是协调服务,不用于创建日志文件
Kafka ❌ 否 Kafka 是消息队列,不负责创建日志文件

判断依据

注意 Flume 配置文件中的命令

bash

复制代码
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

tail -fLinux 系统命令 ,监控的是 Linux 本地文件系统 中的文件,而不是 HDFS 上的文件。


完整操作流程

bash

bash 复制代码
# 1. 在 Linux 终端执行(不是 Hadoop 的 hdfs 命令)
mkdir -p /opt/module/flume/data/
touch /opt/module/flume/data/flume.log

# 2. 查看文件是否创建成功
ls -l /opt/module/flume/data/flume.log

# 3. 向文件写入内容(模拟日志产生)
echo 111 >> /opt/module/flume/data/flume.log

简单记忆

Linux 本地文件系统 ← 创建日志文件

HDFS ← 存储大数据文件(如 Hadoop 处理的数据)

两者是不同的,不要混淆。

2. 编写 Flume 作业配置文件

路径:/opt/module/flume/job/flume-kafka.conf

properties

bash 复制代码
# define
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

# sink (Kafka)
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = node100:9092
a1.sinks.k1.kafka.topic = a2608
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1

# channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

已经在Hadoop中了,怎么退出到Linux环境


在 Hadoop 环境中,你很可能已经进入了 HDFS 的交互界面 或正在使用 Hadoop 命令行的某个子 shell。退出到普通 Linux 环境的方法如下:


常见情况及退出方法

情况1:你正在使用 hdfs dfs 命令(正常情况)

  • 判断 :提示符仍然是 [user@hostname ~]$ 这样的 Linux 格式

  • 结论:你本来就在 Linux 环境中,只是执行了 Hadoop 命令

  • 操作无需退出 ,直接执行 mkdir -p /opt/module/flume/data/ 即可


情况2:你进入了 HDFS 的交互式 Shell

bash

复制代码
# 可能你执行了类似这样的命令
hdfs dfs -ls /
# 或者进入了某个交互工具
  • 判断 :提示符变成了 hdfs>> 或其他特殊提示符

  • 退出方法

    bash

    复制代码
    exit
    # 或按
    Ctrl + C
    # 或按
    Ctrl + D

情况3:你通过 ssh 进入了 Hadoop 节点

  • 判断:提示符中包含其他主机名

  • 退出方法

    bash

    复制代码
    exit
    # 或按
    Ctrl + D

情况4:你正在使用 hadoop fs -ls / 等命令后

  • 结论:命令执行完自动回到 Linux 环境

  • 操作:直接继续输入 Linux 命令即可


快速验证当前位置

bash

复制代码
# 查看当前所在目录(应该是 Linux 路径,不是 HDFS 路径)
pwd

# 查看提示符格式
# Linux 提示符通常是:[user@hostname ~]$
# 如果看到 > 或 hdfs> 等,说明在子 shell 中

最简单的解决方案


如果搞不清楚状态,直接执行:

bash

复制代码
# 连续按几次 Ctrl + C(中断当前操作)
# 然后按 Ctrl + D(退出可能的子 shell)
# 重复 2-3 次,直到回到正常的 Linux 提示符

或者直接关闭当前终端窗口,重新打开一个新终端连接 Linux 服务器。


正常情况下的提示符示例

bash

复制代码
[root@node100 ~]$   # 这是 Linux 环境

在这个环境下直接执行:

bash

复制代码
mkdir -p /opt/module/flume/data/
touch /opt/module/flume/data/flume.log

完全没有问题!

3. 启动 Kafka 消费者(等待数据)

bash

复制代码
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

启动 Kafka 消费者(等待数据)提示没有那个文件或目录


这个错误说明你当前所在的目录不对 ,系统找不到 bin/kafka-console-consumer.sh 这个脚本。


原因

bin/kafka-console-consumer.sh 是一个相对路径 ,需要你在 Kafka 的安装根目录下执行。


解决方法

步骤1:找到 Kafka 安装目录

bash

复制代码
# 查找 Kafka 安装位置
find / -name "kafka-console-consumer.sh" 2>/dev/null

# 或者常见安装路径
ls /opt/module/kafka/bin/
ls /usr/local/kafka/bin/
ls /home/kafka/bin/

步骤2:进入 Kafka 根目录

bash

复制代码
# 根据你找到的路径,进入 Kafka 根目录
# 假设 Kafka 安装在 /opt/module/kafka
cd /opt/module/kafka

步骤3:确认目录结构正确

bash

复制代码
# 应该能看到 bin 目录
ls -l
# 输出示例:
# bin/  config/  libs/  logs/  ...

步骤4:执行命令

bash

复制代码
# 现在可以正确执行了
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

或者使用绝对路径

bash

复制代码
# 不切换目录,直接用完整路径
/opt/module/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

验证 Kafka 是否真的安装了

bash

复制代码
# 检查 Kafka 进程是否运行
jps | grep Kafka

# 如果没有输出,说明 Kafka 没有启动,需要先启动
cd $KAFKA_HOME
bin/kafka-server-start.sh -daemon config/server.properties

设置环境变量(推荐)

为了避免每次都切换目录,可以配置环境变量:

bash

bash 复制代码
# 编辑配置文件
vim ~/.bashrc

# 添加以下内容(根据你的实际路径修改)
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin

# 生效
source ~/.bashrc

# 之后可以直接执行
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

快速排查清单

检查项 命令
Kafka 是否安装 ls /opt/module/kafka/bin/
当前在哪个目录 pwd
Kafka 进程是否运行 `jps
端口是否监听 `netstat -tlnp

最常见的情况就是没有进入 Kafka 根目录,切换到正确目录即可解决。
进入 Kafka 根目录,执行 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608 没反应?


执行 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608没反应 (光标停住、没有报错、也没有输出),这其实是正常现象,说明消费者已经成功启动,正在等待数据。


为什么没反应?


Kafka 消费者启动后,会持续监听 指定的 Topic(a2608),等待新消息到来。此时:

  • 没有输出 = 还没有收到消息

  • 光标闪烁 = 程序在运行,处于阻塞等待状态

  • 不要按 Ctrl+C 退出

4. 启动 Flume 作业

bash

复制代码
cd $FLUME_HOME
bin/flume-ng agent -c conf -n a1 -f job/flume-kafka.conf -Dflume.root.logger=INFO,console
5. 模拟日志数据写入

bash

复制代码
echo 111 >> /opt/module/flume/data/flume.log
echo 222 >> /opt/module/flume/data/flume.log
echo 333 >> /opt/module/flume/data/flume.log
echo 444 >> /opt/module/flume/data/flume.log
6. 验证
  • Kafka 消费者窗口应能实时输出写入的日志内容

八、总结图示

text

复制代码
日志文件 → Flume(Source → Channel → Kafka Sink)→ Kafka(Topic)→ Kafka 消费者
  • Flume 作为生产者将数据写入 Kafka

  • Kafka 作为消息队列存储数据

  • 消费者从 Kafka 实时拉取数据


重新梳理一下具体的操作:按照Kafka生产者、Kafka消费者、Flume来区分,各自都需要什么样的操作,顺序是什么?我是初学者,从Linux环境开始,给出具体的操作,标注操作顺序。是需要打开3个窗口吗?


好的,我来为你完整梳理一遍操作流程,从零开始,按顺序执行,清清楚楚。


总体概览

你需要打开 3 个终端窗口(都连到同一台 Linux 服务器):

窗口 角色 作用
窗口1 Flume 监控日志文件,发送数据到 Kafka
窗口2 Kafka 消费者 等待并显示从 Kafka 收到的消息
窗口3 模拟日志生产 向日志文件写入内容

数据流向

复制代码
窗口3: echo >> flume.log  →  窗口1: Flume 监控到变化  →  窗口1: Flume 发送到 Kafka  →  窗口2: Kafka 消费者显示消息

实际开了5个窗口(窗口重命名更清晰)


前置条件(先确认一下)

在开始之前,确保以下服务已启动:

bash 复制代码
# 在任意窗口执行
jps

# 应该看到类似输出:
# 12345 QuorumPeerMain   (ZooKeeper)
# 12346 Kafka            (Kafka)

如果没有启动,先执行:

bash 复制代码
# 启动 ZooKeeper
cd /opt/module/zookeeper   # 替换成你的 ZooKeeper 路径
bin/zkServer.sh start

# 启动 Kafka
cd /opt/module/kafka        # 替换成你的 Kafka 路径
bin/kafka-server-start.sh -daemon config/server.properties

操作顺序(按步骤执行)


第一步:创建 Topic(只需执行一次)

在任意窗口执行

bash

bash 复制代码
cd /opt/module/kafka
bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic a2608 --partitions 1 --replication-factor 1

验证 Topic 创建成功:

bash 复制代码
bin/kafka-topics.sh --bootstrap-server localhost:9092 --list
# 应该能看到 a2608

第二步:打开 3 个终端窗口

  • 窗口1:Flume

  • 窗口2:Kafka 消费者

  • 窗口3:模拟日志


第三步:窗口2 - 启动 Kafka 消费者(等待数据)

bash 复制代码
cd /opt/module/kafka
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

现象:光标停住不动,没有输出 → ✅ 正常,正在等待数据。

⚠️ 这个窗口保持运行,不要按 Ctrl+C


第四步:窗口1 - 启动 Flume(监控日志文件)

4.1 先准备好日志文件目录
bash 复制代码
mkdir -p /opt/module/flume/data/
touch /opt/module/flume/data/flume.log
4.2 创建 Flume 配置文件
bash 复制代码
mkdir -p /opt/module/flume/job/
vim /opt/module/flume/job/flume-kafka.conf

将以下内容粘贴进去:

properties

bash 复制代码
# define
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# source - 监控日志文件
a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

# sink - 发送到 Kafka
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092
a1.sinks.k1.kafka.topic = a2608
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1

# channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
4.3 启动 Flume
bash 复制代码
cd /opt/module/flume
bin/flume-ng agent -c conf -n a1 -f job/flume-kafka.conf -Dflume.root.logger=INFO,console

现象:会看到一堆启动日志,最后类似:

bash 复制代码
INFO source.ExecSource: Command 'tail -f /opt/module/flume/data/flume.log' started

⚠️ 这个窗口保持运行,不要按 Ctrl+C


第五步:窗口3 - 模拟写入日志数据

bash 复制代码
# 向日志文件写入内容
echo "Hello Kafka" >> /opt/module/flume/data/flume.log
echo "This is test message 1" >> /opt/module/flume/data/flume.log
echo "This is test message 2" >> /opt/module/flume/data/flume.log

模拟写入日志数据没反应,不需要进入什么环境吗


bash 复制代码
Last login: Mon Jun  1 17:50:00 2026 from 192.168.5.1
[hadoop@node100 ~]$ echo "Hello Kafka" >> /opt/module/flume/data/flume.log
[hadoop@node100 ~]$ echo "This is test message 1" >> /opt/module/flume/data/flume.log
[hadoop@node100 ~]$ echo "This is test message 2" >> /opt/module/flume/data/flume.log
[hadoop@node100 ~]$

不需要进入任何特殊环境 !你直接在 Linux 命令行执行 echo 命令就是正确的。


第六步:观察结果

窗口2(Kafka 消费者) 应该会立即显示:

bash 复制代码
Hello Kafka
This is test message 1
This is test message 2

窗口1(Flume) 会显示发送成功的日志。

你的配置文件中 Topic 名称是 one ,但你的消费者监听的是 a2608


问题所在
组件 Topic
Flume 配置 one
Kafka 消费者 a2608

两者不一致,所以消费者收不到消息!


修改 Flume 配置,把 Topic 改为 a2608。

bash 复制代码
sed -i 's/one/a2608/g' /opt/module/flume/job/flume-kafka.conf

# 验证修改结果
cat /opt/module/flume/job/flume-kafka.conf | grep topic

推荐统一使用 a2608


执行以下完整步骤:

步骤1:修改 Flume 配置

bash 复制代码
sed -i 's/one/a2608/g' /opt/module/flume/job/flume-kafka.conf

# 验证
grep "topic" /opt/module/flume/job/flume-kafka.conf
# 应该输出:a1.sinks.k1.kafka.topic = a2608

步骤2:停止 Flume

在窗口1按 Ctrl+C

步骤3:清空日志文件并写入新数据

bash 复制代码
# 窗口3执行
> /opt/module/flume/data/flume.log
echo "Test message 1" >> /opt/module/flume/data/flume.log
echo "Test message 2" >> /opt/module/flume/data/flume.log

步骤4:启动消费者(窗口2)

bash 复制代码
cd $KAFKA_HOME
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

步骤5:启动 Flume(窗口1)

bash 复制代码
cd /opt/module/flume
bin/flume-ng agent -c conf -n a1 -f job/flume-kafka.conf -Dflume.root.logger=INFO,console

步骤6:写入新数据触发发送(窗口3)

bash 复制代码
echo "Trigger new data" >> /opt/module/flume/data/flume.log

步骤7:观察窗口2

应该立即显示 Trigger new data


另外注意:配置文件中的 Kafka 地址


你的配置使用的是 node100:9092,而消费者使用的是 localhost:9092

如果 node100 就是当前机器(hostname 为 node100),那么没问题。


为了确保一致,建议都改成 localhost:9092

bash 复制代码
sed -i 's/node100/localhost/g' /opt/module/flume/job/flume-kafka.conf

# 验证
grep "bootstrap.servers" /opt/module/flume/job/flume-kafka.conf
# 应该输出:a1.sinks.k1.kafka.bootstrap.servers = localhost:9092

验证修复是否成功

执行完上述步骤后,在窗口3执行:

bash 复制代码
echo "Final test" >> /opt/module/flume/data/flume.log

窗口2 应该立即显示 Final test


完整流程图

bash 复制代码
┌─────────────────────────────────────────────────────────────────┐
│                         Linux 服务器                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  窗口3                   窗口1                   窗口2           │
│  ┌────────┐            ┌────────┐            ┌────────┐        │
│  │ echo   │ ──写入──→ │ flume.log │            │        │        │
│  │ 写入   │            │        │            │ Kafka  │        │
│  │ 日志   │            └───┬────┘            │ 消费者 │        │
│  └────────┘                │                 │        │        │
│                            │ tail -f 监控     │ 显示   │        │
│                            ▼                  │ 消息   │        │
│                       ┌────────┐              │        │        │
│                       │ Flume  │ ──发送──→ │ Kafka  │        │
│                       │ Agent  │  数据      │ Topic  │        │
│                       └────────┘              │ a2608  │        │
│                                                └───┬────┘        │
│                                                    │             │
│                                                    │ 消费        │
│                                                    ▼             │
│                                               ┌────────┐        │
│                                               │ 窗口2  │        │
│                                               │ 显示   │        │
│                                               └────────┘        │
└─────────────────────────────────────────────────────────────────┘

常见问题速查

问题 原因 解决方法
消费者启动报错 Connection refused Kafka 没启动 启动 Kafka
消费者启动报错 No such file or directory 不在 Kafka 根目录 cd /opt/module/kafka
消费者启动后没反应 ✅ 正常等待数据 去窗口3写数据
Flume 启动报错 配置文件有问题 检查配置文件路径和内容
消费者收不到消息 Topic 名称不一致 检查 Flume 和消费者中的 topic 名都是 a2608
消费者收不到消息 Kafka 和 Flume 的 bootstrap.servers 不一致 都使用 localhost:9092

快速复盘(命令速查表)

步骤 窗口 命令
创建 Topic 任意 cd /opt/module/kafka && bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic a2608 --partitions 1 --replication-factor 1
启动消费者 窗口2 cd /opt/module/kafka && bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608
创建日志文件 窗口1 mkdir -p /opt/module/flume/data && touch /opt/module/flume/data/flume.log
启动 Flume 窗口1 cd /opt/module/flume && bin/flume-ng agent -c conf -n a1 -f job/flume-kafka.conf -Dflume.root.logger=INFO,console
写入测试数据 窗口3 echo "test" >> /opt/module/flume/data/flume.log

创建 Flume 配置文件这一步,vim进去后卡住了,按i也没有进入编辑状态


这种情况通常是 vim 没有正常启动 或者终端卡住了。教你几种解决方法:

原因分析

最可能的原因是你在 vim 里不小心按了 Ctrl+S(冻结屏幕),或者 vim 启动时出现了问题。


解决方法
方法1:解除终端冻结(最快)

如果你不小心按了 Ctrl+S,终端会被冻结。

按一下 Ctrl+Q 即可解除冻结。

Ctrl+S = 冻结屏幕

Ctrl+Q = 解除冻结

解除后应该能看到 vim 界面,再按 i 进入编辑模式。


方法2:强制退出 vim 重新进入

如果按 Ctrl+Q 没用,按以下步骤强制退出:

bash

复制代码
# 按 Esc 键(确保退出编辑模式)
# 然后输入以下命令强制退出
:q!
# 按回车

如果完全卡死,可以:

bash

复制代码
# 在另一个终端窗口执行,杀掉 vim 进程
pkill -9 vim

然后重新进入:

bash

复制代码
vim /opt/module/flume/job/flume-kafka.conf

方法3:使用 nano(更简单的编辑器)

如果 vim 总是出问题,可以用 nano,对初学者更友好:

bash

复制代码
# 安装 nano(如果没有)
yum install nano -y    # CentOS/RHEL
# 或
apt install nano -y    # Ubuntu

# 使用 nano 编辑
nano /opt/module/flume/job/flume-kafka.conf

nano 操作:

  • 直接输入内容

  • Ctrl+O 保存

  • Ctrl+X 退出


方法4:使用 echo 直接写入文件(最简单)

不需要打开编辑器,直接用命令写入配置:

bash

复制代码
# 先创建目录
mkdir -p /opt/module/flume/job/

# 用 cat 命令直接写入文件
cat > /opt/module/flume/job/flume-kafka.conf << 'EOF'
# define
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

# sink
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092
a1.sinks.k1.kafka.topic = a2608
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1

# channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
EOF

# 验证文件是否创建成功
cat /opt/module/flume/job/flume-kafka.conf

这个方法最可靠,不会卡住。


方法5:检查终端是否正常

如果以上方法都不行,可能是终端会话本身出问题了:

bash

复制代码
# 查看当前终端是否正常
echo "test"

# 如果没反应,说明终端可能卡死,建议:
# 1. 关闭当前终端窗口
# 2. 重新连接 Linux
# 3. 重新开始操作

推荐的完整流程(避免踩坑)

bash

复制代码
# 1. 创建目录
mkdir -p /opt/module/flume/job/

# 2. 用 cat 命令直接创建配置文件(不会卡住)
cat > /opt/module/flume/job/flume-kafka.conf << 'EOF'
a1.sources = r1
a1.sinks = k1
a1.channels = c1

a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092
a1.sinks.k1.kafka.topic = a2608
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1

a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
EOF

# 3. 验证文件内容
cat /opt/module/flume/job/flume-kafka.conf

建议直接用方法4(cat 命令写入) ,最简单且不会出问题。


所有办法都不行,我是关闭了窗口,重新来的。


总结
方法 难度 推荐度
Ctrl+Q 解除冻结 ⭐⭐⭐⭐⭐(先试这个)
:q! 退出 vim ⭐⭐⭐⭐
nano 编辑 ⭐⭐ ⭐⭐⭐⭐
cat 直接写入 ⭐⭐⭐⭐⭐(最推荐)
重启终端 ⭐⭐⭐

窗口2 显示了 Final test,所以Flume是干嘛用的,好像没变化。


太好了!窗口2显示了 Final test,说明整个流程已经跑通了! 🎉


现在回答你的问题:Flume 是干嘛用的?好像没变化?


Flume 在这个流程中的作用

没有 Flume 的情况(你手动做的)

text

复制代码
你手动执行 echo → 直接写入文件 → ? → Kafka 消费者看到消息

等等,这里有个问题:文件本身不会自动发送到 Kafka


有 Flume 的情况(现在运行的)

text

复制代码
你执行 echo → 写入文件 → Flume 监控文件变化 → Flume 发送到 Kafka → 消费者显示消息

Flume 扮演的角色:把"文件中的新数据"自动抓取并发送到 Kafka。


证明 Flume 在工作

你可以做个对比实验:

实验1:停止 Flume,写入数据

bash

复制代码
# 窗口1 按 Ctrl+C 停止 Flume

# 窗口3 写入数据
echo "No Flume test" >> /opt/module/flume/data/flume.log

# 观察窗口2(消费者)→ 不会有任何显示 ❌

实验2:重新启动 Flume,写入数据

bash

复制代码
# 窗口1 重新启动 Flume
cd /opt/module/flume
bin/flume-ng agent -c conf -n a1 -f job/flume-kafka.conf -Dflume.root.logger=INFO,console

# 窗口3 写入数据
echo "With Flume test" >> /opt/module/flume/data/flume.log

# 观察窗口2(消费者)→ 会显示 "With Flume test" ✅

这就是 Flume 的作用! 没有 Flume,文件中的新数据不会自动进入 Kafka。


整个数据流的完整解释

bash 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                           数据流向                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  [你的操作]                                                          │
│     ↓                                                               │
│  echo "test" >> flume.log                                           │
│     ↓                                                               │
│  [Linux 文件]                                                       │
│  /opt/module/flume/data/flume.log                                   │
│     ↓                                                               │
│  [Flume] ← tail -f 监控文件,发现新内容                              │
│     ↓                                                               │
│  Flume 读取新内容,封装成消息                                        │
│     ↓                                                               │
│  Flume 通过 KafkaSink 发送到 Kafka                                  │
│     ↓                                                               │
│  [Kafka] Topic: a2608                                              │
│     ↓                                                               │
│  [Kafka 消费者] 拉取消息                                             │
│     ↓                                                               │
│  [窗口2] 显示消息                                                    │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

为什么你觉得"没变化"?

因为你现在 Flume 一直在运行,所以每次写入文件,Flume 自动帮你发送了。这正是 Flume 的价值所在

场景 你需要做的 Flume 做的
没有 Flume 写文件 + 手动写代码/命令发送到 Kafka
有 Flume 只写文件 自动监控 + 自动发送

Flume 的典型应用场景

  1. 日志收集:服务器上的日志文件 → Flume 监控 → 发送到 Kafka → 供 Spark/Flink 实时分析

  2. 数据集成:多个数据源(文件、网络端口、HTTP)→ Flume 统一收集 → 发送到 Kafka

  3. 解耦:数据生产方只需要写文件,不需要知道 Kafka 的存在


你现在可以做的额外验证

1. 查看 Flume 的发送日志

在 Flume 窗口(窗口1),你应该能看到类似这样的日志:

text

复制代码
INFO kafka.KafkaSink: Sending message to Kafka: Final test

这证明 Flume 确实在发送消息。

2. 确认没有 Flume 时不会自动发送

bash 复制代码
# 停止 Flume(窗口1按 Ctrl+C)

# 写入数据
echo "Flume stopped test" >> /opt/module/flume/data/flume.log

# 观察窗口2 → 不会有消息

# 重启 Flume
# 写入新数据
echo "Flume restarted test" >> /opt/module/flume/data/flume.log

# 观察窗口2 → 会显示

总结

组件 职责 你的感受
你的 echo 命令 产生数据(模拟日志) 主动操作
Flume 监控文件,自动发送到 Kafka 自动化工具,透明工作
Kafka 消息队列,暂存数据 中间件
消费者 显示收到的数据 被动接收

Flume 让你省去了"手动把文件内容发送到 Kafka"这一步。你只管往文件里写数据,Flume 自动帮你送到 Kafka。


这就是它看起来"没变化"但实际很重要的原因------它让数据流转自动化了


老师的课堂笔记中,第一个示例,没有使用flume,好像也能通信。


往队列中发送消息:

--a窗口 bin/kafka-console-producer.sh --broker-list localhost:9092 --topic a2608 消费指定队列中的消息:

--b窗口 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608


你说得完全正确!Kafka 本身就可以直接通信,不需要 Flume


让我帮你理清这两者的区别,以及为什么课堂笔记中要引入 Flume。


Kafka 直接通信(笔记中第一个示例)


操作方式

窗口 角色 命令
窗口A 生产者 bin/kafka-console-producer.sh --broker-list localhost:9092 --topic a2608
窗口B 消费者 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

数据流向

text

复制代码
窗口A(生产者)→ 直接发送 → Kafka → 窗口B(消费者)显示

特点

  • 手动输入消息,手动发送

  • 没有中间环节

  • 适合测试和调试


引入 Flume 的场景(笔记中第二个示例)


为什么需要 Flume?

在实际生产环境中,数据来源不是手动输入的,而是来自:

  • 应用程序日志文件(不断增长)

  • 数据库变更日志

  • 传感器数据

  • 网站访问日志

  • ...

Flume 的作用:自动监控这些数据源,并把数据发送到 Kafka。

数据流向

text

复制代码
日志文件(自动增长)→ Flume(自动监控)→ Kafka → 消费者

特点

  • 自动化,不需要手动输入

  • 适合生产环境的数据采集


对比总结

对比项 Kafka 直接通信 Flume + Kafka
数据来源 手动输入 日志文件/数据源
是否需要人工 每次都要手动输入 自动采集
适用场景 测试、调试 生产环境日志采集
复杂度 简单 稍复杂

两者的关系图

方式1:Kafka 直接通信(手动)

text

复制代码
[你打字] → [Kafka生产者] → [Kafka] → [消费者] → [显示]

方式2:Flume + Kafka(自动)

text

复制代码
[日志文件] → [Flume监控] → [Kafka] → [消费者] → [显示]
     ↑
  echo 写入

实际生产场景举例


场景:监控网站访问日志

没有 Flume

bash

复制代码
# 你需要一直手动执行
cat access.log | kafka-console-producer ...
# 或者写一个定时脚本

有 Flume

bash

复制代码
# Flume 配置文件写一次,永久生效
# 日志每产生一行,Flume 自动发送到 Kafka
# 你什么都不用做

课堂笔记的安排逻辑

  1. 第一个示例:让你理解 Kafka 基本的生产-消费模型

  2. 第二个示例:告诉你实际工作中如何用 Flume 自动化采集数据


Flume 的价值:当你有一个持续产生数据的文件(比如应用程序日志),你不可能每次都手动输入。Flume 帮你自动化这个过程。


你现在已经掌握的技能

✅ Kafka 基本命令(创建 topic、生产、消费)

✅ Flume 配置(source、channel、sink)

✅ Flume 监控文件并发送到 Kafka

✅ 整个数据管道:文件 → Flume → Kafka → 消费者


下一步可以学什么

  1. Flume 其他 Source:监控目录、监听网络端口、读取 HTTP 数据

  2. Kafka 消费者组:多个消费者协同消费

  3. Kafka 分区:提高并发处理能力


简单记忆

  • Kafka 直接通信 = 手动挡汽车(控制感强)

  • Flume + Kafka = 自动驾驶(省心,自动化)

两者各有用途,你现在都学会了!


你前面说的部分没看懂,这里:配置文件中的 Kafka 地址 你的配置使用的是 node100:9092,而消费者使用的是 localhost:9092。 如果 node100 就是当前机器(hostname 为 node100),那么没问题。


问题的本质

localhostnode100 是两个不同的地址写法,它们可能指向同一台机器,也可能指向不同的机器。

地址 含义 实际解析
localhost 本机 永远指向 127.0.0.1(当前这台机器自己)
node100 主机名 取决于 /etc/hosts 或 DNS 的配置

在你的环境中

你的机器主机名是 node100(从提示符 [hadoop@node100 ~]$ 可以看出)。

情况A:localhostnode100 指向同一台机器

如果 /etc/hosts 文件中有这样的配置:

bash

复制代码
cat /etc/hosts

输出:

text

复制代码
127.0.0.1   localhost localhost.localdomain
192.168.x.x node100

那么:

  • localhost → 127.0.0.1(本机环回地址)

  • node100 → 192.168.x.x(本机的实际IP)

虽然指向同一台物理机器,但 Kafka 可能会认为它们是不同的地址,这取决于 Kafka 的配置。


为什么建议统一使用 localhost

1. 避免配置不一致导致的问题

bash

复制代码
# Flume 使用 node100:9092
a1.sinks.k1.kafka.bootstrap.servers = node100:9092

# 消费者使用 localhost:9092
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 ...

潜在问题 :如果 Kafka 配置的 advertised.listeners 只绑定了 localhost,那么 Flume 用 node100 连接可能会失败。

2. 你的实际情况

从你的日志来看,Flume 成功连接到了 Kafka (显示了 Cluster ID),所以你的环境中 node100:9092localhost:9092 都能正常工作。


正确的理解

说法 是否正确 说明
node100localhost 指向同一台机器 ✅ 正确 因为你在 node100 上执行命令
可以混用 ⚠️ 不一定 取决于 Kafka 的监听配置
建议统一 ✅ 正确 避免不必要的麻烦

检查你的 Kafka 监听配置

bash

bash 复制代码
# 查看 Kafka 配置
cat $KAFKA_HOME/config/server.properties | grep listeners

可能的输出:

text

复制代码
# 情况1:只监听了 localhost
listeners=PLAINTEXT://localhost:9092

# 情况2:监听了所有地址
listeners=PLAINTEXT://0.0.0.0:9092

# 情况3:监听了 node100
listeners=PLAINTEXT://node100:9092
  • 情况1 :只能用 localhost 连接

  • 情况2localhostnode100 都可以

  • 情况3 :只能用 node100 连接


最简单的原则

在同一个实验环境中,所有组件使用相同的地址

bash

复制代码
# Flume 配置
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092

# Kafka 消费者
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 ...

# Kafka 生产者
bin/kafka-console-producer.sh --broker-list localhost:9092 ...

全部统一用 localhost,就不会有歧义。


总结

你的问题 答案
node100 是当前机器吗? 是的
可以用 node100 吗? 可以(你的环境能用)
建议用哪个? localhost(更保险,更统一)
为什么之前强调? 因为很多同学混用后会连接失败

在你的环境中,两者都能工作,所以之前的问题(消费者收不到消息)真正的原因是 Topic 名称不一致one vs a2608),而不是地址问题。


Kafka 配置

bash 复制代码
[hadoop@node100 ~]$ cat $KAFKA_HOME/config/server.properties | grep listeners
#     listeners = listener_name://host_name:port
#     listeners = PLAINTEXT://your.host.name:9092
#listeners=PLAINTEXT://:9092
# it uses the value for "listeners" if configured.  Otherwise, it will use the value
#advertised.listeners=PLAINTEXT://your.host.name:9092
[hadoop@node100 ~]$

你的 Kafka 配置显示:

properties

复制代码
#listeners=PLAINTEXT://:9092

这行被注释掉了 (前面有 #)。


这意味着什么?

listeners 被注释掉时,Kafka 使用默认配置PLAINTEXT://:9092(监听所有网络接口)。

默认配置的效果

连接方式 是否可用 原因
localhost:9092 ✅ 可用 本机环回地址
127.0.0.1:9092 ✅ 可用 本机IP
node100:9092 ✅ 可用 主机名解析到本机IP

结论 :你的环境中,localhostnode100 都可以正常连接 Kafka


为什么两种写法都能用?

Kafka 监听的是 0.0.0.0(所有网络接口):

text

bash 复制代码
┌─────────────────────────────────────────────────────┐
│                   你的机器 node100                   │
│                                                     │
│  ┌─────────────┐                                    │
│  │  localhost  │ ← 127.0.0.1 (环回地址)            │
│  │   127.0.0.1 │                                    │
│  └─────────────┘                                    │
│                                                     │
│  ┌─────────────┐                                    │
│  │   node100   │ ← 192.168.x.x (实际IP)            │
│  │  192.168.x.x│                                    │
│  └─────────────┘                                    │
│                                                     │
│         ↓ 都指向同一台机器 ↓                         │
│                                                     │
│  ┌─────────────────────────────────────────────┐   │
│  │           Kafka (监听 0.0.0.0:9092)          │   │
│  │        接受所有网络接口的连接                  │   │
│  └─────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘

总结你之前的成功

你最终成功时:

  • Flume 配置:node100:9092

  • 消费者配置:localhost:9092

两者都能工作,因为它们最终都连接到了同一个 Kafka 实例。


实际建议

虽然两者都能用,但为了配置的统一和可移植性,建议:

properties

复制代码
# Flume 配置
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092

原因:

  1. localhost 在任何机器上都指向本机

  2. 配置文件复制到其他机器不用修改

  3. 更清晰地表达"Kafka 和 Flume 在同一台机器"


你的 Kafka 配置说明

配置项 你的状态 效果
listeners 注释掉(使用默认) 监听所有网络接口
advertised.listeners 注释掉 使用 listeners 的值

这是最简单、最灵活的配置方式,适合学习环境。


现在一切清楚了吗?你的环境配置是正确的,之前的 Topic 名称不匹配是唯一的问题。恭喜你成功跑通了整个流程!🎉


本机环回地址是什么意思


本机环回地址(Loopback Address)

简单理解 :就是指向自己这台电脑的IP地址


最常见的环回地址

地址 格式 说明
127.0.0.1 IPv4 最常用的环回地址
::1 IPv6 IPv6版本的环回地址
localhost 域名 自动解析到 127.0.0.1

通俗比喻

想象你的电脑是一个带信箱的房子

地址类型 比喻 说明
192.168.1.100(实际IP) 房子的门牌号 别人通过这个地址找到你
127.0.0.1(环回地址) 房子内部的传话管道 你自己跟自己通信

环回地址就像你对自己说话:不需要出门,不需要经过邻居,直接传递信息。


实际效果

bash

复制代码
# 这两种方式都会连接到你自己这台机器的 Kafka
ping 127.0.0.1    # 数据包不经过网卡,直接在系统内部转发
ping localhost    # 解析成 127.0.0.1
ping node100      # 实际IP,数据包会经过网卡

图示理解

text

bash 复制代码
┌─────────────────────────────────────────────────┐
│                   你的电脑                       │
│                                                 │
│   应用程序A ──→ 127.0.0.1:9092 ──→ 应用程序B    │
│              (环回地址)                         │
│               ⬆ 内部直接传递                    │
│               ⬆ 不经过网卡                      │
│               ⬆ 速度非常快                      │
│                                                 │
│   应用程序A ──→ 192.168.1.100:9092 ──→ 应用程序B │
│              (实际IP)                          │
│               ⬆ 数据先发出网卡                  │
│               ⬆ 再绕回来接收                    │
│               ⬆ 相对慢一些                      │
│                                                 │
└─────────────────────────────────────────────────┘

为什么需要环回地址?

场景 说明
本地测试 开发时不需要实际网络,直接测试程序
服务通信 电脑上多个服务互相访问(如 Kafka → ZooKeeper)
速度更快 不经过网卡,纯内存操作
不受网络影响 网线拔了也能用

在你的 Kafka 实验中

bash

复制代码
# 消费者使用 localhost:9092
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic a2608

效果

  • Kafka 客户端程序通过 127.0.0.1 连接

  • 数据不经过网卡

  • 直接在系统内部传递

  • 速度和稳定性最好


验证环回地址

bash

复制代码
# 查看 localhost 解析成什么
ping -c 1 localhost
# 输出:PING localhost (127.0.0.1) ...

# 查看所有网络接口
ifconfig lo
# lo 就是环回接口(loopback)
# 通常显示:inet 127.0.0.1

总结

概念 一句话解释
环回地址 指向你自己的IP地址
127.0.0.1 最常用的环回地址
localhost 127.0.0.1 的域名别名
用途 本机内部通信,不需要真实网络

记忆口诀:环回环回,掉头就回,不往外跑,自己和自己开会。


你的配置文件中 Topic 名称是 one,但你的消费者监听的是 a2608。详细解释一下配置文件中各行的作用,因为不熟悉,所以最开始看不出来错误在哪。


非常好的问题!学习新框架时,不理解配置的含义是最大的障碍。我来逐行解释 Flume 配置文件,并说明为什么 Topic 不匹配会出问题。


Flume 配置文件完整解析

配置文件结构

Flume 配置由三大部分组成:Source(来源)Channel(通道)Sink(去向)

text

复制代码
数据流向:Source → Channel → Sink

第一部分:定义组件名称

properties

复制代码
# define
a1.sources = r1
a1.sinks = k1
a1.channels = c1
配置项 含义 说明
a1 Agent 名称 Flume 进程的名称,可以任意起名
sources 数据来源组件 定义有哪些数据源(可以有多个)
r1 Source 名称 给这个数据源起个名字,可以任意起名
sinks 数据去向组件 定义数据要发送到哪里(可以有多个)
k1 Sink 名称 给这个数据去向起个名字
channels 通道组件 定义 Source 和 Sink 之间的缓冲区
c1 Channel 名称 给这个通道起个名字

通俗理解

我有一个叫 a1 的 Flume 进程,它从 r1 读取数据,通过 c1 通道,发送到 k1


第二部分:配置 Source(数据来源)

properties

复制代码
# source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log
配置项 含义
a1.sources.r1.type exec Source 类型是"执行Linux命令"
a1.sources.r1.command tail -f /opt/module/flume/data/flume.log 执行的命令是监控这个文件的变化

通俗理解

执行 tail -f 命令,持续监控 /opt/module/flume/data/flume.log 这个文件,文件有新内容就读取出来。

其他可能的 Source 类型

  • spooldir:监控整个目录,有新文件就读取

  • netcat:监听网络端口

  • http:接收 HTTP 请求


第三部分:配置 Sink(数据去向)

properties

复制代码
# sink
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = node100:9092
a1.sinks.k1.kafka.topic = one
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1
配置项 含义
a1.sinks.k1.type org.apache.flume.sink.kafka.KafkaSink Sink 类型是 Kafka(数据发送到 Kafka)
a1.sinks.k1.kafka.bootstrap.servers node100:9092 Kafka 服务器地址(告诉 Flume Kafka 在哪)
a1.sinks.k1.kafka.topic one 发送到 Kafka 的哪个 Topic ⚠️ 这里是关键!
a1.sinks.k1.kafka.flumeBatchSize 20 每次批量发送多少条消息
a1.sinks.k1.kafka.producer.acks 1 消息确认级别(1 = 等待 Leader 确认)
a1.sinks.k1.kafka.producer.linger.ms 1 发送前等待更多消息的时间(毫秒)

通俗理解

把数据发送到 node100 这台机器的 Kafka,放进名叫 one 的 Topic 里。


第四部分:配置 Channel(通道/缓冲区)

properties

复制代码
# channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
配置项 含义
a1.channels.c1.type memory Channel 类型是"内存"(数据暂存在内存中)
a1.channels.c1.capacity 1000 通道最大能存储多少条消息
a1.channels.c1.transactionCapacity 100 每次事务最多处理多少条消息

通俗理解

在 Source 和 Sink 之间放一个临时仓库,Source 读取的数据先放这里,Sink 从这里取走发送。容量 1000 条,每次最多处理 100 条。


第五部分:绑定组件(组装起来)

properties

复制代码
# bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
配置项 含义
a1.sources.r1.channels = c1 Source r1 把数据发到 Channel c1
a1.sinks.k1.channel = c1 Sink k1 从 Channel c1 取数据

通俗理解

把 Source、Channel、Sink 连接起来,形成完整的数据流。


为什么 Topic 不匹配会导致收不到消息?

数据流向图

text

bash 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                        你的 Flume 配置                               │
│                                                                      │
│   flume.log ──→ [Source] ──→ [Channel] ──→ [Sink]                  │
│                    │                      │                         │
│                    │                      ↓                         │
│                    │              发送到 Kafka                       │
│                    │              Topic = "one" ←─── ⚠️ 关键        │
│                    │                                                │
└────────────────────│────────────────────────────────────────────────┘
                     │
                     ↓
              ┌─────────────┐
              │   Kafka     │
              │  Topic: one │ ← Flume 把数据发到这里
              └─────────────┘
                     
                     
┌─────────────────────────────────────────────────────────────────────┐
│                        你的消费者命令                                │
│                                                                      │
│   bin/kafka-console-consumer.sh --topic a2608                      │
│                                        ↑                            │
│                                   ⚠️ 从 Topic "a2608" 读           │
│                                                                      │
│   Kafka 收到消费请求:从 "a2608" 读数据                              │
│   但数据都在 "one" 里 → 没有数据 → 什么都不显示                      │
└─────────────────────────────────────────────────────────────────────┘

类比理解

把 Kafka 想象成一个停车场

概念 类比
Topic 停车场里的不同区域(A区、B区、C区)
Flume 一辆送客的车
消费者 一辆接客的车

你的配置

  • Flume(送客车)把客人送到 "one" 区

  • 消费者(接客车)去 "a2608" 区 接客人

结果:接客车永远接不到人 ❌

修复后

  • Flume 把客人送到 "a2608" 区

  • 消费者也去 "a2608" 区 接人

结果:成功接到人 ✅


如何快速发现这种错误?

1. 查看 Flume 启动日志

**Flume 启动时会显示配置信息,但没有直接显示 Topic 名称。**不过你可以:

bash

复制代码
# 查看 Flume 完整配置
cat /opt/module/flume/job/flume-kafka.conf | grep topic

2. 查看 Kafka 中的 Topic 列表

bash

复制代码
cd $KAFKA_HOME
bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

这会显示所有存在的 Topic。你可能会发现:

  • one(Flume 发送的)

  • a2608(消费者监听的)

两个都存在,但数据只在一个里面。

3. 消费时加 --from-beginning

bash

复制代码
# 尝试消费 one
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic one --from-beginning

# 如果看到你的测试消息,说明 Flume 工作正常,只是 Topic 不对

配置文件模板(带注释)

properties

bash 复制代码
# ========== 1. 定义组件名称 ==========
# Agent名称.sources = Source名称
a1.sources = r1

# Agent名称.sinks = Sink名称  
a1.sinks = k1

# Agent名称.channels = Channel名称
a1.channels = c1

# ========== 2. 配置Source ==========
# Source类型:exec = 执行Linux命令
a1.sources.r1.type = exec

# Source执行的命令:监控文件新增内容
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

# ========== 3. 配置Sink ==========
# Sink类型:Kafka Sink
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink

# Kafka服务器地址(多个用逗号分隔)
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092

# ⚠️ 重要:发送到Kafka的哪个Topic
a1.sinks.k1.kafka.topic = a2608

# 批量发送大小
a1.sinks.k1.kafka.flumeBatchSize = 20

# 消息确认级别
a1.sinks.k1.kafka.producer.acks = 1

# 延迟发送时间(毫秒)
a1.sinks.k1.kafka.producer.linger.ms = 1

# ========== 4. 配置Channel ==========
# Channel类型:内存
a1.channels.c1.type = memory

# 最大消息数量
a1.channels.c1.capacity = 1000

# 事务最大处理数
a1.channels.c1.transactionCapacity = 100

# ========== 5. 绑定组件 ==========
# Source绑定Channel
a1.sources.r1.channels = c1

# Sink绑定Channel
a1.sinks.k1.channel = c1

总结:你犯的错误和学到的经验

错误 原因 如何避免
Flume 用 Topic one,消费者用 a2608 配置文件中的 topic 参数被忽略 检查配置文件中的每个参数

经验教训

  1. 配置文件中的每一行都有意义

  2. 排错时逐项检查每个参数是否匹配

  3. grep 快速查看关键配置

  4. --list 查看 Kafka 中实际存在的 Topic

现在你应该能看懂 Flume 配置了!有问题随时问。


还有一个疑问,最开始创建 Flume 配置文件这一步不是重复了很多次,但每次打开配置文件都还在。是教室环境,使用的统一安装的虚拟机环境,跟这个有关系吗,我想的是正常情况应该会提醒重复创建,或者打开配置文件是空白才对。以下命令执行了多次都没有报错 mkdir -p /opt/module/flume/data/ touch /opt/module/flume/data/flume.log mkdir -p /opt/module/flume/job/ 这个文件/opt/module/flume/job/flume-kafka.conf打开每次都有内容,我看不懂,所以就没有修改。好像是老师提前写好的。


为什么重复执行命令没有报错?


mkdir -p 不报错的原因

bash

复制代码
mkdir -p /opt/module/flume/data/
情况 mkdir -p 的行为 是否报错
目录不存在 创建目录 ✅ 正常
目录已存在 什么都不做,直接返回成功 ✅ 不报错

-p 参数的作用

  • -p = parents(父目录)

  • 如果目录存在,静默跳过,不报错也不覆盖

  • 所以执行多次完全没问题

没有 -p 的情况

bash

复制代码
mkdir /opt/module/flume/data/   # 第一次执行:成功
mkdir /opt/module/flume/data/   # 第二次执行:报错 "File exists"

touch 不报错的原因

bash

复制代码
touch /opt/module/flume/data/flume.log
情况 touch 的行为 是否报错
文件不存在 创建空文件 ✅ 正常
文件已存在 更新文件的修改时间戳 ✅ 不报错(不会清空内容)

touch 不会覆盖或清空文件内容,只会更新时间戳。


为什么配置文件每次打开都有内容?


你猜对了!这是教室环境老师提前准备好的

可能的情况

可能性 说明
老师预置的 老师为了教学方便,提前把配置写好了放在 /opt/module/flume/job/flume-kafka.conf
共享虚拟机镜像 所有同学用的是同一个虚拟机镜像,文件本来就存在
之前的实验残留 这个教室环境可能被多次使用,文件一直保留着

验证文件是什么时候创建的

bash

复制代码
# 查看文件的创建/修改时间
ls -l /opt/module/flume/job/flume-kafka.conf

# 输出示例:
# -rw-r--r-- 1 hadoop hadoop 1024 May 20 10:30 flume-kafka.conf
#                            ↑
#                     这个时间是文件最后修改时间

如果时间比你上课时间还早,说明是老师提前放好的。

bash

复制代码
# 查看文件内容中的注释
cat /opt/module/flume/job/flume-kafka.conf | head -5

如果有一些教学性质的注释(比如 # 这是Kafka Sink示例),更说明是老师准备的。


老师为什么提前放好配置文件?

原因 说明
节省时间 不需要每个同学从头敲配置,可以专注讲解
避免错误 防止同学敲错配置导致实验失败
统一环境 保证所有人的配置一致,方便教学
初学者友好 让你先跑通流程,之后再学配置细节

你应该怎么做?

1. 理解配置内容(你已经通过之前的学习做到了)

2. 修改配置来验证理解

bash

bash 复制代码
# 先备份原配置
cp /opt/module/flume/job/flume-kafka.conf /opt/module/flume/job/flume-kafka.conf.bak

# 修改 topic 名称(你现在已经知道这个很重要了)
vim /opt/module/flume/job/flume-kafka.conf
# 或者用 sed 命令
sed -i 's/one/a2608/g' /opt/module/flume/job/flume-kafka.conf

3. 自己手写一个配置文件

bash

bash 复制代码
# 创建你自己的配置文件
cat > /opt/module/flume/job/my-flume-kafka.conf << 'EOF'
a1.sources = r1
a1.sinks = k1
a1.channels = c1

a1.sources.r1.type = exec
a1.sources.r1.command = tail -f /opt/module/flume/data/flume.log

a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = localhost:9092
a1.sinks.k1.kafka.topic = a2608

a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
EOF

# 使用你自己的配置文件运行
bin/flume-ng agent -c conf -n a1 -f job/my-flume-kafka.conf -Dflume.root.logger=INFO,console

总结:你问的这个问题说明你学得很好

你的疑问 说明
"命令执行多次没报错" 你注意到了命令的幂等性(多次执行结果相同)
"文件每次打开都有内容" 你发现了环境预置的事实
"看不懂所以没修改" 谨慎对待不懂的内容,这是好习惯

现在你懂了配置的含义,就可以大胆修改了!


学习建议

作为初学者,这种教学环境的安排是合理的:

  1. 先跑通流程(用老师给的配置)→ 建立信心

  2. 再理解配置(我们刚才做的)→ 深入原理

  3. 最后自己写(课后练习)→ 真正掌握

你现在已经完成了第2步,可以进入第3步了!

就以上问答,重新总结Kafka课堂笔记,方便日后复习。


(课堂笔记)Kafka + Flume 完整实战

相关推荐
JAVA面经实录9172 小时前
Kafka 全套学习知识手册
java·kafka
是小王同学啊~21 小时前
Kafka 面试通关笔记:高频八股 + 生产实战 + 追问链路(上)
笔记·面试·kafka
Devin~Y1 天前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
Hello_worlds1 天前
Kafka InconsistentClusterIdException 导致容器无限重启,磁盘打满排查与修复
docker·kafka·磁盘·排障
007张三丰1 天前
AIoT与嵌入式系统深度解析:2026软考案例核心考点全攻略
物联网·mqtt·kafka·freertos·时序数据库·tdengine·aiot
jiayong232 天前
Kafka 高吞吐消息链路常见面试问题及详细解答
分布式·面试·kafka
段一凡-华北理工大学2 天前
工业领域的Hadoop架构学习~系列文章05:Kafka消息队列 - 工业数据流传输
人工智能·hadoop·学习·架构·kafka·工业智能体·高炉炼铁智能化
Irene19913 天前
Flume 中的 Agent(JVM进程)= Source(数据读取) + Channel(数据缓冲) + Sink(数据写入)
大数据·flume
西安邮电大学3 天前
Kafka保证消息顺序性
java·后端·kafka