重新启动Kafka(python)使用者会再次消耗队列中的所有消息

时间:2014-07-09 18:46:11

标签: python apache-kafka

我正在使用Kafka 0.8.1和Kafka python-0.9.0。在我的设置中,我有2个kafka经纪人设置。当我运行我的kafka消费者时,我可以看到它从队列中检索消息并跟踪两个经纪人的偏移量。一切都很棒!

我的问题是,当我重新启动消费者时,它会从头开始消费消息。我所期待的是,重新启动后,消费者会开始在消息传出之前从消失的地方消费消息。

我确实尝试跟踪Redis中的消息偏移,然后在从队列中读取消息之前调用consumer.seek,以确保我只收到我以前没见过的消息。虽然这很有效,但在部署此解决方案之前,我想与y'所有人进行核实...也许我对Kafka或python-Kafka客户端产生了一些误解。似乎消费者能够从停止的地方重新开始读取是非常基本的功能。

谢谢!

5 个答案:

答案 0 :(得分:5)

小心使用kafka-python库。它有一些小问题。

如果速度对您的消费者来说不是真正的问题,您可以在每条消息中设置自动提交。它应该有用。

SimpleConsumer提供了一个seek方法(https://github.com/mumrah/kafka-python/blob/master/kafka/consumer/simple.py#L174-L185),允许您在任何需要的位置开始使用消息。

最常见的电话是:

  • consumer.seek(0, 0)从队列的开头开始阅读。
  • consumer.seek(0, 1)开始从当前偏移中读取。
  • consumer.seek(0, 2)跳过所有待处理的邮件,并开始只阅读新邮件。

第一个参数是这些位置的偏移量。这样,如果您拨打consumer.seek(5, 0),您将跳过队列中的前5条消息。

另外,不要忘记,为消费者群体存储偏移量。确保你一直使用同一个。

答案 1 :(得分:2)

kafka-python存储kafka服务器的偏移量,而不是单独的zookeeper连接。不幸的是,在apache kafka 0.8.1.1之前,支持提交/获取偏移的kafka服务器apis并不完全正常。如果您升级kafka服务器,您的设置应该有效。我还建议将kafka-python升级到0.9.4。

[kafka-python maintainer]

答案 2 :(得分:1)

首先,您需要设置一个group_id,记录偏移量,以便它将继续使用来自此group_id的消息。

如果您已经使用了组中所有现有的消息交换,则您要再次重新使用消息交换。您可以使用seek来实现。

这里是一个例子:

def test_consume_from_offset(offset):
    topic = 'test'
    consumer = KafkaConsumer(bootstrap_servers=broker_list, group_id='test')
    tp = TopicPartition(topic=topic, partition=0)
    consumer.assign([tp])
    consumer.seek(tp, offset)   # you can set the offset you want to resume from.
    for msg in consumer:
        # the msg begins with the offset you set
        print(msg)

test_consume_from_offset(10)

答案 3 :(得分:0)

卡夫卡消费者is able to store offsets in Zookeeper。在Java API中,我们有two options - 高级消费者,为我们管理状态并开始消耗重启后的状态,以及没有超级大国的无状态低级消费者。

根据我在Python的消费者代码(https://github.com/mumrah/kafka-python/blob/master/kafka/consumer.py)中的理解,SimpleConsumerMultiProcessConsumer都是有状态的并且跟踪Zookeeper中的当前偏移量,所以很奇怪你有这个重建问题。

确保重启后有相同的使用者组ID(可能是您随机设置的吗?)并检查以下选项:

auto_commit: default True. Whether or not to auto commit the offsets
auto_commit_every_n: default 100. How many messages to consume
                     before a commit
auto_commit_every_t: default 5000. How much time (in milliseconds) to
                     wait before commit

可能是你消费< 100条消息或< 5000毫秒?

答案 4 :(得分:0)

您只需要确保您的Kafka Consumer从最新偏移量(auto.offset.reset="latest")开始读取即可。另外,请确保定义了一个消费者组,以便可以提交偏移量,并且当消费者下降时可以选择其最后提交的位置。


使用std::numeric_limits

from confluent_kafka import Consumer


c = Consumer({
    'bootstrap.servers': 'localhost:9092',
    'group.id': 'mygroup',
    'auto.offset.reset': 'latest'
})

c.subscribe(['my_topic'])

使用confluent-kafka-python

from kafka import KafkaConsumer


consumer = KafkaConsumer(
    'my_topic', 
    bootstrap_servers=['localhost:9092'],
    auto_offset_reset='latest', 
    enable_auto_commit=True,
    group_id='mygroup'
)