Kafka上线了Log Compact功能后,Kafka由之前的一个DataHub, 也可以承担一个Database的作用
-
重要参数
1.开启Log Compact
cleanup.policy=compact
2.tombstone保留时间
delete.retention.ms=1000 保留delete tombstone的时间, 这是一种标记, 例如 key1:test, key1:null, 则表明删除key1的数据,但是key1:null这条record仍然存在,这参数控制key1:null这条record什么时候删除掉,这就是tombstone
3.Compact Lag
min.compaction.lag.ms=0 max.compaction.lag.ms=5000 kafka 2.3+ 才有的配置
4.Compact频率
min.cleanable.dirty.ratio=0.01 越大越高效,越小频率越高
5.多久生成新的segment,做测试用
segment.ms=5000 5秒生成一个segement
-
测试
-
创建Topic
./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic cmp_test_4 --partitions 1 --replication-factor 1 --config cleanup.policy=compact --config segment.ms=5000 --config min.cleanable.dirty.ratio=0.01 --config flush.messages=1 `
-
Produce数据
./kafka-console-producer.sh --broker-list localhost:9092 --topic cmp_test_4 --property "parse.key=true" --property "key.separator=:"` 1:test_v1 2:test_v1 3:test_v1 1:test_v2 3:test_v2
-
Consume数据
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --property "print.key=true" --topic cmp_test_4 实际consume数据 1 test_v1 2 test_v1 3 test_v1 1 test_v2 3 test_v2 理论上应该是 2 test_v1 1 test_v2 3 test_v2
这是由于head log不会被compact,所以展示上述结果, 必须等到所有数据在非head log里时,才能执行compact,把重复的去掉
发送none:done, 触发建立新的head log,之前的数据全部在非head log 中,数据正确
结论
- 理论上Kafka因Compact功能可以保证主键唯一性,但是由于compact机制,只能在非active的log中compact,所以极端情况,会发生数据compact滞后,导致数据更新不及时,因为有部分数据在active的head log中
解决办法:
- 每次push完数据后,经过segment.ms的时间后,发送一条mark message,如本文中的none:done,触发建立新的head log,将之前的数据全部一起compact