Skip to content
安装与配置

安装与配置

Kafka 在 Windows 下的两种安装方式(Zookeeper 模式 / KRaft 模式)、启停脚本,以及 Broker / Topic / JVM 核心配置参数详解。

适用 Kafka 版本: 3.x(ZooKeeper 遗留模式)/ 4.x(纯 KRaft,当前最新 4.3.x)。Kafka 4.0 起 ZooKeeper 模式已彻底移除,Broker 端要求 Java 17+。


Windows

方式一:Zookeeper 模式(Kafka 3.x 及之前)

注意:Kafka 4.0(2025-03)起已完全移除 ZooKeeper 支持,本节仅适用于维护 3.x 存量集群;3.9 是唯一兼容两种模式的过渡版本,新装 3.x 也应直接用 KRaft。

Kafka 下载地址

Windows 选择 Binary download,推荐选择稳定版本。

配置步骤

  1. 在 Kafka 根目录中创建一个 kafka-logs 目录,用于存放消息日志:

    image-20260515110846181

  2. 配置 config 目录下的 server.properties 文件:

    # 指定日志存储路径
    log.dirs=/kafka-logs

    注意:路径中使用正斜杠 /,避免 Windows 反斜杠转义问题。

启动 Zookeeper

注意:Kafka 默认解压后的目录名较长,在 Windows 下可能因路径过长导致命令执行失败。建议将 Kafka 根目录重命名为短名称,例如 kafka。

image-20260515111833115

进入 Kafka 根目录,执行:

# 启动 Zookeeper(第一个窗口)
.\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties

image-20260515112001334

看到上述日志输出即表示 Zookeeper 启动成功。

启动 Kafka

保持 Zookeeper 窗口不关闭,新建一个 cmd 窗口,进入 Kafka 根目录,执行:

# 启动 Kafka Broker(第二个窗口)
.\bin\windows\kafka-server-start.bat .\config\server.properties

等待片刻,看到如下日志即表示 Kafka Broker 启动成功:

image-20260515112425379

启停注意事项

Caution

重要:必须使用 Kafka 提供的 xxx-stop.bat 脚本来关闭服务。 不要直接 Ctrl+C 或关闭窗口!不要直接 Ctrl+C 或关闭窗口!不要直接 Ctrl+C 或关闭窗口!

直接杀进程可能导致日志文件损坏或元数据不一致。

一键启动脚本

将以下内容保存为 start-kafka.bat,注意将 KAFKA_HOME 替换为你的实际路径:

@echo off
chcp 65001 > nul
TITLE Kafka 启动器 - kafka_2.13-3.9.0

SETLOCAL

set KAFKA_HOME=D:\dev\Kafka\kafka

if not exist "%KAFKA_HOME%" (
    echo ❌ 错误:KAFKA_HOME 路径不存在: %KAFKA_HOME%
    pause
    exit /b 1
)

cd /d %KAFKA_HOME%

:: 清理残留的锁文件和 PID 文件(防止上次异常退出导致启动冲突)
if exist "logs\*.lock" del /Q "logs\*.lock"
if exist "logs\*.pid"  del /Q "logs\*.pid"

:: 启动 ZooKeeper
echo ▶️ 正在启动 ZooKeeper...
start "ZooKeeper" /D "%KAFKA_HOME%" call bin\windows\zookeeper-server-start.bat config\zookeeper.properties

:: 等待 ZooKeeper 初始化完成
timeout /t 7 > NUL

:: 启动 Kafka
echo ▶️ 正在启动 Kafka Server...
call bin\windows\kafka-server-start.bat config\server.properties

echo ✅ Kafka 已成功启动!
pause
一键关闭脚本

将以下内容保存为 stop-kafka.bat:

@echo off
chcp 65001 > nul
TITLE Kafka 关闭器 - kafka_2.13-3.9.0

SETLOCAL

set KAFKA_HOME=D:\dev\Kafka\kafka

if not exist "%KAFKA_HOME%" (
    echo ❌ 错误:KAFKA_HOME 路径不存在: %KAFKA_HOME%
    pause
    exit /b 1
)

cd /d %KAFKA_HOME%

:: 优雅停止 Kafka
echo ⏹️ 正在尝试优雅地停止 Kafka...
call "%KAFKA_HOME%\bin\windows\kafka-server-stop.bat"

