我试图使用Java Admin Client API的delete Records方法从kafka主题中删除消息。以下是我尝试过的步骤
1. I pushed 20000 records to my TEST-DELETE topic 2. Started a console consumer and consumed all the messages 3. Invoked my java program to delete all those 20k messages 4. Started another console consumer with a different group id. This consumer is not receiving any of the deleted messages
当我检查文件系统时,我仍然可以看到所有20k条记录都占用了磁盘空间。我的意图是也从文件系统中永久删除这些记录。
我的主题配置以及server.properties设置在下面给出
Topic:TEST-DELETE PartitionCount:4 ReplicationFactor:1 Configs:cleanup.policy=delete Topic: TEST-DELETE Partition: 0 Leader: 0 Replicas: 0 Isr: 0 Topic: TEST-DELETE Partition: 1 Leader: 0 Replicas: 0 Isr: 0 Topic: TEST-DELETE Partition: 2 Leader: 0 Replicas: 0 Isr: 0 Topic: TEST-DELETE Partition: 3 Leader: 0 Replicas: 0 Isr: 0
log.retention.hours=24 log.retention.check.interval.ms=60000 log.cleaner.delete.retention.ms=60000 file.delete.delay.ms=60000 delete.retention.ms=60000 offsets.retention.minutes=5 offsets.retention.check.interval.ms=60000 log.cleaner.enable=true log.cleanup.policy=compact,delete
我的删除代码在下面给出
public void deleteRecords(Map<String, Map<Integer, Long>> allTopicPartions) {
Map<TopicPartition, RecordsToDelete> recordsToDelete = new HashMap<>();
allTopicPartions.entrySet().forEach(topicDetails -> {
String topicName = topicDetails.getKey();
Map<Integer, Long> value = topicDetails.getValue();
value.entrySet().forEach(partitionDetails -> {
if (partitionDetails.getValue() != 0) {
recordsToDelete.put(new TopicPartition(topicName, partitionDetails.getKey()),
RecordsToDelete.beforeOffset(partitionDetails.getValue()));
}
});
});
DeleteRecordsResult deleteRecords = this.client.deleteRecords(recordsToDelete);
Map<TopicPartition, KafkaFuture<DeletedRecords>> lowWatermarks = deleteRecords.lowWatermarks();
lowWatermarks.entrySet().forEach(entry -> {
try {
logger.info(entry.getKey().topic() + " " + entry.getKey().partition() + " "
+ entry.getValue().get().lowWatermark());
} catch (Exception ex) {
}
});
}
下面是我的Java程序的输出
2019-06-25 16:21:15 INFO MyKafkaAdminClient:247 - TEST-DELETE 1 5000 2019-06-25 16:21:15 INFO MyKafkaAdminClient:247 - TEST-DELETE 0 5000 2019-06-25 16:21:15 INFO MyKafkaAdminClient:247 - TEST-DELETE 3 5000 2019-06-25 16:21:15 INFO MyKafkaAdminClient:247 - TEST-DELETE 2 5000
我的打算是从文件系统中删除消耗的记录,因为我正在为我的kafka代理使用有限的存储空间。
我想从下面的疑惑中寻求帮助
感谢您的帮助
谢谢
答案 0 :(得分:0)
处理此问题的推荐方法是为感兴趣的主题设置retention.ms
和相关的配置值。这样,您可以定义Kafka在删除数据之前将存储数据的时间,确保您所有的下游消费者都有机会先将数据拉出,然后再将其从Kafk集群中删除。
但是,如果您仍然要强制Kafka根据字节删除,则有log.retention.bytes
和retention.bytes
配置值。第一个是群集范围的设置,第二个是特定于主题的设置,默认情况下,它采用第一个设置为的设置,但是您仍然可以按每个主题覆盖它。 retention.bytes
号是每个分区强制执行的,因此您应将其乘以主题分区的总数。
但是请注意,如果您有一个失控的生产者突然开始生成大量数据,并且将其设置为硬字节限制,则可能会消灭集群中整天的数据,并且只剩下最后几分钟的数据,甚至在有效的使用者都无法从群集中提取数据之前。这就是为什么最好将您的kafka主题设置为基于时间的保留,而不是基于字节的保留。
您可以在Kafka官方文档中找到配置属性及其说明:https://kafka.apache.org/documentation/