kafka-python用户开始从偏移量自动读取

时间:2018-08-11 11:11:42

标签: python-3.x apache-kafka offset kafka-consumer-api kafka-python

我正在尝试使用kafka-python构建应用程序,其中消费者从一系列主题中读取数据。消费者永远不要两次阅读同一条消息,也永远不会错过任何一条消息,这一点非常重要。

除了我关闭使用者(例如失败)并尝试从偏移量开始读取之外,其他所有内容似乎都可以正常工作。我只能阅读主题中的所有消息(这会造成重复阅读),或者仅听新消息(并错过细分期间发出的消息)。暂停消费者时,我不会遇到此问题。

我创建了一个隔离的模拟以尝试解决该问题。

这里是通用生产者:

from time import sleep
from json import dumps
from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers=['localhost:9092'])

x=0 # set manually to avoid duplicates 

for e in range(1000):
    if e <= x:
        pass
    else:
        data = dumps(
            {
            'number' : e
        }
        ).encode('utf-8')

        producer.send('numtest', value=data)
        print(e, ' send.')

        sleep(5)

和消费者。如果auto_offset_reset设置为'earliest',则将再次读取所有消息。如果auto_offset_reset设置为'latest',则在停机期间将不会读取任何消息。

from kafka import KafkaConsumer
from pymongo import MongoClient
from json import loads

## Retrieve data from kafka (WHAT ABOUT MISSED MESSAGES?)
consumer = KafkaConsumer('numtest', bootstrap_servers=['localhost:9092'],
                         auto_offset_reset='earliest', enable_auto_commit=True,
                         auto_commit_interval_ms=1000)


## Connect to database
client = MongoClient('localhost:27017')
collection = client.counttest.counttest

# Send data
for message in consumer:
    message = loads(message.value.decode('utf-8'))
    collection.insert_one(message)
    print('{} added to {}'.format(message, collection))

我觉得自动提交无法正常工作。

我知道这个问题与this one类似,但是我想要一个具体的解决方案。

感谢您的帮助。

2 个答案:

答案 0 :(得分:6)

之所以会出现这种情况,是因为您的消费者没有使用消费者组。在消费者组中,消费者将定期向Kafka承诺(保存)其立场。这样,如果重新启动,它将从上次提交的位置开始拾取。

要使您的消费者使用消费者组,在构造它时需要设置group_id。 请参见docs中的group_id说明:

  

要加入动态分区的使用者组的名称   分配(如果启用),并用于获取和提交   抵消。如果为无,则自动分区分配(通过组协调器)   和偏移量提交被禁用。默认值:无

例如:

consumer = KafkaConsumer('numtest', bootstrap_servers=['localhost:9092'],
                         auto_offset_reset='earliest', enable_auto_commit=True,
                         auto_commit_interval_ms=1000, group_id='my-group')

答案 1 :(得分:0)

是否可以使用来自其他服务器的使用者。我已经在下面尝试了相同的代码,并且没有从kafka中获取任何数据。

consumer = KafkaConsumer('tet', bootstrap_servers=['192.168.1.20:9092'],
                     auto_offset_reset='earliest', enable_auto_commit=True,
                     auto_commit_interval_ms=1000, group_id=None)

注意:- 当我输入错误的IP或端口号时,会引发异常。