到目前为止,在我阅读的所有Kafka教程中,他们都提到“ Kafka分区是不可变的”。但是,我还从该站点https://towardsdatascience.com/log-compacted-topics-in-apache-kafka-b1aa1e4665a7上了解到,Kafka会不时删除分区中的旧消息(取决于您在log-compact命令中设置的保留时间)。您可以从下面的屏幕截图中看到,在删除分区中重复的键之后,分区中的数据已明显更改:
所以我的问题是,说“ Kafka分区是不可变的”到底是什么意思?
答案 0 :(得分:1)
单个消息是不可变的。
压缩或保留将删除消息。它不会更改消息或偏移量
答案 1 :(得分:1)
Tha Kafka分区被定义为“不可变的”,是指生产者可以将消息附加到分区本身,而不更改现有分区的值(即,使用相同的键)。从生产者的角度来看,分区本身是一个提交日志,仅在附加模式下工作。 当然,这意味着如果没有删除(按保留时间)和压缩之类的任何机制,分区大小就会无限增长。 此时,您可能会想..“所以它不是一成不变的!”就像你提到的 好吧,正如我所说的,不变性是从生产者的角度来看的。删除和压缩是管理操作。 例如,也可以使用Admin Client API删除记录...,但是我们一直在谈论管理内容,而不是生产者/消费者相关的东西。
如果您考虑压缩及其工作方式,那么生产者最初会发送例如键= A和有效载荷=“ Hello”的消息。一段时间后,为了“更新”该值,它会发送一条新消息,该消息具有相同的键= A和有效载荷=“ Hi” ...,但实际上这是在分区日志末尾附加的新消息;这将是代理中的压缩线程,它使用“ Hello”有效负载删除旧消息,而仅留下新消息。 生产者可以以相同的方式发送密钥= A且有效载荷= null的消息。这是实际删除消息的方式(null称为“逻辑删除”)。无论如何,生产者仍在向分区添加新消息。始终是压缩线程,它将在看到墓碑时删除键= A的最后一条消息。
答案 2 :(得分:1)
Kafka中的数据存储在主题中,主题进行了分区,每个分区又分为段,最后每个段都有一个日志文件来存储实际消息,一个索引文件来存储位置日志文件和timeindex文件中的消息,例如:
$ 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 的情况下,压缩是通过定期重新复制日志段在后台完成的:它从头到尾重新复制日志,删除具有以后出现在日志中。新的干净段将立即交换到日志中,因此所需的额外磁盘空间只是一个额外的日志段(不是完整的日志副本)。换句话说,旧段被新的压缩段代替
查看有关分布式日志的更多信息:
https://kafka.apache.org/documentation.html#compaction
https://medium.com/@durgaswaroop/a-practical-introduction-to-kafka-storage-internals-d5b544f6925f
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/
答案 3 :(得分:0)
不变性是存储在分区本身中的记录的属性。当来源(文档或文章)在主题或分区的上下文中声明不变性时,它们通常指的是以下两种情况之一,这两种情况在有限的上下文中都是正确的:
记录是不可变的。记录一旦写入,其内容将永远无法更改。当 (a) 由于保留限制而删除分区的内容时,代理可以删除记录,(b) 为取代原始记录的相同键添加新记录并进行压缩,或 ( c) 为同一个key添加一个值为null
的记录,作为tombstone记录,删除原记录,不添加替换。
从客户端的角度来看,分区只能追加,因为客户端不允许修改记录或直接从分区中删除记录,只能追加到分区。这有点值得商榷,因为客户端可以通过压缩功能诱导删除记录,尽管此操作是异步的,并且客户端无法准确指定应删除哪个记录。