通过之前的学习,我已经对Kafka有了初步的了解,这一篇是自己深入学习Kafka过程的记录,主要包括单节点-多代理的配置、主题操作,以及在这些过程中经历的报错和解决方法,希望对和我一起学习Kafka的人有所帮助。
(一)单节点-多代理配置
1、启动ZooKeeper;
2、在Kafka的config目录下新增多个代理文件,例如:复制粘贴server.properties,新增server-one.properties,server-one.properties两个文件,修改新增的代理文件的配置:
config/server-one.properties
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=1
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
listeners=PLAINTEXT://:9093
# A comma separated list of directories under which to store log files
log.dirs=./logs-one
config/server-two.properties
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=2
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
listeners=PLAINTEXT://:9094
# A comma separated list of directories under which to store log files
log.dirs=./logs-two
3、启动多个代理:
Broker1
.\bin\windows\kafka-server-start.bat .\config\server.properties
Broker2
.\bin\windows\kafka-server-start.bat .\config\server-one.properties
Broker3
.\bin\windows\kafka-server-start.bat .\config\server-two.properties
4、新建主题
(1)先用命令行查看是不是有已创建的主题,我这里还没有创建主题,所以显示没有,如下图所示:
(2)新建主题并查看
#新建示例
kafka-topics.bat --create --zookeeper localhost:2181 --topic TopicName
#查看主题列表示例
kafka-topics.bat --list --zookeeper localhost:2181
(3)不过上面都是只创建了一个代理时的主题,如果有三个代理,这种怎么办呢?
只需要更改复制因子,也就是命令行“--replication-factor”后的数字,用“--describe”命令行去查看该主题的具体情况,如下图所示:
#新建具有1个分区,3个复制因子的主题示例
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic TopicName
#查看主题的具体信息
kafka-topics.bat --describe --zookeeper localhost:2181 --topic TopicName
以TestTopic4这个主题为例:从上面的输出中,我们看到第一行显示了主题名称,分区数和我们已经选择的复制因子。在第二行中,每个节点将成为分区的随机选择部分的领导者,而上面截图中的领导者Leader都是broker.id=2的经纪人,副本是“2,0,1”。
5、和单节点单代理一样去创建生产者和消费者
创建生产者截图如下:
创建消费者截图如下:
(二)主题的更改、删除
1、修改主题(增加分区数)
可以看到成功增加了一个分区,Partition Count:2
如果增加一个已有的分区会怎样呢?我这里就犯了这个错误:
结果提示我“执行topic命令时出错:只能增加主题的分区数,主题TestTopic2当前有1个分区,分区1不能再次添加。”
2、删除主题
示例:
kafka-topics.bat --describe --zookeeper localhost:2181 --topic TopicName
如上图所示,实际上并没有删除那个主题,而只是做了个标记,而且也有句提醒在那里:如果delete.topic.enable未设置为true,则不会有任何影响。
此外,作为领导者的Kafka代理(brokeris=2)报了异常结束,即使再次启动这个Kafka代理也会报错,所以删主题前,记得备份Kafka和ZooKeeper的日志。如果实在没备份,可参照文末最后一条报错记录去解决。
不过,有人就会问了,到底怎么彻底删除Topic呢?
第一种方法:
找到server.propertise,搜索了一下delete.topic.enable,如果没有这个配置,那么添加一个并设置为true,重新执行命令行去删除Topic。
当然这种办法可能还是不行,试试第二种办法,具体步骤如下:
(1)找到zkCli.cmd,登录zookeeper客户端,下图是登录成功的截图:
(2)执行命令行“ls /brokers/topics”,找到所有已创建的topic,输出如下:
可以看到我已经创建的Topic:TestTopic, TestTopic1, TestTopic2, TestTopic3, TestTopic4。
(3)找到要删除的topic,执行“deleteall /brokers/topics/topic名称”即可,此时topic被彻底删除:
不相信的话,可以执行查看主题列表的命令行去查看,如下图所示:可以看到已经没有TestTopic2这个主题了:
(三)报错记录
1、启动Kafka报错:
ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
kafka.common.InconsistentClusterIdException: The Cluster ID 7BxH6LhCQnGArxFtH5KAOw doesn't match stored clusterId Some(dIb7412LRPSDH3k0iA0GBw) in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.
at kafka.server.KafkaServer.startup(KafkaServer.scala:220)
at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
at kafka.Kafka$.main(Kafka.scala:84)
at kafka.Kafka.main(Kafka.scala)
报错原因:修改了ZooKeeper的日志路径,但是没删除原来的日志就启动了Kafka。
解决办法:删除原来的ZooKeeper日志,重新启动Kafka。
2、启动Kafka报错:
ERROR [KafkaServer id=0] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Failed to acquire lock on file .lock in D:\kafka_2.13-2.4.1\.\logs. A Kafka instance in another process or thread is using this directory.
at kafka.log.LogManager.$anonfun$lockLogDirs$1(LogManager.scala:249)
at scala.collection.StrictOptimizedIterableOps.flatMap(StrictOptimizedIterableOps.scala:118)
at scala.collection.StrictOptimizedIterableOps.flatMap$(StrictOptimizedIterableOps.scala:105)
at scala.collection.mutable.ArraySeq.flatMap(ArraySeq.scala:38)
at kafka.log.LogManager.lockLogDirs(LogManager.scala:244)
at kafka.log.LogManager.<init>(LogManager.scala:105)
at kafka.log.LogManager$.apply(LogManager.scala:1093)
at kafka.server.KafkaServer.startup(KafkaServer.scala:250)
at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
at kafka.Kafka$.main(Kafka.scala:84)
at kafka.Kafka.main(Kafka.scala)
报错原因:对应的Kafka代理已经启动了。
解决办法:查看一下server名称并修改,命令行更改为 .\bin\windows\kafka-server-start.bat .\config\new_server.properties
3、启动Kafka报错:
ERROR [KafkaServer id=2] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Socket server failed to bind to 0.0.0.0:9093: Address already in use: bind.
报错原因:两个代理配置的端口号都是9093
解决办法:把其中一个的端口号改成没配置过的。
4、启动Kafka报错:ERROR [KafkaServer id=0] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
org.apache.kafka.common.KafkaException: Failed to acquire lock on file .lock in D:\tmp\kafka-logs. A Kafka instance in another process or thread is using this directory.
报错原因:两个Kafka代理的日志路径是一样的。
解决办法:把其中一个server.properties文件中的日志路径修改成其他路径。
5、用命令行删除某个已创建的主题,发现该主题并没有被删除,只是做了个删除标记,而且此时的Kafka会报错,停止运行,即使重新启动也会报同样的错误,具体如下图所示:
也看了一下其他人的解决方案,说是把Kafka的日志(路径是server.properties文件里面log.dirs字段的值)和ZooKeeper的日志(路径是zoo.cfg文件里面的dataDir字段的值)都删掉,然后重新启动。但是这么做了之后发现问题还存在,明明日志都删了呀。
只好继续查看,发现在Kafka的config目录下有个“zookeeper.properties”文件,打开一看里面也有个dataDir的字段,这里填的是一个默认的路径,与zoo.cfg文件里面的dataDir字段的值不一致。难道是因为这个dataDir不一致导致的?
我把“zoo.cfg”文件和“zookeeper.properties”文件中的dataDir都改成“D:/apache-zookeeper-3.5.7/data”,然后同样地把已经产生的日志删掉,重新启动ZooKeeper和Kafka,问题解决~
ps:好像只有windows环境会有这个问题,不过删Topic还是要谨慎啊。