Kafka的版本变迁
0.11.x拥有的特性:
传统消息队列及副本容灾功能
支持exactly once 恰好一次语义
事务支持.
kafka stream支持.
consumer 消息拉取线程和心跳线程分开
截止到0.11.x,kafka作为传统的发布订阅功能基本完善,建议至少升级到该版本.
1.0.x
新增磁盘故障转移
新增跨副本路径迁移
2.x
2.1.x支持ZStandard的压缩,提高吞吐性能
优化生产者和消费者
当前最新稳定版本如下:
2.7.0,2.6.1,2.6.0
Kafka中的每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序号,用于partition唯一标识一条消息。
Offset记录着下一条将要发送给Consumer的消息的序号。
Offset从语义上来看拥有两种:Current Offset和Committed Offset。
Current Offset
Current Offset保存在Consumer客户端中,它表示Consumer希望收到的下一条消息的序号。它仅仅在poll()方法中使用。例如,Consumer第一次调用poll()方法后收到了20条消息,那么Current Offset就被设置为20。这样Consumer下一次调用poll()方法时,Kafka就知道应该从序号为21的消息开始读取。这样就能够保证每次Consumer poll消息时,都能够收到不重复的消息。
Committed Offset
Committed Offset保存在Broker上,它表示Consumer已经确认消费过的消息的序号。主要通过commitSync
和commitAsync
API来操作。举个例子,Consumer通过poll() 方法收到20条消息后,此时Current Offset就是20,经过一系列的逻辑处理后,并没有调用consumer.commitAsync()
或consumer.commitSync()
来提交Committed Offset,那么此时Committed Offset依旧是0。
Committed Offset主要用于Consumer Rebalance。在Consumer Rebalance的过程中,一个partition被分配给了一个Consumer,那么这个Consumer该从什么位置开始消费消息呢?答案就是Committed Offset。另外,如果一个Consumer消费了5条消息(poll并且成功commitSync)之后宕机了,重新启动之后它仍然能够从第6条消息开始消费,因为Committed Offset已经被Kafka记录为5。
在Kafka 0.9前,Committed Offset信息保存在zookeeper的[consumers/{group}/offsets/{topic}/{partition}]目录中(zookeeper其实并不适合进行大批量的读写操作,尤其是写操作)。而在0.9之后,所有的offset信息都保存在了Broker上的一个名为__consumer_offsets的topic中。
计算Lag值
在计算Lag之前先普及几个基本常识
LEO(LogEndOffset): 这里说的和官网说的LEO有点区别,主要是指对consumer可见的offset.即HW(High Watermark)
CURRENT-OFFSET: consumer消费到的具体位移
知道以上信息后,可知Lag=LEO-CURRENT-OFFSET
。计算出来的值即为消费延迟情况。
Kafka 2.8.0 出炉了,此版本有一项重大改进:
实现了 Raft 分布式一致性机制,意味着可以脱离 ZooKeeper 独立运行了。
ZooKeeper 在 Kafka 中扮演着重要的角色,用来存储 Kafka 的元数据。
ZooKeeper 存储着 Partition 和 Broker 的元数据 ,同时也负责 Kafka Controller 的选举工作。
对于 Kafka 来讲,ZooKeeper 是一套外部系统,要想部署一套 Kafka 集群,就要同时部署、管理、监控 ZooKeeper。
ZooKeeper 有自己的配置方式、管理工具,和 Kafka 完全不一样,所以,一起搞两套分布式系统,自然就提升了复杂度,也更容易出现问题。有时工作量还会加倍,例如要开启一些安全特性,Kafka 和 ZooKeeper 中都需要配置。
除了复杂度,外部存储也会降低系统效率。
例如 Kafka 集群每次启动的时候,Controller 必须从 ZooKeeper 加载集群的状态信息。
再比如选举出一个新的 Controller 之后也会比较麻烦,因为需要加载元数据,而此时元数据的量可能已经非常大了,这就产生了效率问题。
所以,ZooKeeper 带来的复杂度、系统效率这两个问题已经成为 Kafka 的痛点,Kafka 团队一直在努力去除对 ZooKeeper 的依赖。Kafka 2.8.0 这个版本终于实现了。
使用 Raft 模式之后,元数据、配置信息都会保存在 @metadata
这个 Topic 中,自动在集群中复制。这样 Kafka 就会简单轻巧很多。
但需要注意的是,Zookeeper-less Kafka 还属于早期版本,并不完善,所以,现在不要应用在线上产品环境中。