由于使用structured streaming +kafka 处理数据,任务运行一段时间后就会出现Kafka数据无法消费,任务运行正常,但是从日志中看到This member will leave the group 。。。的输出。由于是structured streaming做的,所以在设置Kafka参数时,在任务中是否生效,在测试,所以先记录一下,预知下文如何,且看下次分解。
1,consumer poll一次数据,处理时间过长,第二次consumer poll又来了
kafka消费端 poll数据的时候一次poll数据太多,由于是structured streaming做的流处理,在数据业务逻辑的处理与数据输出到数据库的原因,处理的时间有点长。导致一批数据处理完成的周期较长,导致下一次poll的时间太长,超出了消费者和broker联系的心跳时间(消费端调用poll方法的时候回进行一次心跳),超出这个心跳时间,broker就会认为这个消费者挂了,所以就会抛出上面的异常,并且对消费者通过算法重新rebalance。
2020-03-15 16:47:32 WARN AbstractCoordinator:[Consumer clientId=consumer-1, groupId=spark-kafka-source-f1681175-3b4f-414a-926e-6dbdd1d39656--1373084301-driver-0] This member will leave the group because consumer poll timeout has expired. This means the time between subsequent calls to poll() was longer than the configured max.poll.interval.ms, which typically implies that the poll loop is spending too much time processing messages. You can address this either by increasing max.poll.interval.ms or by reducing the maximum size of batches returned in poll() with max.poll.records.
上面的报错已经说的很清楚了,二次poll的时间间隔超过了max.poll.interval.ms设置,解决办法:1,加大max.poll.interval.ms的时间,2,减少max.poll.records的请求的条数,或者二个同时间调整。
在这里要注意:怎么调整参数,要根据topic里面单条数据的大小,以及插入到topic里面数据的频率,cpu,内存来决定。这块要亲自的实验一下,才知道。
如果consumer单条数据很小,max.poll.records设置的又比较少,这样就会导致,入hdfs时,小文件问题,很浪费系统资源。
2,kafka 消费者默认配置如下
auto.commit.interval.ms = 1000
auto.offset.reset = latest
bootstrap.servers = [bigserver1:9092, bigserver2:9092, testing:9092]
check.crcs = true
client.dns.lookup = default
client.id =
connections.max.idle.ms = 540000
default.api.timeout.ms = 60000
enable.auto.commit = true
exclude.internal.topics = true
fetch.max.bytes = 52428800
fetch.max.wait.ms = 500
fetch.min.bytes = 1
group.id = track_pc
heartbeat.interval.ms = 3000
interceptor.classes = []
internal.leave.group.on.close = true
isolation.level = read_uncommitted
key.deserializer = class org.apache.kafka.common.serialization.StringDeserializer
max.partition.fetch.bytes = 1048576
max.poll.interval.ms = 300000
max.poll.records = 500
metadata.max.age.ms = 300000
metric.reporters = []
metrics.num.samples = 2
metrics.recording.level = INFO
metrics.sample.window.ms = 30000
partition.assignment.strategy = [class org.apache.kafka.clients.consumer.RangeAssignor]
receive.buffer.bytes = 65536
reconnect.backoff.max.ms = 1000
reconnect.backoff.ms = 50
request.timeout.ms = 10000
retry.backoff.ms = 100
sasl.client.callback.handler.class = null
sasl.jaas.config = null
sasl.kerberos.kinit.cmd = /usr/bin/kinit
sasl.kerberos.min.time.before.relogin = 60000
sasl.kerberos.service.name = null
sasl.kerberos.ticket.renew.jitter = 0.05
sasl.kerberos.ticket.renew.window.factor = 0.8
sasl.login.callback.handler.class = null
sasl.login.class = null
sasl.login.refresh.buffer.seconds = 300
sasl.login.refresh.min.period.seconds = 60
sasl.login.refresh.window.factor = 0.8
sasl.login.refresh.window.jitter = 0.05
sasl.mechanism = GSSAPI
security.protocol = PLAINTEXT
send.buffer.bytes = 131072
session.timeout.ms = 10000
ssl.cipher.suites = null
ssl.enabled.protocols = [TLSv1.2, TLSv1.1, TLSv1]
ssl.endpoint.identification.algorithm = https
ssl.key.password = null
ssl.keymanager.algorithm = SunX509
ssl.keystore.location = null
ssl.keystore.password = null
ssl.keystore.type = JKS
ssl.protocol = TLS
ssl.provider = null
ssl.secure.random.implementation = null
ssl.trustmanager.algorithm = PKIX
ssl.truststore.location = null
ssl.truststore.password = null
ssl.truststore.type = JKS
value.deserializer = class org.apache.kafka.common.serialization.StringDeserializer
主要调优参数如下:
session.timeout.ms
这个值是会话超时时间,什么意思了,就是说如果发送心跳时间超过这个时间,broker就会认为消费者死亡了,默认值是10000ms,也就是10s(这个值一般默认没问题)
heartbeat.interval.ms
这个值是心跳时间,表示多长时间想broker报告一次,这个默认值3000ms,这个值官方推荐不要高于session.timeout.ms 的1/3(这个值默认没问题)
enable.auto.commit
是否启用自动提交。
auto.commit.interval.ms
自动提交间隔
max.poll.interval.ms
每俩次poll拉取数据时间间隔最大超时时间,超过这个值,
auto.offset.reset
earliest 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费 latest 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
heartbeat.interval.ms
heartbeat心跳主要用于沟通交流,及时返回请求响应。这个时间间隔真是越快越好。因为一旦出现reblance,那么就会将新的分配方案或者通知重新加入group的命令放进心跳响应中.使用Kafka的群组管理工具时,预期到消费者协调员的两次心跳之间的时间。心跳用于确保消费者的会话保持活动状态,并在新消费者加入或离开该组时促进重新平衡。该值必须设置为小于session.timeout.ms
,但通常应设置为不大于该值的1/3。可以将其调整得更低,以控制正常重新平衡的预期时间
request.timeout.ms
这个配置控制一次请求响应的最长等待时间。如果在超时时间内未得到响应,kafka要么重发这条消息,要么超过重试次数的情况下直接置为失败。
auto.offset.reset
1) earliest:自动重置到最早的offset。
2) latest:看上去重置到最晚的offset。
3) none:如果边更早的offset也没有的话,就抛出异常给consumer,告诉consumer在整个consumer group中都没有发现有这样的offset。
4) 如果不是上述3种,只抛出异常给consumer。
fetch.min.bytes
服务器应为获取请求返回的最小数据量。如果没有足够的数据,则请求将等待该数据积累,然后再回答请求。默认设置为1字节,这意味着只要有一个字节的数据可用,或者提取请求超时等待数据到达,就将对提取请求进行应答。将此值设置为大于1的值将导致服务器等待大量数据累积,这可以以一些额外的延迟为代价提高服务器吞吐量。