十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Kafka可视化控制台部署实战:从KRaft模式到Kafka UI

Kafka可视化控制台部署实战:从KRaft模式到Kafka UI 不说废话先交代背景。我这边团队之前要搭一套Kafka环境给数据中台用集群本身部署不难真正烦人的是Kafka自带的管理方式太“原始”——全命令行操作查看topic列表要敲命令、看消费组堆积要敲命令、排查某个分区消息有没有问题还是要敲命令。几十个topic、十几个消费组堆下来光靠命令行查状态能把人逼疯。所以这次部署Kafka我把“控制台【后台管理界面】”作为整个项目里必不可少的环节一起做掉了这也是这个标题的由来。这篇文章就是把我从选型、部署、联调到最终交付的完整过程整理出来给同样被Kafka命令行折磨过的朋友一个可以直接抄作业的参考。1. 部署Kafka之前先选定版本和运行模式很多新手上来就下载最新版Kafka然后一路默认配置启动结果遇到一堆莫名其妙的坑。我在这次部署之前先花了一上午做两件事确认Kafka版本演进带来的架构变化以及确认当前场景下该用哪种运行模式。1.1 版本演进带来的直接影响Apache Kafka从2.8版本开始引入了KRaft模式Kafka Raft Metadata的预览到3.3版本正式宣布KRaft模式可用于生产环境。到了3.5版本之后社区已经明确传递出信号ZooKeeper模式终将被移除。实际上在Kafka 4.0版本里ZooKeeper支持已经被彻底移除了。这一变化对部署方案的直接影响是什么就是如果你现在还照着网上那些老教程用ZooKeeper模式部署全新环境等于是把一套过时的架构再走一遍。我这次选的是Kafka 3.6.x版本原因很直接——这个版本KRaft模式已经足够稳定同时文档、社区讨论、第三方控制器控制台的兼容性验证都比较成熟踩坑概率比更早版本低很多。1.2 ZooKeeper模式与KRaft模式的取舍两种模式差异用一个生活类比来解释ZooKeeper模式相当于公司里有个独立的行政部ZooKeeper集群专门管人事档案元数据业务部Kafka Broker要查档案得跑行政部KRaft模式则是把人事档案管理职能直接并入业务部由Kafka节点自己选出一个“人事主管”Controller来管理元数据。具体对比看这张表维度ZooKeeper模式KRaft模式依赖组件需要额外部署ZooKeeper集群不需要Kafka自带Raft协议集群规模适合超大规模集群历史验证充分中小规模集群推荐免维护一套ZK部署复杂度需要单独维护ZK集群的健康和版本只有一个组件部署和运维更轻元数据一致性依赖ZK与Broker协调由Controller节点通过Raft协议管理与新版生态的兼容新版Kafka对ZK模式支持持续弱化未来版本唯一方向我的判断是如果是从零开始的新项目、集群规模在几个节点到十几个节点的范围直接上KRaft模式。如果是维护已有的大规模历史集群那才需要考虑沿用ZooKeeper模式并规划后续迁移方案。我这次本地和测试环境都用KRaft模式省掉了ZooKeeper后整个资源占用都降了一截。1.3 版本和下载的实操建议下载地址不贴了直接去Apache Kafka官网下载页找对应二进制包。建议选择带了-src后缀之外的纯二进制包一般叫kafka_2.13-3.6.2.tgz这种格式不要下源码包自己编译没必要。2.13是Scala编译版本现在统一用2.13或2.12都行对实际使用没有可见差异。另外要注意JDK版本。Kafka 3.x运行要求JDK 8、JDK 11、JDK 17都可以但这几年各组件生态对JDK 8的兼容度越来越差我这次统一装的JDK 17。JDK版本太低会遇到一些类加载异常太高又有可能碰到模块化限制实测JDK 17在Kafka 3.6上跑得最省心。2. Kafka服务端部署实操从裸机到可用集群版本定了、模式选了接下来就是动真格部署。虽然标题里“控制台”才是重头戏但没有一个健康的Kafka服务端控制台就是无源之水。所以这一章把服务端部署完整过一遍后面控制台才能稳稳挂上去。2.1 部署前的环境规划我习惯先把目录结构定好避免后续路径混乱。以Linux服务器为例我这次规划如下/data/kafkaKafka程序主目录解压后的二进制包放这里/data/kafka/data日志数据目录broker的消息日志不是应用日志/data/kafka/logs应用的运行日志目录/data/kafka/config存放修改过的配置文件磁盘方面有一点要特别提醒Kafka的日志数据是顺序写盘对磁盘IO要求远高于随机读写。生产环境一定要用独立数据盘不要和系统盘混在一起本地测试环境如果跑在虚拟机上也尽量用固态硬盘。之前我在机械硬盘虚拟机上跑Kafka生产端吞吐量直接腰斩把数据目录迁到SSD后才恢复正常。2.2 KRaft模式单机部署步骤首先解压二进制包并创建目录tar -zxvf kafka_2.13-3.6.2.tgz -C /data/kafka cd /data/kafka mv kafka_2.13-3.6.2 kafka-3.6.2 mkdir -p /data/kafka/data mkdir -p /data/kafka/logsKRaft模式要先为Controller生成一个集群ID。这里的一个关键点是KRaft模式下每个节点都需要在config/kraft/server.properties里明确节点的角色。先看核心配置修改。打开/data/kafka/kafka-3.6.2/config/kraft/server.properties我在单机模式下重点关注这几项process.rolesbroker,controller node.id1 controller.quorum.voters1localhost:9093 listenersPLAINTEXT://:9092,CONTROLLER://:9093 inter.broker.listener.namePLAINTEXT advertised.listenersPLAINTEXT://你的服务器实际IP:9092 controller.listener.namesCONTROLLER log.dirs/data/kafka/data这几个配置项简单解释一下process.rolesbroker,controller单节点模式下让当前节点同时承担broker和controller两种角色。集群模式下需要拆分角色一部分节点是broker,controller一部分只写broker。但这里不要误解默认配置里说明的是生产环境建议三台controller我这里测试环境单节点就一肩挑了。controller.quorum.voters这个参数是KRaft模式的核心它告诉当前节点控制器选举组的成员是谁。格式是节点ID主机名:端口多个成员用逗号分隔。单机就填自己。advertised.listeners这是最容易踩坑的地方。写localhost的话外部客户端包括控制台、远程生产消费工具连不上写公网或内网IP的话要注意防火墙放行。我建议这里直接写实际IP别偷懒用localhost不然控制台部署好后还得回头改。然后生成集群ID并格式化存储目录# 生成集群ID会自动写入 cd /data/kafka/kafka-3.6.2 KAFKA_CLUSTER_ID$(bin/kafka-storage.sh random-uuid) bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties格式化完成后启动服务bin/kafka-server-start.sh -daemon config/kraft/server.properties echo $! /data/kafka/kafka.pid启动后用jps或bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092验证一下能正常返回版本信息就说明broker起来了。2.3 快速验证Kafka服务可用性服务起来后先做一轮最基础的验证创建topic、生产消息、消费消息。# 创建topic bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic test-topic --partitions 3 --replication-factor 1 # 查看topic列表 bin/kafka-topics.sh --bootstrap-server localhost:9092 --list # 生产消息直接在控制台输入内容 bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test-topic # 消费消息另开一个终端执行注意消费完不会自动退出 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test-topic --from-beginning这里顺便解答很多新手问过的问题kafka的消费命令启动一次会一直运行吗答案是——消费命令启动后会持续监听必须保持终端不关闭它不会像普通命令那样执行完自动退出。要退出需要按CtrlC。这个特性是消费者模型决定的Kafka消费组需要长期在线拉取消息。所以用控制台脚本做验证没问题但想把消费能力接入业务系统必须用客户端API写消费者程序而不是挂个命令行工具在那盯着。2.4 配置开机自启和服务化我一直不建议在测试环境手动起进程毕竟服务器重启后没人记得手动把这些服务拉起来。Linux上用systemd管理比较干净我习惯把所有中间件都纳入systemd统一管理。下面这个unit文件可以直接用[Unit] DescriptionApache Kafka Server Afternetwork.target [Service] Typesimple Userkafka Groupkafka ExecStart/data/kafka/kafka-3.6.2/bin/kafka-server-start.sh /data/kafka/kafka-3.6.2/config/kraft/server.properties ExecStop/data/kafka/kafka-3.6.2/bin/kafka-server-stop.sh Restarton-failure RestartSec10 [Install] WantedBymulti-user.target这段配置有几个关键点Typesimple配合ExecStart直接启动Kafka主进程Restarton-failure保证异常退出时自动拉起User换成你自己的运行用户杜绝用root跑服务的坏习惯。log.dirs里的数据在Kafka中非常重要在格式化完存储目录后它就已经是Kafka元数据的一部分了。如果服务器重启时这块目录权限不对会导致broker启不来。所以systemd里的User/Group必须和/data/kafka目录属主一致这是很多人忽略的细节。3. 可视化控制台选型对比哪些后台管理界面值得部署Kafka服务端部署好只是第一步真正让团队用起来舒服还得靠控制台。目前开源社区和商业工具里有好几条路线各有各的侧重点。我先把我实际对比过的工具摆出来再说我为什么最终选了其中某一个。3.1 主流开源控制台盘点EFAK原Kafka Eagle老牌开源监控管理工具国内社区用户非常多。功能覆盖topic管理、消费组监控、消息查看、告警通知等。部署方式是JDK环境加一个可执行脚本配置数据源之后就能跑。特点是功能全、界面信息密度高但整体UI风格偏老旧部分功能操作路径较繁琐。Kafka UIprovectus/kafka-ui这个是我个人印象最好的一个。界面现代化支持多集群统一管理Docker部署极其丝滑能直接在页面里查看topic、浏览消息、管理消费组、动态调整分区副本等等。配置方式是环境变量或YAML文件对新手非常友好页面交互也符合直觉。Offset Explorer原名Kafka Tool这是一个桌面GUI客户端不是Web控制台。Windows/Mac/Linux都有对应版本。适合个人本地连Kafka排查问题支持查看topic消息、消费组offset、生成测试消息等。不适合团队统一部署使用但作为本机调试工具很好用。CMAK原Kafka Manager这个工具是早几年Yahoo开源的Kafka集群管理工具当年很火但项目已经基本停止维护对新版本Kafka的兼容性越来越差。我这次不推荐也不选用这里提出来是提醒大家搜技术文章时如果看到三年前的Kafka Manager教程直接绕过。3.2 各工具功能对比表功能维度EFAKKafka UIOffset Explorer部署形态Web服务Web服务桌面客户端多集群管理支持支持支持需逐集群配置Topic创建/删除支持支持支持消息浏览与搜索支持支持交互体验好支持消费组Lag监控支持有告警支持支持消息Schema管理部分支持集成Schema Registry不支持认证授权支持用户体系支持Basic Auth/OAuth不支持部署难度中等低Docker一键低界面友好度一般高中等3.3 我的最终选择Kafka UI最终选择了Kafka UI理由有三条第一部署成本最低。官方提供Docker镜像指定几个环境变量就能跑起来没有额外依赖。第二页面设计符合团队习惯。数据中台的同事不是每个都熟悉Linux命令行他们需要一个直观的地方看消息内容、查消费堆积。Kafka UI的消息浏览、分区offset展示都做得非常清楚。第三多集群管理能力强。公司后面可能不止一套Kafka环境Kafka UI可以在一个界面上同时连接多个集群切换查看很方便。当然EFAK也不是没有优势它对告警和监控的支持更细如果团队运维体系需要把告警打通EFAK的成熟度更高。这一点后面可以根据需要把两个工具分层使用Kafka UI作为日常操作的入口EFAK作为监控告警端。4. 控制台部署实战Kafka UI完整安装过程选型定了直接开干。Kafka UI支持两种部署方式Docker Compose和二进制包直接运行。本地测试环境我推荐Docker Compose生产环境如果有Kubernetes则可以直接用Helm Chart。4.1 Docker Compose一键部署Kafka UI我这次用的就是Docker Compose文件不长但细节点不少。先贴出完整的docker-compose.ymlversion: 3.8 services: kafka-ui: image: provectuslabs/kafka-ui:latest container_name: kafka-ui ports: - 8080:8080 environment: KAFKA_CLUSTERS_0_NAME: local-kafka KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: 192.168.x.x:9092 KAFKA_CLUSTERS_0_ZOOKEEPER: # KRaft模式下无需配置ZK地址 KAFKA_CLUSTERS_0_KAFKACONFIG_SASL_MECHANISM: PLAIN KAFKA_CLUSTERS_0_KAFKACONFIG_SECURITY_PROTOCOL: SASL_PLAINTEXT KAFKA_CLUSTERS_0_KAFKACONFIG_SASL_JAAS_CONFIG: | org.apache.kafka.common.security.plain.PlainLoginModule required \ usernameadmin \ passwordyour-password; depends_on: - kafka kafka: image: bitnami/kafka:3.6 container_name: kafka ports: - 9092:9092 environment: KAFKA_CFG_PROCESS_ROLES: broker,controller KAFKA_CFG_NODE_ID: 1 KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1kafka:9093 KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://192.168.x.x:9092 KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT ALLOW_PLAINTEXT_LISTENER: yes volumes: - /data/kafka-data:/bitnami/kafka这里有一个容易搞混的地方上面这个Compose文件里的Kafka是容器化部署的如果读者用的是我们第二章里宿主机直装的Kafka那就把kafka-ui里的depends_on和kafka服务整个去掉只保留kafka-ui服务然后把KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS指向宿主机的IP和端口即可。我之前见过很多人在Docker里跑Kafka UI连不上宿主机Kafka大部分都是因为BOOTSTRAPSERVERS配了localhost或127.0.0.1。在Docker容器内localhost指的是容器自己不是宿主机。这时候要填宿主机的局域网IP或者在Docker Desktop环境下用host.docker.internal这个特殊域名。4.2 关键环境变量拆解Kafka UI的连接配置完全靠环境变量驱动理解这些变量比记命令更重要KAFKA_CLUSTERS_0_NAME集群显示名称在界面上会展示。多个集群就对应KAFKA_CLUSTERS_1_NAME、KAFKA_CLUSTERS_2_NAME。KAFKA_CLUSTERS_0_BOOTSTRAPSERVERSKafka Broker的地址列表多个Broker用逗号分隔例如192.168.1.10:9092,192.168.1.11:9092。KAFKA_CLUSTERS_0_KAFKACONFIG_SASL_MECHANISMSASL认证机制。如果Kafka开启了SASL_PLAINTEXT这里要和Broker端保持一致。KAFKA_CLUSTERS_0_KAFKACONFIG_SASL_JAAS_CONFIGJAAS认证配置里面填写Kafka中配置的用户名密码。举个例子如果Kafka Broker端配置了listener.name.internal.sasl.enabled.mechanismsPLAIN那控制台这边就必须配置对应的SASL信息否则连不上。之前我遇到过一个小坑KAFKA_CLUSTERS_0_KAFKACONFIG_SASL_JAAS_CONFIG里我用了多行字符串YAML格式没对齐导致服务起不来改成单行加上续行符\就好了。4.3 启动与验证执行命令并检查状态docker compose up -d docker ps | grep kafka-ui docker logs -f kafka-ui看到日志里出现Started DemoKafkaUiApplication或在控制台输出Kafka UI is running on port 8080之类的信息说明启动完成。浏览器访问http://服务器IP:8080打开后的界面如果能看到broker节点信息、topic列表和消费者组列表说明Kafka UI已经成功连接上Kafka集群。如果页面一直显示连接失败优先检查两步Kafka的advertised.listeners是否配了实际IP。检查方式是在宿主机执行bin/kafka-broker-api-versions.sh --bootstrap-server 192.168.x.x:9092如果宿主机能通而容器里不通问题大概率出在BOOTSTRAPSERVERS或者Docker网络。防火墙是否放行9092端口。这个不用展开多数连接不上都是被防火墙拦了。5. 控制台日常运维功能验证不只是看看那么简单控制台部署完成后功能验证是整个环节中最花时间的部分。因为团队成员不是每个人都会用命令行Kafka工具我们得确认控制台能覆盖高频运维动作并且运行稳定。5.1 用控制台创建和删除Topic登录Kafka UI后在Topics页面点击Add a Topic填写名称、分区数和副本数。我强烈建议把分区数和副本数的预估逻辑讲给团队听——分区数决定了消息并行度副本数决定了容错能力。这里的设置要和业务量级匹配不是越大越好分区数适用场景成本代价1顺序性要求极高的场景吞吐量受限3~6一般业务默认复杂度适中10以上高吞吐、大流量场景文件句柄和元数据开销大删除Topic前Kafka UI会弹出确认框这个操作不可逆里面的消息会被全部清掉。我在团队里强调过一个原则宁可保留一个多余topic也不要误删生产topic。5.2 查看Topic中的消息数据Kafka UI的Messages页面可以按分区浏览消息也可以输入offset范围精确查看某一段消息。这个功能在实际排查问题时的价值非常大——比如业务反馈某个消息没被消费到我可以直接在界面上查看该分区的最后一条消息offset和消费组的offset做对比立刻判断是没生产进来还是消费者卡住了。在浏览消息时有两个细节容易忽略消息体格式。Kafka里消息值是byte[]控制台会按字符串解码显示。如果业务用的是Avro或Protobuf序列化界面上看到的就是一堆乱码。Kafka UI可以通过配置Schema Registry解决这个问题但前提是业务侧有注册Schema。消息的header信息。Kafka消息除了key和value还可以带一组header键值对很多链路追踪信息就放在这里。排查问题时别忘了看。5.3 监控Consumers消费组Lag这是控制台最核心的监控功能之一。在Consumers页面可以看到每个消费组的当前Lag积压消息数。Lag就是生产消息数和消费消息数之间的差值Lag持续升高说明消费者处理能力跟不上生产速度是性能问题的早期信号。这里我分享一下判断基准Lag为0消费正常完全跟上了生产速度。Lag偶尔波动消费者会定时拉批稍微有积压正常。Lag持续增长且不回落必须排查消费者是否卡在某个外部调用、数据库连接是否耗尽、或者下游处理能力到达瓶颈。Kafka UI会展示每个消费组在每个分区上的Lag明细比命令行看要直观很多。我之前在命令行时都用kafka-consumer-groups.sh --describe去查输出又长又不直观现在直接打开控制台就能看到全貌。5.4 控制台生产消息做联调验证Kafka UI左侧菜单有一个Producer入口可以直接向指定topic生产一条测试消息。这个功能平时用来做联调测试很方便不用再跑到服务器上敲命令行。做法是选择目标topic、填写key和value点击提交。然后切到Messages页签查一下新消息有没有进来。这个功能也要提醒一点Kafka UI的生产接口默认不带消息不进事务、不等待ack所以生产成功后页面提示成功不代表消费者立刻就能拿到。如果要做精确的消息链路验证还是建议用业务侧的生产者SDK。6. 以问题排查视角补充Kafka控制台部署容易踩的坑这一章把我在实际部署和后续运维过程中踩过的坑整理出来。这些坑不是文档能完全覆盖到的都是需要亲自动手才能形成的肌肉记忆。6.1 坑一KRaft模式下控制台连接失败KRaft模式把ZooKeeper从架构里拿掉了但很多控制台工具尤其是老一代工具还默认要填ZooKeeper地址。Kafka UI本身不需要ZK地址但如果你在Docker Compose里给Kafka UI配置了KAFKA_CLUSTERS_0_ZOOKEEPER并填了某个地址它会尝试连着ZK做某些操作一旦ZK不存在就直接报错。正确做法是在KRaft模式下把KAFKA_CLUSTERS_0_ZOOKEEPER留空或者直接不配置这个环境变量。6.2 坑二JVM内存配置不当导致服务假死Kafka默认启动脚本里JVM堆内存是-Xmx1G -Xms1G默认给1G。这在开发测试环境可能够了但如果你用Kafka UI同时管理多个集群控制台自身也会吃内存。更关键的是Broker本身在大量topic和消息场景下1G肯定不够我之前遇到过Kafka Broker频繁Full GC、请求超时的情况排查下来就是堆内存太小。打开bin/kafka-server-start.sh找到KAFKA_HEAP_OPTS这行export KAFKA_HEAP_OPTS-Xmx4G -Xms4G4G是相对平衡的配置。如果你的服务器内存大、业务流量高可以考虑8G但不要超过物理内存的一半毕竟操作系统页缓存对Kafka性能影响也很大。Kafka UI自身的内存配置同样可以通过环境变量调整Docker部署时加JAVA_OPTS: -Xmx512m即可大部分场景512m到1G足够。6.3 坑三Docker网络模式下客户端连不上Kafka这个问题常出现在Docker里跑Kafka或者Kafka UI容器连宿主机Kafka的场景。我在测试环境用Docker把Kafka和Kafka UI都容器化后宿主机客户端用localhost:9092可以连上但从另一台机器用宿主机IP去连却发现连接一直超时。根因在advertised.listeners。Docker内启动的Kafka进程拿到的是容器IP它认为自己应该对外广播容器IP宿主机客户端拿到这个地址后自然连不上。解决办法是显式配置advertised.listeners为宿主机IP。Kafka的容错机制没有像数据库那样会自动做NAT转换很多服务首次容器化最容易在这翻车。6.4 坑四控制台访问权限过度开放默认部署Kafka UI是不带认证的也就是任何人只要知道IP和端口就能看到你集群里所有topic的消息内容。这在内部测试环境问题不大但如果部署到有外网访问权限的服务器上风险就非常大。Kafka UI支持配置Basic Auth。在Docker Compose环境变量里加上AUTH_TYPE: LOGIN_FORM SECURITY_BASIC_ENABLED: true SECURITY_BASIC_USERNAME: admin SECURITY_BASIC_PASSWORD: 你的强密码加了这两项后第一次打开控制台会跳转登录页就必须输入账号密码。如果公司有LDAPKafka UI也支持LDAP对接这样团队成员直接用自己的域账号登录少维护一套账户体系。另外更细颗粒度的访问控制比如某个用户只能看某些topic不能删topic开源版Kafka UI做得还不够好。生产环境如果要做到分权管理建议控制台只放在内网加减权限全部在Kafka ACL层处理不要指望控制台本身的权限系统能做到审计级别的管控。7. 控制台部署后的团队日常践行部署完成只是开始团队能长期稳定地用这套控制台才是这次工作的价值所在。最后再分享几个维护经验。Docker镜像的更新不比二进制包建议不要随便docker compose pull升级。Kafka UI的新版本虽然通常向后兼容但大版本升级前最好先在测试环境挂到同一个Kafka集群上验证几天确认没有兼容问题再上生产。Kafka数据目录的膨胀问题也要提前管理。控制台可以帮你直观看到每个topic的消息量但对于长期没人消费、也过了业务生命周期的topic该清理就要及时清理。Kafka不会像数据库那样自动回收过期的日志文件它的日志保留策略默认按磁盘上限或时间上限触发如果topic规模控制不住数据盘很容易被填满。关于控制台服务器本身的监控可以接入Prometheus通过JMX导出器暴露Kafka指标。Kafka UI集成的Partitions/Consumers页面可以看运行期状态但历史趋势和告警还是要交给监控体系去做控制台更适合作为“即时查看”的面板来用。从这次部署的最终效果来看Kafka加一套好的后台管理界面对团队整体的生产力提升是显而易见的。之前同事排查问题得找我帮忙敲命令行现在他们在控制台点几下就能自己看到消息积压和主题数据运维压力下降了很多。
返回列表