:: 等待 Kafka 进程结束(最多等待 30 秒)
call :wait_for_process_exit "kafka" 30
if errorlevel 1 (
    echo ⚠️ Kafka 进程未能在指定时间内退出,请检查日志或手动终止。
)

:: 优雅停止 ZooKeeper
echo ⏹️ 正在尝试优雅地停止 ZooKeeper...
call "%KAFKA_HOME%\bin\windows\zookeeper-server-stop.bat"

:: 等待 ZooKeeper 进程结束(最多等待 30 秒)
call :wait_for_process_exit "zookeeper" 30
if errorlevel 1 (
    echo ⚠️ ZooKeeper 进程未能在指定时间内退出,请检查日志或手动终止。
)

echo ✅ Kafka 和 ZooKeeper 已尝试优雅关闭。
pause
exit /b 0


:: ============ 函数区 ============

:: 等待指定关键字的 Java 进程退出
:wait_for_process_exit
setlocal
set keyword=%~1
set timeout=%~2
set count=0

echo 🔍 正在等待 [%keyword%] 进程退出,最多等待 %timeout% 秒...

:loop
tasklist | findstr /i java >nul && (
    tasklist | findstr /i %keyword% >nul && (
        if %count% lss %timeout% (
            timeout /t 1 >nul
            set /a count+=1
            goto loop
        ) else (
            endlocal
            exit /b 1
        )
    )
)

endlocal
exit /b 0

安装注意事项与常见问题

1. 目录与路径

  • 避免路径中包含空格和特殊字符(如中文、括号等)
  • Windows 路径有长度限制(260 字符),建议将 Kafka 放在盘符根目录下
  • 配置文件中使用正斜杠 / 替代反斜杠 \

2. 内存与 JVM 配置

  • Kafka 默认 JVM 堆内存较大(1GB+),本地开发可根据机器配置适当调小 KAFKA_HEAP_OPTS
  • JDK 版本匹配:Kafka 3.x 支持 JDK 8/11/17;Kafka 4.x 的 Broker/Controller/命令行工具要求 JDK 17+(Java 客户端最低 JDK 11)。本地开发直接装 JDK 17 或 21 最省心

3. KRaft 模式

  • Kafka 4.x 开始默认采用 KRaft 模式管理集群(不再依赖 Zookeeper)
  • 启动前必须执行 kafka-storage.bat format 格式化元数据,否则 Broker 会因找不到 meta.properties 文件而启动失败
  • 在 server.properties 中,process.roles 决定节点的角色:broker(存储数据)、controller(管理集群)或 broker,controller(两者兼有)。本地单机测试建议保持默认即可

参考资料:Windows 下 Kafka 安装教程(保姆级)


方式二:KRaft 模式(Kafka 4.x 推荐,无需 Zookeeper)

KRaft(Kafka Raft)是 Kafka 自 3.x 开始引入的元数据管理协议,用于替代 Zookeeper。在 4.x 版本中已成为默认模式。

使用 Scoop 安装

scoop search kafka
scoop install kafka

配置步骤

1. 配置日志生成路径

  • 在 Kafka 目录中创建一个日志文件夹:

    image-20260630145717279

  • 修改 server.properties,将 log.dirs 指向该路径:

    image-20260630145854720

    注意:Windows 下路径中的反斜杠需要使用 \\ 进行转义。

2. 生成集群 ID

kafka-storage.bat random-uuid

执行后会生成一串 UUID,将其复制下来备用。

image-20260630150019216

3. 格式化元数据日志目录

这一步告诉 Kafka 当前节点在集群中的角色以及如何初始化共识机制:

kafka-storage.bat format -t <你的集群ID> -c ..\..\config\server.properties --standalone

参数说明:

参数 含义
--standalone 单机模式。Kafka 自动将 node.id 设为 0,并自动配置 controller.quorum.voters 指向自己(0@localhost:9093),无需手动修改 server.properties 中的集群配置
--initial-controllers 多节点集群。手动指定初始控制器列表,需要明确告诉 Kafka 哪些节点是 Controller 及其地址
--no-initial-controllers 不在此阶段初始化控制器信息,完全依赖 server.properties 中的 controller.quorum.voters 配置

image-20260630150751921

执行格式化命令后,日志目录下会生成三个文件夹(图中因为已经运行过,所以会多一些运行时文件)。

4. 启动 Kafka

kafka-server-start.bat ..\..\config\server.properties

image-20260630150941709

出现以上日志提示即表示 Kafka 启动成功。


