我正在尝试使用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类似,但是我想要一个具体的解决方案。
感谢您的帮助。
答案 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或端口号时,会引发异常。