"Kafka partitions are immutable" 的真正含义是什么?

What does it really mean by "Kafka partitions are immutable"?

到目前为止我读过的所有 Kafka 教程中都提到了 "Kafka partitions are immutable"。但是,我还从该站点 https://towardsdatascience.com/log-compacted-topics-in-apache-kafka-b1aa1e4665a7 了解到,Kafka 会不时地删除分区中的旧消息(取决于您在 log-compact 命令中设置的保留时间)。从下面的截图可以看出,分区中删除重复的Keys后,分区内的数据发生了明显的变化:

所以我的问题是 "Kafka partitions are immutable" 到底是什么意思?

个别消息是不可变的。

压缩或保留将丢弃消息。它不会改变消息或偏移量

Kafka 分区被定义为 "immutable",指的是生产者可以将消息附加到分区本身而不更改现有分区的值(即使用相同的密钥)这一事实。从生产者的角度来看,分区本身是一个提交日志,仅在追加模式下工作。 当然,这意味着如果没有删除(通过保留时间)和压缩等任何机制,分区大小可能会无限增长。 在这一点上,你可以像你提到的那样想.. "so it's not immutable!"。 好吧,正如我所说,不变性是从生产者的角度来看的。删除和压缩是管理操作。 例如,删除记录也可以使用管理客户端 API ...但我们总是谈论管理的东西,而不是 producer/consumer 相关的东西。

如果您考虑压缩及其工作原理,例如,生产者最初发送一条消息,密钥 = A 且有效负载 = "Hello"。一段时间后,为了 "update" 该值,它发送了一条具有相同键 = A 和有效载荷 = "Hi" 的新消息......但实际上它是一条真正的新消息附加在分区日志的末尾;它将是代理中的压缩线程执行删除具有 "Hello" 有效载荷的旧消息的工作,只留下新消息。 以同样的方式,生产者可以发送带有 key = A 和 payload = null 的消息。这是实际删除消息的方式(null 称为 "tombstone")。无论如何,生产者仍在向分区附加一条新消息;它总是压缩线程,当它看到墓碑时,它会删除带有 key = A 的最后一条消息。

Kafka中的数据存储在主题中,主题被分区,每个分区进一步分为,最后每个段都有一个日志文件来存储实际的消息,一个索引文件存储消息在日志文件和时间索引文件中的位置,例如:

$ ls -l /mnt/data/kafka/*consumer*/00000000004618814867*
-rw-r--r-- 1 kafka kafka 10485760 Oct  3 23:41 /mnt/data/kafka/__consumer_offsets-7/00000000004618814867.index
-rw-r--r-- 1 kafka kafka  8189913 Oct  3 23:41 /mnt/data/kafka/__consumer_offsets-7/00000000004618814867.log
-rw-r--r-- 1 kafka kafka 10485756 Oct  3 23:41 /mnt/data/kafka/__consumer_offsets-7/00000000004618814867.timeindex

log.cleanup.policy(或特定主题的 cleanup.policy)设置为 delete 的情况下,发生完全删除一些日志段(一个或多个) .

在参数设置为 compact 的情况下,通过定期 recopying 日志段在后台完成压缩:它从从开始到结束删除日志中稍后出现的键。新的、干净的段会立即交换到日志中,因此所需的额外磁盘 space 只是一个额外的日志段(不是日志的完整副本)。换句话说,旧段被新的压缩段取代

查看有关分布式日志的更多信息:

https://kafka.apache.org/documentation.html#compaction

https://medium.com/@durgaswaroop/a-practical-introduction-to-kafka-storage-internals-d5b544f6925f

https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying

https://bookkeeper.apache.org/distributedlog/docs/0.5.0/user_guide/architecture/main

https://bravenewgeek.com/building-a-distributed-log-from-scratch-part-1-storage-mechanics/

不变性是 属性 存储在分区本身内的记录。当来源(文档或文章)在主题或分区的上下文中声明不变性时,它们通常指的是两件事之一,这两者在有限的上下文中都是正确的:

  1. 记录是不可变的。记录一旦写入,其内容将永远无法更改。当 (a) 由于保留限制而删除分区的内容,(b) 为取代原始记录的相同密钥添加新记录并发生压缩时,代理可以删除记录,或者 ( c) 为具有 null 值的相同键添加一条记录,作为墓碑记录,删除原始记录而不添加替换。

  2. 从客户端的角度来看,分区是仅附加的,因为不允许客户端修改记录或直接[=26] =] 从分区中删除记录,只附加到分区。这有点值得商榷,因为客户端可以通过压缩功能诱导删除记录,尽管这个操作是异步的,客户端不能准确指定应该删除哪条记录。