Linux(KRaft,生产主流形态)

以 Kafka 4.3 二进制包为例(Scala 2.13 版本 kafka_2.13-4.3.0.tgz,要求 JDK 17+):

# 下载解压
tar -xzf kafka_2.13-4.3.0.tgz -C /opt/ && ln -s /opt/kafka_2.13-4.3.0 /opt/kafka
export PATH=$PATH:/opt/kafka/bin

单机最小配置改 /opt/kafka/config/kraft/server.properties 这几处:

process.roles=broker,controller
node.id=1
listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
controller.quorum.voters=1@localhost:9093
log.dirs=/data/kafka-logs
num.partitions=6
default.replication.factor=1        # 单机只能 1;集群按 08 章改 3
auto.create.topics.enable=false     # 生产强烈建议关闭

初始化并启动(与 Windows 同理,format 只做一次):

CLUSTER_ID=$(kafka-storage.sh random-uuid)
kafka-storage.sh format -t $CLUSTER_ID -c /opt/kafka/config/kraft/server.properties
kafka-server-start.sh -daemon /opt/kafka/config/kraft/server.properties

生产部署建议用 systemd 托管(要点:Type=simple、Restart=on-failure、数据目录与 /var/lib/kafka 一致、LimitNOFILE=100000);关闭永远走 kafka-server-stop.sh,kill -9 会导致日志截断恢复(陷阱 #17)。多节点集群搭建见 12-集群与高可用。

Docker

官方镜像 apache/kafka(内置 KRaft,自动注入 CLUSTER_ID 与 node id)单机最省事,本地开发/联调推荐:

# docker-compose.yml
services:
  kafka:
    image: apache/kafka:4.3.0
    ports:
      - "9092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1     # 单机被迫 1;生产务必 ≥3(06 章)
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
      KAFKA_LOG_DIRS: /var/lib/kafka/data
    volumes:
      - kafka-data:/var/lib/kafka/data

volumes:
  kafka-data:
docker compose up -d kafka

# 进容器执行管理命令(脚本都在 /opt/kafka/bin)
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --create \
  --topic order-events --partitions 3 --replication-factor 1 \
  --bootstrap-server localhost:9092

三个常见坑:

  1. 宿主机连不上容器内 Kafka:容器内监听 0.0.0.0 没用,关键是 KAFKA_ADVERTISED_LISTENERS——客户端拿到的地址是它。localhost:9092 只适合"宿主机跑客户端";容器间互访要改成 PLAINTEXT://kafka:9092(compose 网络内域名),跨机器部署则写宿主机可达 IP/域名。要"宿主机 + 容器网络"同时可达就配 INTERNAL/EXTERNAL 双 listener。
  2. 数据丢失:不挂 volume 时容器一删日志全没;volume 路径必须与 KAFKA_LOG_DIRS 一致。
  3. 镜像内 offsets.topic.replication.factor 等内部 Topic 参数单机只能设小,别把这套 compose 原样抄进生产(副本/ISR 参数对照 08/12 章)。

bitnami/kafka 等第三方镜像用法类似(环境变量前缀不同),注意 bitnami 策略调整后的镜像 tag 归属变化,优先官方镜像。

Kafka 重要配置

Broker 端配置

broker.id

每个 Broker 的唯一标识符,默认值为 0。在集群中必须唯一,可以设为任意整数值。

port

Kafka 默认监听 9092 端口。可修改为任意端口,但注意使用 1024 以下的端口需要 root 权限。

zookeeper.connect(Zookeeper 模式)

指定 Zookeeper 地址,格式为 hostname:port/path。多个地址用逗号分隔。

  • hostname:Zookeeper 服务器的机器名或 IP
  • port:Zookeeper 客户端端口(默认 2181)
  • /path:可选的 Zookeeper 路径(chroot 环境)。如果不指定,默认使用根路径。

示例:如果有两套 Kafka 集群 kafka1 和 kafka2,可以这样配置:

  • kafka1:zk1:2181,zk2:2181,zk3:2181/kafka1
  • kafka2:zk1:2181,zk2:2181,zk3:2181/kafka2

log.dirs

Kafka 将所有消息持久化到磁盘,日志片段的存放目录通过 log.dirs 指定(用逗号分隔多个本地路径)。此参数没有默认值,必须手动指定。

还有一个 log.dir 参数(不含末尾的 s),一般情况下只配置 log.dirs 即可。例如:/home/kafka1,/home/kafka2,/home/kafka3

num.recovery.threads.per.data.dir

在以下三种情况下,Kafka 会使用可配置的线程池来处理日志片段:

  • 服务器正常启动,打开每个分区的日志片段
  • 服务器崩溃后重启,检查和截断每个分区的日志片段
  • 服务器正常关闭,关闭日志片段

默认每个日志目录只使用 1 个线程。对于分区数量较多的服务器,增大此值可以显著缩短崩溃恢复时间(可能省下数小时)。注意:该数值对应的是每个日志目录的线程数。例如设为 8 且 log.dirs 指定了 3 个路径,则总共需要 24 个线程。

auto.create.topics.enable

默认情况下,Kafka 在以下三种场景会自动创建不存在的 Topic:

  • 生产者开始往某个 Topic 写入消息
  • 消费者开始从某个 Topic 读取消息
  • 任意客户端向某个 Topic 发送元数据请求

建议:生产环境将 auto.create.topics.enable 设为 false,避免因拼写错误意外创建 Topic。


Topic 默认配置

Kafka 为新创建的主题提供了丰富的默认配置参数:

num.partitions

新创建 Topic 的默认分区数,默认值为 1。

注意:分区数可以后续增加,但不能减少。创建时应合理预估分区数。

default.replication.factor

消息的默认副本数,默认值为 1。如果副本失效,其他副本可以继续提供服务。该参数仅在启用了自动创建 Topic 时有效。

log.retention.ms

Kafka 根据时间判断数据可以保留多久。log.retention.ms 是最推荐使用的配置参数(另有 log.retention.hours 和 log.retention.minutes,作用相同),默认值为 168 小时(7 天)。

log.retention.bytes

按磁盘空间大小判断消息是否过期。该参数作用在每个分区上。例如,一个 8 分区的 Topic,log.retention.bytes 设为 1GB,则 Topic 最多保留 8GB 数据。分区数增加时,整个 Topic 可保留的总数据量也随之增加。

log.segment.bytes

日志是按"片段(Segment)“管理的。当消息到达 Broker 时,它们被追加到当前片段。当片段大小达到 log.segment.bytes 上限(默认 1GB)时,当前片段被关闭并创建新片段。被关闭的片段开始等待过期清理。该值设得太小会导致频繁关闭和创建新文件,降低磁盘写入效率。

log.segment.ms

指定日志片段在多长时间后被强制关闭。和 log.segment.bytes 不互斥——哪个条件先触发就按哪个执行。

message.max.bytes

限制单条消息的最大大小(压缩后),默认 1MB。如果生产者发送超过此限制的消息,Broker 会拒绝并返回错误。

该值越大,处理网络连接和请求的线程耗时越长,磁盘写入块也越大,影响 I/O 吞吐量。

retention.ms(Topic 级别)

指定该 Topic 的消息保存时长,默认 7 天。该值设置后会覆盖 Broker 端的全局参数。

retention.bytes(Topic 级别)

指定为该 Topic 预留的最大磁盘空间。默认值 -1 表示无限使用。多租户 Kafka 集群中特别有用。


JVM 参数配置

JDK 版本:Kafka 4.x Broker 必须 JDK 17+(Java 8/11 已从服务端支持矩阵移除);3.x 存量集群才涉及 JDK 8 调优话题。

堆内存(Heap Size)

业界广泛推荐直接将 JVM 堆大小设为 6GB,这样能避免很多内存相关的异常。Kafka 大部分"缓存"其实靠 OS page cache(见 11 章零拷贝链路),堆开太大反而挤占 page cache、加重 GC 停顿——6GB 是经验甜点位,不要盲目加码。

垃圾回收器(GC)选择

  • Java 8 及以上、以及所有 Kafka 4.x 部署 → 直接使用默认的 G1 收集器即可,无需调优参数;
  • 极端延迟敏感的大堆场景(JDK 17+)可以评估分代 ZGC(-XX:+UseZGC -XX:+ZGenerational),以更高 CPU 换取亚毫秒级 GC 停顿——先压测再上,不是默认答案。

G1 的两个关键参数:

参数 说明 默认值
MaxGCPauseMillis 每次 GC 的目标停顿时间。G1 会根据需要调整,非硬性上限 200ms
InitiatingHeapOccupancyPercent 堆使用率达到该百分比时触发新一轮 GC(包括新生代和老年代) 45

参考资料