我有一个使用Kafka主题数据的消费者项目。该流中90%的数据可以实时处理,但对于特定记录(~10%),我需要延迟处理。
我是否应该在同一个JVM中有两个独立的使用者并在一个使用者中消耗90%的记录而忽略10%并让其他使用者处理它或将10%的消息推送到另一个主题并延迟处理另一个话题?
如果我有一个单一的消费者和两个检查点机制,一个90%,另一个延迟10%,但Kafka客户端似乎不支持这个用例,那将是很好的。这将有助于我避免任何不必要的反序列化和网络IO。
答案 0 :(得分:1)
单个消费者无法拥有多个检查点 - 使用两个消费者或两个主题。
两个消费者的一个问题是所有消息都会被读取两次,而不是在同一时间读取,这会导致问题知道消息何时是历史消息而不是消息:消息生成时会发生什么?这一天由一个消费者在23:59:59读取,另一个消费者在00:00:01读取(相对时间相同)。你可以使用一些滞后和监视滞后来防止这个问题。
将您的数据分为两个主题。您可以使用kafka流或任何其他流处理工具。例如,您的events
主题将在两个主题historical-events
和realtime-events
中处理和分隔。您仍然会有两个消费者,但不会有相同的主题。正如您所建议的那样,您也可以只使用events
主题,处理即时数据并将历史数据发送到其他主题(因此您有两个主题而不是三个主题,并且承诺偏移没有问题) - 但这意味着更多流程客户端的IO,以及客户端的两个职责
由于您只有一位消费者阅读基本主题中的每条消息,因此它将始终是最近的或历史的,因此您不会遇到上一个问题。
只有一个消费者会相应地处理消息,但正如您所指出的那样,对于偏移提交存在问题,并且在给定历史批次时可能会使用大量RAM。关于偏移提交,您可以简单地存储(在另一个kafka压缩主题中与_consumer_offset相同的方式)关于历史或当前偏移的最后一个偏移,并且在重新启动时,从历史批次中恢复,并忽略所有"最近"数据,直到达到正确的偏移量。这是可能的,但使用更多的RAM,并且更麻烦。
您的选择在很大程度上取决于您的问题(IO,RAM,只是有正确的行为)。从一开始就分离两个主题可能是最容易实现的,可以在一个单独的过程中完成,有效地分离每个过程的责任,并最大限度地减少对处理客户端的影响。