Java 卡夫卡消费者多次收到同一信息

Java 卡夫卡消费者多次收到同一信息,java,apache-kafka,kafka-consumer-api,Java,Apache Kafka,Kafka Consumer Api,我最近开始使用卡夫卡来阅读通过网络爬虫获取的文档。我注意到的是,当我处理数百万个文档时,消费者一次又一次地处理同一条消息。由于某种原因,数据似乎未提交。当我用几百条消息测试消费者时,情况并非如此 我正在使用java中的kafka高级消费客户机代码。我使用的消费者组运行的线程数相当于分区数。因此,每个线程都被划分为一个分区。下面是用于轮询数据的代码片段 以下是完整的消费者配置: metric.reporters = metadata.max.age.ms = 300000 partition

我最近开始使用卡夫卡来阅读通过网络爬虫获取的文档。我注意到的是,当我处理数百万个文档时,消费者一次又一次地处理同一条消息。由于某种原因,数据似乎未提交。当我用几百条消息测试消费者时,情况并非如此

我正在使用java中的kafka高级消费客户机代码。我使用的消费者组运行的线程数相当于分区数。因此,每个线程都被划分为一个分区。下面是用于轮询数据的代码片段


以下是完整的消费者配置:

metric.reporters = 
metadata.max.age.ms = 300000
partition.assignment.strategy = [org.apache.kafka.clients.consumer.RangeAssignor]
reconnect.backoff.ms = 50
sasl.kerberos.ticket.renew.window.factor = 0.8
max.partition.fetch.bytes = 1048576
bootstrap.servers = [kafkahost1:9092, kafkahost2:9092]
ssl.keystore.type = JKS
enable.auto.commit = true
sasl.mechanism = GSSAPI
interceptor.classes = null
exclude.internal.topics = true
ssl.truststore.password = null
client.id =ssl.endpoint.identification.algorithm = null
max.poll.records = 2147483647
check.crcs = true
request.timeout.ms = 181000
heartbeat.interval.ms = 3000
auto.commit.interval.ms = 1000
receive.buffer.bytes = 65536
ssl.truststore.type = JKS
ssl.truststore.location = null
ssl.keystore.password = null
fetch.min.bytes = 1
send.buffer.bytes = 131072
value.deserializer = class com.test.preprocessor.consumer.serializer.KryoObjectSerializer
group.id = full_group
retry.backoff.ms = 100
sasl.kerberos.kinit.cmd = /usr/bin/kinit
sasl.kerberos.service.name = null
sasl.kerberos.ticket.renew.jitter = 0.05
ssl.trustmanager.algorithm = PKIX
ssl.key.password = null
fetch.max.wait.ms = 500
sasl.kerberos.min.time.before.relogin = 60000
connections.max.idle.ms = 540000
session.timeout.ms = 180000
metrics.num.samples = 2
key.deserializer = class org.apache.kafka.common.serialization.StringDeserializer
ssl.protocol = TLS
ssl.provider = null
ssl.enabled.protocols = [TLSv1.2, TLSv1.1, TLSv1]
ssl.keystore.location = null
ssl.cipher.suites = null
security.protocol = PLAINTEXT
ssl.keymanager.algorithm = SunX509
metrics.sample.window.ms = 30000
auto.offset.reset = latest

公制单位=
metadata.max.age.ms=300000
partition.assignment.strategy=[org.apache.kafka.clients.consumer.RangeAssignor]
重新连接.backoff.ms=50
sasl.kerberos.ticket.renew.window.factor=0.8
max.partition.fetch.bytes=1048576
bootstrap.servers=[kafkahost1:9092,kafkahost2:9092]
ssl.keystore.type=JKS
enable.auto.commit=true
sasl.mechanism=GSSAPI
interceptor.classes=null
exclude.internal.topics=true
ssl.truststore.password=null
client.id=ssl.endpoint.identification.algorithm=null
max.poll.records=2147483647
check.crcs=true
request.timeout.ms=181000
heartbeat.interval.ms=3000
auto.commit.interval.ms=1000
receive.buffer.bytes=65536
ssl.truststore.type=JKS
ssl.truststore.location=null
ssl.keystore.password=null
fetch.min.bytes=1
send.buffer.bytes=131072
value.deserializer=class com.test.preprocessor.consumer.serializer.KryoObjectSerializer
group.id=完整组
retry.backoff.ms=100
sasl.kerberos.kinit.cmd=/usr/bin/kinit
sasl.kerberos.service.name=null
sasl.kerberos.ticket.renew.jitter=0.05
ssl.trustmanager.algorithm=PKIX
ssl.key.password=null
fetch.max.wait.ms=500
sasl.kerberos.min.time.before.relogin=60000
connections.max.idle.ms=540000
session.timeout.ms=180000
metrics.num.samples=2
key.deserializer=类org.apache.kafka.common.serialization.StringDeserializer
ssl.protocol=TLS
ssl.provider=null
ssl.enabled.protocols=[TLSv1.2、TLSv1.1、TLSv1]
ssl.keystore.location=null
ssl.cipher.suites=null
security.protocol=明文
ssl.keymanager.algorithm=SunX509
metrics.sample.window.ms=30000
auto.offset.reset=最新版本
我的示例kafka队列有8个分区,具有2个复制因子

