1. 什么是Kafka
很多人常常把Kafka和消息队列相提并论,事实上这是一个错误的概念。
根据官网的解释,它的准确定义如下:
Apache Kafka is a distributed streaming platform.
A streaming platform has three key capabilities:
Publish and subscribe to streams of records
similar to a message queue or enterprise messaging system.Store streams of records in a fault-tolerant durable way
Process streams of records as they occur
好了,以上便是官网的解释。
从上面可以看出,准确的定义应该如下:
Apache Kafka是一个分布式的流平台。
Kafka有3项重要能力:
- 发布订阅流数据,有点类似于消息队列
- 以容错的方式持久化流数据
- 即时处理流数据
不同于基于队列和交换器的RabbitMQ,Kafka的存储层是使用分区事务日志来实现的。
2. Kafka 与传统 MQ 消息系统之间的区别
主要区别有3个:
- Kafka 持久化日志,这些日志可以被重复读取和无限期保留
- Kafka 是一个分布式系统, 它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性
- Kafka 支持实时的流式处理
3. Kafka的一些重要概念
Broker
一台 Kafka 机器就是一个 Broker。
一个集群由多个 Broker 组成。
一个 Broker 可以容纳多个 Topic。Producer
消息生产者,向 Kafka Broker 发消息的客户端。Consumer
消息消费者,从 Kafka Broker 取消息的客户端。Topic
可以理解为一个队列,Topic 将消息分类,生产者和消费者面向的是同一个 Topic。Consumer Group
消费者组(CG),消费者组内每个消费者负责消费不同分区的数据,提高消费能力。
一个分区只能由组内一个消费者消费,消费者组之间互不影响。
所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。Partition
为了实现扩展性,提高并发能力,一个非常大的 Topic 可以分布到多个 Broker (即服务器)上,
一个 Topic 可以分为多个 Partition,每个 Partition 是一个 有序的队列。
Topic 是逻辑上的概念,而 Partition 是物理上的概念。
每个 Partition 对应于一个 log 文件,该 log 文件中存储的就是 Producer 生产的数据。Replica
副本,为实现备份的功能,保证集群中的某个节点发生故障时,该节点上的 Partition 数据不丢失,且 Kafka 仍然能够继续工作,Kafka 提供了副本机制。
一个 Topic 的每个分区都有若干个副本,一个 Leader 和若干个 Follower。Leader
每个分区多个副本的“主”副本,生产者发送数据的对象,以及消费者消费数据的对象,都是 Leader。Follower
每个分区多个副本的“从”副本,实时从 Leader 中同步数据,保持和 Leader 数据的同步。Leader 发生故障时,某个 Follower 还会成为新的 Leader。Offset
消费者消费的位置信息,监控数据消费到什么位置,当消费者挂掉再重新恢复的时候,可以从消费位置继续消费。Zookeeper
Kafka 集群能够正常工作,需要依赖于 Zookeeper,Zookeeper 帮助 Kafka 存储和管理集群信息。
4. Kafka的存储机制
由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位效率低下,Kafka 采取了分片和索引机制。
Kafka将每个 Partition 分为多个 Segment,每个 Segment 对应两个文件:
“.index” 索引文件和 “.log” 数据文件。
这些文件位于同一文件下,该文件夹的命名规则为:topic 名-分区号。
例如,first 这个 topic 有三分分区,则其对应的文件夹为 first-0,first-1,first-2。
index 和 log 文件以当前 Segment 的第一条消息的 Offset 命名。
见下图:
“.index” 文件存储大量的索引信息,“.log” 文件存储大量的数据,索引文件中的元数据指向对应数据文件中 Message 的物理偏移量。
5. Kafka的分区分配策略
-
Range策略
默认分配策略
1. 将分区按数字顺序排行序,消费者按名称的字典序排序。
2. 用分区总数除以消费者总数。如果能够除尽,平均分配;若除不尽,则位于排序前面的消费者将多负责一个分区。
-
RoundRobin策略
基于轮询算法
1. 将所有主题的分区组成TopicAndPartition列表。
2. 对TopicAndPartition列表按照hashCode进行排序某个 topic。
6. Kafka和其它消息队列的比较
7. Kafka常见问题解决
Kafka存储数据量过大,导致磁盘写满了怎么办
背景:
电商系统峰值的时候,Producer数据产生请求量很大,很容易写满。
解决方案:
保留短时间的数据。
eg: 只保留 2 个小时的数据,但此时我们的磁盘已经写满了。
怎么清除旧数据呢。我们只需要将保留策略设置成 2h(修改为log.retention.hours=2)
然后依次启动单个 kafka 的节点(注意: 是单个启动,一起启动会失败),此时 kafka 会自动清除本地过期的旧数据。
kafka如何保证消息的顺序消费
Kafka 分布式的单位是 partition,同一个 partition 用一个 write ahead log 组织,所以可以保证 FIFO 的顺序。不同 partition 之间不能保证顺序。但是绝大多数用户都可以通过 message key 来定义,因为 同一个 key 的 Message 可以保证只发送到同一个 partition。
Kafka 中发送 1 条消息的时候,可以指定(topic, partition, key) 3 个参数。partiton 和 key 是可选的。 如果你指定了 partition,那就是所有消息发往同 1个 partition,就是有序的。并且在消费端,Kafka 保 证,1 个 partition 只能被1 个 consumer 消费。或者你指定 key(比如 order id),具有同 1 个 key 的所有消息,会发往同 1 个 partition。