我们有Kafka设置,可以通过多个服务器并行处理消息。但每条消息必须只处理一次(并且只能由一台服务器处理)。我们已经启动并运行它并且工作正常。
现在,我们面临的问题是Kafka消费者分批阅读消息以获得最大效率。如果/当处理失败,服务器关闭或其他什么时,这会导致问题,因为这样我们就会丢失即将处理的数据。
有没有办法让消费者一次只读取消息让Kafka保留未处理的消息?就像是;消费者提取一条消息 - >过程 - >完成后提交偏移量,重复。使用Kafka这是可行的吗?有什么想法/想法吗?
谢谢!
答案 0 :(得分:8)
您可以尝试将max.poll.records设置为1。
答案 1 :(得分:0)
你提到只有一个处理,但是你担心丢失数据。我假设你担心一个服务器出现故障时的边缘情况?你输了数据吗?
我认为没有办法一次完成一条消息。通过consumer configurations查看,似乎只有一个选项可以设置消费者可以从Kafka获取的最大字节数,而不是消息数。
fetch.message.max.bytes
但是如果你担心完全丢失数据,如果你从未提交过偏移,那么Kafka将不会标记为已提交并且不会丢失。 阅读有关delivery semantics,
的Kafka文档因此,Kafka保证默认情况下至少一次交付 允许用户通过禁用最多实施一次交付 生产者重试并在处理之前提交其偏移量 一批消息。完全一次交付需要与合作 目标存储系统但Kafka提供了偏移量 实现这一点是直截了当的。
因此,实现一次性处理不是Kafka默认启用的。每当您将处理输出写入存储时,它都要求您实现存储偏移量。
但是这可以更简单地处理,通常只需简单地处理 消费者将其偏移量存储在与其输出相同的位置......作为一个例子, 我们在HDFS中填充数据的Hadoop ETL将其偏移量存储在HDFS中 用它读取的数据,以保证数据和 偏移都被更新或两者都没有。
我希望有所帮助。
答案 2 :(得分:0)
这取决于您将使用的客户端。对于C ++和python,每次都可以使用 ONE 消息。
对于python,我使用了https://github.com/mumrah/kafka-python。以下代码每次都可以使用一条消息:
message = self.__consumer.get_message(block=False, timeout=self.IterTimeout, get_partition_info=True )
__ consumer是SimpleConsumer的对象。
请在此处查看我的问题和答案:How to stop Python Kafka Consumer in program?
对于C ++,我使用的是https://github.com/edenhill/librdkafka。以下代码每次都可以使用一条消息。
214 while( m_bRunning )
215 {
216 // Start to read messages from the local queue.
217 RdKafka::Message *msg = m_consumer->consume(m_topic, m_partition, 1000);
218 msg_consume(msg);
219 delete msg;
220 m_consumer->poll(0);
221 }
m_consumer是指向C ++ Consumer对象(C ++ API)的指针。
希望得到这个帮助。