文章目录

  • 前言
  • 关于Kafka&ZooKeeper
  • 关于__consumer_offsets
  • 解决办法



前言

我们在启动 Kafka 集群服务时,通过 jps 命令查不到 kafka 服务进程。或者在 Kafka 集群中创建 topic 时,报错replication factor: 1 larger than available brokers: 0。都是由于 Kafka 服务无法启动或者启动后自动关闭导致的。

  • 可先尝试使用守护进程模式启动 Kafka:kafka-server-start.sh -daemon config/server.properties
  • 首先检查一下所有节点的 ZooKeeper 服务是否可以正常启动,尤其是myid的配置千万不能一样。
  • 然后检查一下 Kafka 的配置文件server.properties。第一个配置参数,每个 Kafka 节点的broker.id不能相同。第二个配置参数,通过 ZooKeeper 连接 Kafka 集群需要在localhost:port后面加上/kafka,并且在创建 topic 时也需要加上:kafka-topics.sh --create --topic sgapp122_log --zookeeper master01:2181/kafka --partitions 3 --replication-factor 2
[root@master01 ~]# cd /opt/software/spark/kafka241/config
[root@master01 config]# vi server.properties

kafkamap无法添加集群 kafka集群失效_kafkamap无法添加集群


kafkamap无法添加集群 kafka集群失效_数据_02


关于Kafka&ZooKeeper

  • 由于 Kafka 依赖于 ZooKeeper,启动后要去 ZooKeeper 中注册。因此开启服务的时候,是先开 ZooKeeper 后开 Kafka,而关闭服务的时候,是先关 Kafka 后关 ZooKeeper。注意这里 Kafka 关闭服务的时间较长,如果还未等到集群中的 Kafka 全部关闭,就去关闭 ZooKeeper,或者是先关了 ZooKeeper再关 Kafka,则有可能引发下次 Kafka 启动后自动关闭的问题。这是因为 Kafka 在退出服务的时候,会把 ZooKeeper 下的/kafka/brokers/ids里的临时节点删掉,但如果是 ZooKeeper 先退出就不会删除。当下次启动时,Kafka 再用 id 去注册,发现已经存在了,所以会导致启动失败。

关于__consumer_offsets

  • 由于 ZooKeeper 并不适合大批量的频繁写入操作,新版 Kafka 将consumer的位移信息保存在 Kafka 内部的topic中,即__consumer_offsets topic,并且默认提供了kafka_consumer_groups.sh脚本供用户查看consumer的信息。
  • __consumer_offsets作为 Kafka 的内部 topic,用来保存消费组元数据以及对应提交的offset信息。每次消费者消费完一批数据需要标记这批数据被消费掉时,需要将消费的偏移量即offset提交掉,这个提交过程其实就是将offset信息写入__consumer_offsets的过程。
  • 一般情况下,当集群中第一次有消费者拉取数据时会自动创建__consumer_offsets。首先在offsets.topic.replication.factor配置的值(副本因子,默认值为1)和当前可用的 brokers 个数中取最小值作为__consumer_offsets的副本数,offsets.topic.num.partitions作为分区数(默认值为50),然后创建__consumer_offsets
  • 考虑到一个 Kafka 生产环境中可能有很多consumerconsumer group,如果这些consumer同时拉去数据并提交offset,必将加重__consumer_offsets的写入负载,因此 Kafka 默认为该topic创建了50个分区,并且对每个group.id做哈希求模运算Math.abs(groupID.hashCode()) % numPartitions,从而将负载分散到不同的__consumer_offsets分区上。
  • __consumer_offsets的每条消息可以看成是K/V格式的消息,其中 key 就是一个三元组:group.id+topic+partition,而 value 就是offset的值。

解决办法

  • 找到 ZooKeeper 根目录下,用来存放myid文件的文件夹mydata,这个是自己创建的,可能名字会不同。进入mydata之后,删除文件夹version-2。可以把所有节点的都删除,下次启动时会自动创建。
[root@master01 ~]# cd /opt/software/hadoop/zookeeper357/mydata
[root@master01 mydata]# ls
myid  version-2
[root@master01 mydata]# rm -rf version-2
  • 重新建立索引:找到Kafka根目录下,用来存放日志文件的文件夹kfklogs,对应的是配置文件server.properties里的log.dirs=/opt/software/spark/kafka241/kfklogs,这个也是自己创建的,名字可能会不同。将所有节点的日志文件夹kfklogs删除重新创建。
[root@master01 ~]# cd /opt/software/spark/kafka241/
[root@master01 kafka241]# ls
bin  config  kfklogs  libs  LICENSE  logs  NOTICE  site-docs
[root@master01 kafka241]# rm -rf kfklogs
[root@master01 kafka241]# mkdir kfklogs
  • 删除brokers:进入 ZooKeeper 客户端删除 Kafka。集群所有节点的 ZooKeeper 服务都需要启动,删除操作只需在一个节点上操作即可。
[root@master01 ~]# zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /
[kafka,zookeeper]
[zk: localhost:2181(CONNECTED) 1] deleteall /kafka
  • 最后关闭 ZooKeeper 重启,再开启 Kafka。