这篇文章是从我们介绍Kafka 体系结构的一系列文章中获得的启发,包括Kafka topic架构,Kafka生产者架构,Kafka消费者架构和Kafka生态系统架构。
这篇文章的灵感在很大程度上来源于Kafka section on design around log compaction。
你可以认为它是关于Kafka日志结构设计的精简笔记。
卡夫卡可以根据日志的时间或大小删除旧记录。Kafka还支持记录关键字压缩。日志压缩意味着Kafka将保留最新版本的日志记录,并在日志压缩中删除旧版本。
Jean-Paul Azar在Cloudurable工作。Cloudurable提供Kafka培训,Kafka咨询,Kafka支持并帮助在AWS中设置Kafka群集。
日志压缩至少保留每个主题部分的每个记录key的最新值。压缩日志对于系统崩溃或系统故障后恢复到原来状态很有帮助。
它们对于基于内存中的服务,数据持久化存储,重新加载缓存等非常有用。一个关于数据流的
重要用例是记录数据表的键控变化,可变数据的更改或内存中微服务中对象的更改。
日志压缩是一种粒度保留机制,可保留每个key的最新更新。日志压缩主题日志包含每个记录key的最终记录值的完整快照,而不仅仅是最近更改的密钥。
Kafka日志压缩允许下游消费者从日志压缩主题恢复他们的状态。
通过压缩日志,日志具有头部和尾部。压缩日志的头部与传统的Kafka日志相同。新记录会追加到头部的末尾。
所有日志压缩都在日志的尾部运行。只有尾部得到压缩。在用压缩清理软件重写后,日志尾部的记录保留其原始偏移量。
卡夫卡日志压缩体系结构
所有压缩日志的偏移量仍然有效,即使在偏移量位置的记录已被压缩,因为消费者将获得下一个最高偏移量。
卡夫卡日志压缩也允许删除。一个带有key和空有效负载的消息的作用类似于墓碑,即该key的删除标记。墓碑在一段时间后被清除。通过重新复制日志段,日志压缩定期在后台运行。压缩不会阻塞读取操作,并且可以进行限制以避免影响生产者和消费者的I / O。
如果一个卡夫卡消费者一直跟踪日志头部,它会看到每个写入的记录。
Topic config min.compaction.lag.ms
可用于保证在压缩消息之前必须经过的最短时间。只要消费者在小于Topic config配置的时间段内(默认值为24小时)达到日志首部,消费者就会看到所有墓碑。日志压缩永远不会重新排序消息,只删除一些。消息的分区偏移不会改变。min.compaction.lag.msdelete.retention.ms
任何从日志开头阅读的消费者至少可以按照他们写入的顺序查看所有记录的最终状态。
回想一下,每个卡夫卡主题有一个日志。一个日志被分解成小分区,小分区被分割成包含有键和值的记录的段。
卡夫卡日志清洁员实现日志压缩。该日志清洁员有一个后台压缩线程池。这些线程会重新记录日志段文件,删除在最近在日志中重新出现过的key的旧记录。每个压缩线程选择日志头与日志尾部比率最高的主题日志。然后,压缩线程开始从头到尾重新复制日志,同时会删除那些key在稍后会重复出现的记录。
当日志清理器清理日志分区段时,这些段会立即替换旧分段而被换入日志分区。这样压缩并不需要整个分区的空间增加一倍,因为所需的额外磁盘空间只是一个额外的日志分区段 - 分而治之。
要打开主题的压缩功能,使用主题配置 log.cleanup.policy=compact
要设置延迟压缩日志的时间,请使用topic config: log.cleaner.min.compaction.lag.ms=[ms]。
直到这段时间之后,记录才会被压缩。该设置让消费者有时间获得每一条记录。
卡夫卡可以根据日志的时间或大小删除旧记录。Kafka还支持记录key压缩的日志压缩。
由于日志压缩保留了最新的值,因此它是最新记录的完整快照,对于基于内存中的服务,持久化数据存储或重新加载缓存在系统崩溃或系统故障后恢复状态非常有用。它允许下游消费者恢复他们的状态。
对于压缩的日志,它具有头部和尾部。压缩日志的头部与传统的Kafka日志相同。新记录会追加到头部的末尾。所有日志压缩都在压缩日志的尾部工作。
压缩后,日志记录的偏移量会发生变化吗?不会。
回想一下,一个话题有一个日志。一个主题日志被分解为不同的分区,分区又被分成包含具有键和值的记录的分段文件。分段文件允许在压缩日志时进行分而治之。段文件是分区的一部分。当日志清理程序清理日志分区段时,段会立即替换旧段文件而交换到日志分区。这种压缩方式不需要整个分区的空间增加一倍,因为所需的额外磁盘空间只是一个额外的日志分区段。
Jean-Paul Azar在Cloudurable工作。Cloudurable提供Kafka培训,Kafka咨询,Kafka支持并帮助在AWS中设置Kafka群集。