Kafka4.0 KRaft 模式分布式搭建

1,211 阅读7分钟

概述

Kafka集群的基本安装过程

架构

基于本地环境的配置

  • Java:jdk21

  • 虚拟机: 7台 (Broker: 3, Controller: 3 / 监控VM: prometheus, grafana, UI For Kafka)

角色数量主机名功能
Controller3台kaf01,kaf02,kaf03元数据管理无需ZooKeeper运行
Broker3台kaf04,kaf05,kaf06消息收发与存储
Monitoring1台mon1Prometheus, Grafana, UI for kafka等

配置

机器配置

  • Kafka 服务器应设置为其中一个或两个,但不能同时设置为两者。组合模式可以在开发环境中使用,但应避免在关键部署环境中使用。process.role broker controller

  • 为了实现冗余,Kafka 集群应使用 3 个或更多控制器,具体取决于成本和系统应承受的并发故障数量等因素,而不会影响可用性。为了使 KRaft 控制器集群能够承受并发故障,控制器集群必须包含控制器。N2N + 1

  • Kafka Controller将集群的所有元数据存储在内存和磁盘上。我们认为,对于典型的 Kafka 集群,元数据日志控制器上的 5GB 主内存和 5GB 磁盘空间就足够了

192.168.26.76 kafka-node1
192.168.26.77 kafka-node2
192.168.26.78 kafka-node3
192.168.26.12 kafka-node4
192.168.26.176 kafka-node5
192.168.26.66 kafka-node6

jdk安装

wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm
rpm -ivh jdk-21_linux-x64_bin.rpm
echo 'export JAVA_HOME=/usr/lib/jvm/jdk-21.0.7-oracle-x64' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

检查

[root@vms76 ~]# java -version
java version "21.0.7" 2025-04-15 LTS
Java(TM) SE Runtime Environment (build 21.0.7+8-LTS-245)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.7+8-LTS-245, mixed mode, sharing)

内核参数调整

[root@vms76 ~]# cat /etc/sysctl.conf
# Kafka性能优化内核参数

# 增加文件描述符限制
fs.file-max = 1000000

# 增加网络性能参数
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.optmem_max = 65536
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# 增加最大内存映射区域数,对于大量分区尤为重要
vm.max_map_count = 262144

# 增加有效的epoll事件数量
fs.epoll.max_user_watches = 524288

# 其他网络优化
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1

[root@vms76 ~]# sysctl -p

文件最大打开数量调整

[root@vms76 ~]# cat /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000

创建数据目录

mkdir -p /data/kafka/logs

hosts解析

[root@vms76 ~]# cat /etc/hosts
192.168.26.76 kafka-node1
192.168.26.77 kafka-node2
192.168.26.78 kafka-node3
192.168.26.12 kafka-node4
192.168.26.176 kafka-node5
192.168.26.66 kafka-node6

下载kafka文件

wget https://mirrors.aliyun.com/apache/kafka/4.0.0/kafka_2.13-4.0.0.tgz
tar -xf kafka_2.13-4.0.0.tgz
mv kafka_2.13-4.0.0 /opt/kafka

jmx 调优 修改KAFKA_HEAP_OPTS这段

[root@vms76 ~]# cat /opt/kafka/bin/kafka-server-start.sh
if [ $# -lt 1 ];
then
        echo "USAGE: $0 [-daemon] server.properties [--override property=value]*"
        exit 1
fi
base_dir=$(dirname $0)

if [ -z "$KAFKA_LOG4J_OPTS" ]; then
    export KAFKA_LOG4J_OPTS="-Dlog4j2.configurationFile=$base_dir/../config/log4j2.yaml"
fi

if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
    export KAFKA_HEAP_OPTS="-Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80 -XX:+ExplicitGCInvokesConcurrent"
fi

EXTRA_ARGS=${EXTRA_ARGS-'-name kafkaServer -loggc'}

COMMAND=$1
case $COMMAND in
  -daemon)
    EXTRA_ARGS="-daemon "$EXTRA_ARGS
    shift
    ;;
  *)
    ;;
esac

exec $base_dir/kafka-run-class.sh $EXTRA_ARGS kafka.Kafka "$@"

控制器 VM配置

controller.properties

Kafka控制器的配置文件

############################# Server Basics #############################
# 服务器角色设置 - KRaft模式
process.roles=controller

# 节点ID - 确保在集群中唯一
node.id=1

# 控制器仲裁集群配置
controller.quorum.voters=1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093

############################# Socket Server Settings #############################
# 控制器监听器配置
listeners=CONTROLLER://kafka-node1:9093
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT

# 网络线程 - 适当增加以提高性能
num.network.threads=8
num.io.threads=16

# 套接字缓冲区调整
socket.send.buffer.bytes=1048576
socket.receive.buffer.bytes=1048576
socket.request.max.bytes=104857600

############################# Log Basics #############################
# 日志目录 - 建议使用独立磁盘
log.dirs=/data/kafka/logs

# 日志配置调整
num.recovery.threads.per.data.dir=2

############################# Log Retention Policy #############################
# 日志保留策略
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000

############################# System Settings #############################
# 后台线程数
background.threads=10

其他节点配置说明

参照上面只修改这下面

第二台Controller节点配置 (node.id=2)

node.id=2
listeners=CONTROLLER://kafka-node2:9093

第三台Controller节点配置 (node.id=3)

node.id=3
listeners=CONTROLLER://kafka-node3:9093

JMX监控Agent配置

为了使用Prometheus监控Kafka指标,需要配置JMX收集Agent:

vim /opt/kafka/bin/kafka-server-start.sh

# 在文件中添加以下配置
export KAFKA_OPTS="-javaagent:/opt/kafka/jmx/jmx_javaagent-1.2.0.jar=7071:/opt/kafka/jmx/kafka_kraft.yml"

相关文件可从以下地址获取:

Controller启动

获取集群Id

#这个只执行一次
/opt/kafka/bin/kafka-storage.sh random-uuid
5UxGj6CNRk2fBN-3wVTTHQ

格式化

 /opt/kafka/bin/kafka-storage.sh format -t 5UxGj6CNRk2fBN-3wVTTHQ -c /opt/kafka/config/server.properties

先启动所有Controller节点(控制器之间启动顺序无关紧要):

/opt/kafka/bin/kafka-server-start.sh  -daemon  /opt/kafka/config/server.properties

Broker VM配置

server.properties

############################# 服务器基础配置 #############################
 
# broker节点ID - 设置为4、5或6(取决于是哪台服务器)
node.id=4
 
# 服务器角色设置为broker
process.roles=broker
 
############################# 套接字服务器设置 #############################
# 监听器配置 - 指定broker接收连接的网络接口
listeners=PLAINTEXT://kafka-node4:9092
# 广播监听器 - 告知客户端如何连接到此broker
advertised.listeners=PLAINTEXT://kafka-node4:9092
 
# 网络线程数 - 建议增加到16以提高并发处理能力
num.network.threads=16
 
# IO线程数 - 建议增加到32以提高磁盘IO处理性能
num.io.threads=32
 
# 发送缓冲区大小 - 增加到1048576提高网络吞吐量
socket.send.buffer.bytes=1048576
 
# 接收缓冲区大小 - 增加到1048576提高数据接收性能
socket.receive.buffer.bytes=1048576
 
# 最大请求大小 - 保持1048576000以支持大消息
socket.request.max.bytes=1048576000

############################# 日志基础设置 #############################
 
# 日志存储目录 - 建议使用多个目录分散IO负载
log.dirs=/data/kafka/logs/
 
# 主题默认分区数 - 增加到6以提高并行处理能力
num.partitions=6
 
# 每个数据目录的恢复线程数 - 增加到2加速启动恢复过程
num.recovery.threads.per.data.dir=2
 
############################# 内部主题设置 #############################
# 消费者偏移量主题复制因子 - 增加到3提高可靠性
offsets.topic.replication.factor=3
# 事务状态日志复制因子 - 增加到3提高可靠性
transaction.state.log.replication.factor=3
# 事务日志最小同步副本数 - 增加到2提高数据可靠性
transaction.state.log.min.isr=2
 
############################# 日志保留策略 #############################
# 日志保留时间 - 7天,根据业务需求可调整
log.retention.hours=168
 
# 日志检查间隔 - 300秒检查一次过期日志
log.retention.check.interval.ms=300000
 
############################# 控制器配置 #############################
# 控制器仲裁投票者配置 - 连接到KRaft控制器节点
controller.quorum.voters=1@kafka-node1:9093,2@kafka-node2:9093,3@kafka-node3:9093
# 控制器监听器名称
controller.listener.names=CONTROLLER
# 监听器安全协议映射
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
 
############################# 消费者组设置 #############################
# 初始重平衡延迟 - 增加到3000毫秒减少频繁重平衡
group.initial.rebalance.delay.ms=3000