server.properties中的日志保留期设置为168小时。

log.retention.hours=168
log.roll.hours=168

不确定我在这里遗漏了什么。

我将消费者属性中的
auto.commit.interval.ms=8000
3000
增加到
8000
。这修复了重复记录的问题

我猜是分区分配的问题。

也不确定。然而,只要您的使用者正在运行,他们就会在内存中保持偏移量——提交偏移量仅用于在使用者关闭或崩溃时保留偏移量。因此,在每次
poll()
之后,偏移量将提前。@MatthiasJ.Sax。。。谢谢根据日志,我可以看到消费者组下的不同线程正在接收相同的消息。是否有可能将相同的消息传递到多个分区?我可以看到偏移量越来越高。我的目的是试图了解这背后可能的原因,以便我能够避免。配置参数中是否有任何可以避免这种情况的调整?感谢您的反馈。如果所有线程都使用相同的
group.id
,则每个分区应该只分配给一个线程。只有在重新平衡的情况下(如果新消费者加入或离开组),才会出现重复消息。您能仔细检查分区分配吗?@MatthiasJ.Sax。。我增加了分区/使用者线程的数量,并在队列中添加了几百万条消息。仔细检查日志后,我发现以下警告,这解释了使用者循环问题。“组满时自动偏移提交失败\u组:提交无法完成,因为该组已重新平衡并将分区分配给另一个成员”。我的max.poll.records=20000,session.timeout.ms=180000ms。我想我需要围绕这一点进行优化设置。只是想知道是否有一个最佳实践/经验法则?如果您以1:1的线程/分区比同步发送/接收,我认为将maxInFlightConnections值设置为1可能会有所帮助。默认值为5。

consumer.auto.commit=true
consumer.auto.commit.interval=1000
consumer.session.timeout=180000
consumer.poll.records=2147483647
consumer.request.timeout=181000

metric.reporters = 
metadata.max.age.ms = 300000
partition.assignment.strategy = [org.apache.kafka.clients.consumer.RangeAssignor]
reconnect.backoff.ms = 50
sasl.kerberos.ticket.renew.window.factor = 0.8
max.partition.fetch.bytes = 1048576
bootstrap.servers = [kafkahost1:9092, kafkahost2:9092]
ssl.keystore.type = JKS
enable.auto.commit = true
sasl.mechanism = GSSAPI
interceptor.classes = null
exclude.internal.topics = true
ssl.truststore.password = null
client.id =ssl.endpoint.identification.algorithm = null
max.poll.records = 2147483647
check.crcs = true
request.timeout.ms = 181000
heartbeat.interval.ms = 3000
auto.commit.interval.ms = 1000
receive.buffer.bytes = 65536
ssl.truststore.type = JKS
ssl.truststore.location = null
ssl.keystore.password = null
fetch.min.bytes = 1
send.buffer.bytes = 131072
value.deserializer = class com.test.preprocessor.consumer.serializer.KryoObjectSerializer
group.id = full_group
retry.backoff.ms = 100
sasl.kerberos.kinit.cmd = /usr/bin/kinit
sasl.kerberos.service.name = null
sasl.kerberos.ticket.renew.jitter = 0.05
ssl.trustmanager.algorithm = PKIX
ssl.key.password = null
fetch.max.wait.ms = 500
sasl.kerberos.min.time.before.relogin = 60000
connections.max.idle.ms = 540000
session.timeout.ms = 180000
metrics.num.samples = 2
key.deserializer = class org.apache.kafka.common.serialization.StringDeserializer
ssl.protocol = TLS
ssl.provider = null
ssl.enabled.protocols = [TLSv1.2, TLSv1.1, TLSv1]
ssl.keystore.location = null
ssl.cipher.suites = null
security.protocol = PLAINTEXT
ssl.keymanager.algorithm = SunX509
metrics.sample.window.ms = 30000
auto.offset.reset = latest
log.retention.hours=168
log.roll.hours=168