kafka 架构简单的大吞吐分布式发布订阅消息系统
这两天调研管理 kafka 的开源工具,顺带复习了下 kafka 的东西,这里为了理解方便 介绍不涉及 Zookeeper且默认 zookeeper 和 broker 相关联,最后不得不说标题确实很绕口
从架构上来说,kafka 总体分为三个部分:
- 生产者(producer)
- 消费者(consumer)
- kafka 队列服务(broker)
整个流程:
- 生产者生产消息,发送到 broker 并落地到 broker 的数据目录(默认 /tmp/logs)
- 消费者从 broker 手里去拿消息,并且可以通过是否在“消费命令”中加上参数“--from-beginning”控制从头开始消费还是从当前开始消费
拆分流程:
-
生产者生产消息,首先要知道生产的消息是什么,消费者才可以告诉 broker 它需要消费什么。
如果生产者需要生产两类信息分别供不同的消费者消费使用,其中一类是个人信息,就不应该被消费天气信息的消息者所消费。那么我们称控制消息是什么的概念叫做“topic”
-
实际上 topic 也是一个物理概念,生产者在生产消息的时候(必须)指定 topic,这批数据也就进入到数据目录的子目录(topic-x)下了。
看着上面的 topic-x 可能会有点疑惑,这个“x”是什么,实际上在数据目录的物理路径下,topic的目录是以这样的格式存在(如testTopic-0),其中“0”是指他的partition(分区)。
-
Kafka 将 Topic 分成一个或者多个 Partition,每个 Partition 在物理上对应一个文件夹,该文件夹下存储这个 Partition 的所有消息。事实上每一个 Partition 也是一个有序且不可变的消息队列,生产者生产的消息有序添加到 Partition 的尾部,当存在多个 Partition 时,多个消息队列大大加强了该 topic 的吞吐量。partitions数量在创建 topic 时由参数--partitions [int]指定
-
消费者消费消息,同样消费命令需要指定从哪个 broker 提供的服务、获取哪个 topic 的消息,另外一个可选参数“group”,指的是消费者组的概念。
一个或多个消费者组成 consumer-group 概念,在consumer-group中每一个 consumer 分工消费 topic 中 partitions 的消息。
如某个 topic 中有 4 个 partitions,使用的 consumer-group 内有 4 个 consumer,那么刚好一个 consumer 读取一个 partition,一个 partition 在一个时间只能被同样consumer-group 的一个consumer 消费。
还有一种情况:假如有 4 个 partitions,使用的 consumer-group 中有5个 consumer,根据刚才的机制,始终有一个 consumer 处于不可消费状态, 所以不能盲目的以为只要消费者数量多,消费性能就高
命令解析:
- 生产命令:
/KAFKA_HOME/bin/kafka-console-producer.sh --topic test --broker-list localhost:9092,localhost:9093,localhost:9094--topic 指定消息放入的 topic,--broker-list 指定放入的 brokers,broker 提供服务的端口默认9092,当启用多实例时,自行手动配置其他实例的端口(9093/9094/...)
- 消费命令:
/KAFKA_HOME/bin/kafka-console-consumer.sh --topic test --bootstrap-server localhost:9092,localhost:9093,localhost:9094 --group test-group --from-beginning--bootstrap-server 指定broker服务,--group 指定 consumer-group,[--from-beginning]可选参数 从头开始消费
生产消费命令还有Old 和 New 的区分,这里提供的是 Old
副本机制
- 创建 topic 时还有一个参数 --replication-factor 3 ,表示消息做3副本,这3个副本里其中一个是 leader,另外两个是 follower,当生产消费时,生产者和消费者都只会与 leader 进行交互,而 follower 只做一个数据冗余。当 leader 数据更新时,follower 主动从 leader 上拉取数据,进行数据同步。处于同步状态的副本叫做 ISR(In Sync Replicas)
- 当其中一个 partition 的 leader 失效了(所在 broker 故障),broker 上面的副本自然也失效,这时正常的其中一个 follower 会提升为 leader。当故障 broker 恢复后,该 broker 上的副本都是 follower,生产者消费者无法和该 broker 进行交互,也就造成该 broker 性能浪费,需要调用 perfered-replica-election,将 leader 恢复到优先副本(挂掉的 broker 上)。0.10.0及以上版本会在重启 broker 时自动调用 perfered-replica-election。
Q: 前面提到consumer 只和 leader 进行交互,假如当前消费命令只指定了一个 broker,还有一部分 partitions 的 leader 不在我们指定的 broker 里,那他是怎么进行消费的?
(这里感谢华为大佬智哥哥的解惑)
A: 每一个 broker 下都记录有所有 partitions 的 leader 索引信息,客户端可以从一个 broker 获取到所有信息,进而进行交互。