############################# 性能优化设置 #############################
# 副本拉取最大字节数
replica.fetch.max.bytes=10485760
# 消息最大字节数
message.max.bytes=10485760
# 批处理大小
batch.size=131072
# 消息累积等待时间(ms)
linger.ms=5
# 压缩类型
compression.type=producer
# 请求超时时间
request.timeout.ms=30000
# 副本拉取线程数
num.replica.fetchers=4

node.id=5的配置(只列出需要修改的部分)

properties# broker节点ID
node.id=5

# 监听器配置
listeners=PLAINTEXT://kafka-node5:9092
# 广播监听器
advertised.listeners=PLAINTEXT://kafka-node5:9092

node.id=6的配置(只列出需要修改的部分)

properties# broker节点ID
node.id=6

# 监听器配置
listeners=PLAINTEXT://kafka-node6:9092
# 广播监听器
advertised.listeners=PLAINTEXT://kafka-node6:9092

Broker的JMX监控配置

与Controller相同,配置JMX Agent:

vim /opt/kafka/bin/kafka-server-start.sh

# 在文件中添加以下配置
export KAFKA_OPTS="-javaagent:/opt/kafka/jmx/jmx_javaagent-1.2.0.jar=7071:/opt/kafka/jmx/kafka_kraft.yml"

Broker启动

确保所有Controller已正常启动后,再启动Broker:

格式化

 /opt/kafka/bin/kafka-storage.sh format -t 5UxGj6CNRk2fBN-3wVTTHQ -c /opt/kafka/config/server.properties

启动

/opt/kafka/bin/kafka-server-start.sh  -daemon  /opt/kafka/config/server.properties

检查


[root@vms12 kafka]# /opt/kafka/bin/kafka-metadata-quorum.sh --bootstrap-server kafka-node4:9092 describe --status
ClusterId:              5UxGj6CNRk2fBN-3wVTTHQ
LeaderId:               1
LeaderEpoch:            4
HighWatermark:          8723
MaxFollowerLag:         0
MaxFollowerLagTimeMs:   0
CurrentVoters:          [{"id": 1, "directoryId": null, "endpoints": ["CONTROLLER://kafka-node1:9093"]}, {"id": 2, "directoryId": null, "endpoints": ["CONTROLLER://kafka-node2:9093"]}, {"id": 3, "directoryId": null, "endpoints": ["CONTROLLER://kafka-node3:9093"]}]
CurrentObservers:       [{"id": 4, "directoryId": "VGQhZKm0UG69lix00tWqSw"}, {"id": 5, "directoryId": "awjteVkpIOlrRCr7FAnOFw"}, {"id": 6, "directoryId": "TloYch2Asa0GFy42-gV6nQ"}]

监控配置

Kafka 导出器

在每个Kafka集群节点上安装用于指标采集:

  • 收集Kafka主题信息的Agent

  • 数据传输容量、速度、时间

  • 每个主题的复制和分区数

  • 消费者指标等

github.com/danielqsj/k…

启动命令:

#安装一台就行了

wget https://github.com/danielqsj/kafka_exporter/releases/download/v1.9.0/kafka_exporter-1.9.0.linux-386.tar.gz
tar -xf kafka_exporter-1.9.0.linux-386.tar.gz
cd kafka_exporter-1.9.0.linux-386/
nohup ./kafka_exporter --kafka.server=kafka-node4:9092 &

Prometheus配置

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

scrape_configs:
  - job_name: 'kafka'
    static_configs:
      - targets:
        - 'kafka-node1:7071' # JMX exporter
        - 'kafka-node2:7071' # JMX exporter
        - 'kafka-node3:7071' # JMX exporter
        - 'kafka-node4:7071' # JMX exporter
        - 'kafka-node5:7071' # JMX exporter
        - 'kafka-node6:7071' # JMX exporter
        - 'kafka-node4:9308' # kafka_exporter

启动 Prometheus:

nohup ./prometheus --config.file=/root/prometheus-2.53.2.linux-amd64/prometheus.yml &

grafana

sudo yum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-11.6.1-1.x86_64.rpm
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable grafana-server.service
sudo /bin/systemctl start grafana-server.service
导入 21078,7589 图形id

压测

bin/kafka-topics.sh --create \
  --bootstrap-server kafka-node4:9092 \
  --replication-factor 3 \
  --partitions 10 \
  --topic perf-test-topic



  bin/kafka-producer-perf-test.sh --topic perf-test-topic \
  --num-records 10000000 \
  --record-size 1000 \
  --throughput 100000 \
  --producer-props bootstrap.servers=kafka-node4:9092,kafka-node5:9092,kafka-node6:9092

image.png