1.0-2.0
3.x 移处ZK
理想情况下,Consumer实例的数==该 Group 订阅Topic的分区总数。
假设一个 Consumer Group 订阅了 3 个主题,
分别是 A、B、C,它们的分区数依次是 1、2、3(总共是 6 个分区)。
为该 Group 设置 6 个 Consumer 实例是比较理想的情形,因为它能最大限度地实现高伸缩性。
如果设置 8 个实例,那么有 2 个实例(8 – 6 = 2)将不被分配分区,永远处于空闲状态。
位移
消费者在消费的过程中需要记录自己消费了多少数据(位移)
比如某个 Group 下有 20 个 Consumer 实例,它订阅了一个具有 100 个分区的 Topic。
正常情况下,Kafka 平均会为每个 Consumer 分配 5 个分区。
这个分配的过程就叫 Rebalance。
避免 Rebalance 的发生
在 Rebalance 过程中,所有 Consumer 实例都会停止消费,等待 Rebalance 完成。这是 Rebalance 为人诟病的一个方面。
位移主题的 Key 中应该保存 3 部分内容:
为每条消息定义消息键,简称为 Key。
保证同一个 Key 的所有消息都进入到相同的分区里面,由于每个分区下的消息处理都是有顺序的
但这种策略一般只针对那些大规模的Kafka集
群,特别是跨城市、跨国家甚至是跨大洲的集群。
Kafka 默认分区策略实际上同时实现了两种策略:如果指定了 Key,那么默认实现按消息键保序策略;如果没有指定 Key,则使用轮询策略。
producer端进行消息压缩,broker端保持消息压缩,consumer端解压缩,
在 Kafka 中,压缩可能发生在两个地方:生产者端和 Broker 端。
程序中配置 compression.type 参数即表示启用指定类型的压缩算法
spring.kafka.producer.compression-type=gzip
Producer 启动后生产的每个消息都是 GZIP 压缩过的,从而降低了Producer到Broker的网络传输,从而也降低了Broker的数据存储压力。
producer.properties
compression.type=none
其实大部分情况下 Broker 从 Producer 端接收到消息后 原封不动保存。
有两种例外情况就可能让 Broker 重新压缩消息。
比较
无消息丢失如何实现
Kafka 只对“已提交”的消息(committed message)做有限度的持久化保证。
(1)已成功提交
当 Kafka 的若干个 Broker 成功地接收到一条消息并写入到日志文件后,
它们会告诉生产者程序这条消息已成功提交。
(2)有限度的持久化
假如消息保存在 N 个 Kafka Broker 上,前提条件: N 个 Broker 中至少有 1 个存活。
只要这个条件成立,Kafka 就能保证你的这条消息永远不会丢失。
Producer 永远要使用带有回调通知的发送 API,也就是说不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。
当前的书签页是第 90 页,我先将书签放到第 100 页上,之后开始读书。
当阅读到第 95 页时,我临时有事中止了阅读。
那么问题来了,当我下次直接跳到书签页阅读时,我就丢失了第 96~99 页的内容。
解决办法:
(1)单线程消费
维持 【先消费消息,再更新位移】的顺序
(2)多线程消费
如果是多线程异步处理消费消息,Consumer 程序不要开启自动提交位移,而是要应用程序手动提交位移。
但是,这种处理方式可能带来的问题是【消息的重复处理】,同一页被读了很多遍。
索引文件(file)。每个索引对象在磁盘上都对应了一个索引文件。你可能注意到了,这个字段是 var 型,说明它是可以被修改的。难道索引对象还能动态更换底层的索引文件吗?是的。自 1.1.0 版本之后,Kafka 允许迁移底层的日志路径,所以,索引文件自然要是可以更换的。
起始位移值(baseOffset)。索引对象对应日志段对象的起始位移值。举个例子,如果你查看 Kafka 日志路径的话,就会发现,日志文件和索引文件都是成组出现的。比如说,如果日志文件是 00000000000000000123.log,正常情况下,一定还有一组索引文件 00000000000000000123.index、00000000000000000123.timeindex 等。这里的“123”就是这组文件的起始位移值,也就是 baseOffset 值。
索引文件最大字节数(maxIndexSize)。它控制索引文件的最大长度。Kafka 源码传入该参数的值是 Broker 端参数 segment.index.bytes 的值,即 10MB。这就是在默认情况下,所有 Kafka 索引文件大小都是 10MB 的原因。
索引文件打开方式(writable)。“True”以“读写”方式打开,“False”以“只读”打开。
常规索引
不同索引类型保存不同的
.index 文件
.timeindex 文件
Kafka 日志对象由多个日志段对象组成,而每个日志段对象会在磁盘上创建一组文件,包括
主流 Hash 散列算法介绍和使用
哈希算法简单来说就是将一个元素映射成另一个元素,可以简单分类两类,
MurMurHash的随机分布特征表现更良好,Redis,Memcached,Cassandra,HBase,Lucene中都使用到了这种hash算法。
Raft比ZK的ZAB协议更加易懂,也更加高效,partition的主选举将变得更快捷,controller的调度速度将上一个档次。
Kafka高可用 — KRaft集群搭建
kafka3.1集群搭建(kraft模式)
kafka核心技术实战