kafka-1-kafka运行异常的情况及解决方案

1 消费者consumer无法消费的异常

(1)异常现象:
服务器:record is corrupt(记录损坏)不明原因,有可能磁盘空间不足导致,导致消费者无法正常消费消息,卡在某一个offset不能继续消费。
(2)解决办法:
先停掉消费者程序,杀掉进程(不可关闭kafka服务)然后手动设置偏移量,跳过卡在的offset位置。
进入kafka目录,命令:
#bin/kafka-consumer-groups.sh --bootstrap-server ip:9092 --group groupName --reset-offsets --to-offset 1000 --topic topicName --execute
然后重启消费者程序。
(3)举例
在这里插入图片描述当前消费到的偏移量
实际已经写入的偏移量
延迟的偏移量

查看特定consumer group 详情,使用–group与–describe参数
#kafka-consumer-groups.sh --bootstrap-server hbak1:9092 --group consumer1 --describe
在这里插入图片描述分区2,当前偏移量为2
分区1,当前偏移量为0
分区0,当前偏移量为13

(3-1)设为offset10
#kafka-consumer-groups.sh --bootstrap-server hbak1:9092 --group consumer1 --re set-offsets --to-offset 10 --topic zb --execute
(3-2)设为offset0
#kafka-consumer-groups.sh --bootstrap-server hbak1:9092 --group consumer1 --re set-offsets --to-offset 0 --topic zb --execute
在这里插入图片描述从图中可以看出,如果设置偏移量为10。
分区2,偏移量会被设置为2
分区1,偏移量会被设置为0
(3-3)然后运行如下的程序
就会从偏移量位置开始消费了。

from kafka import KafkaConsumer

consumer = KafkaConsumer('zb', bootstrap_servers=['IP:9092'],group_id = "consumer1")
for msg in consumer:
    print((msg.value).decode('utf8'))

2 kafka的broker异常停止

(1)异常信息
[2020-11-14 03:19:25,498] INFO [ReplicaManager broker=0] Stopping serving replicas in dir /usr/local/kafka-logs (kafka.server.ReplicaManager)
[2020-11-14 03:19:25,498] ERROR Uncaught exception in scheduled task ‘kafka-log-start-offset-checkpoint’ (kafka.utils.KafkaScheduler)
org.apache.kafka.common.errors.KafkaStorageException: Error while writing to checkpoint file /usr/local/kafka-logs/log-start-offset-checkpoint
Caused by: java.io.FileNotFoundException: /usr/local/kafka-logs/log-start-offset-checkpoint.tmp (Too many open files)
在这里插入图片描述[2020-11-14 03:19:25,598] ERROR Shutdown broker because all log dirs in /usr/local/kafka-logs have failed (kafka.log.LogManager)
在这里插入图片描述 ERROR Shutdown broker because all log dirs in…have failed

kafka删除配置的log.dirs目录后,重启服务,报错如上。

解决方案:除了删除kafka该目录内容外,还需要删除zookeeper配置的dataDir目录内容,再重启zookeeper和kafka服务。

如果是重要数据,删除数据之前注意备份。

3 Zookeeper 3.5启动时 8080端口被占用

在这里插入图片描述发现8080端口被占用,通过查阅Zookeeper3.5的官方文档,发现这是Zookeeper3.5的新特性:这是Zookeeper AdminServer,默认使用8080端口,它的配置属性如下:
在这里插入图片描述
解决方式:修改在zoo.cfg中修改AdminServer的端口: admin.serverPort=8888

保存后,再次启动,Zookeeper启动成功。

4 kafka消费者报错INVALID_FETCH_SESSION_EPOCH

(1)警告信息

%2020-12-03 13:00:03:244 INFO  [org.springframework.kafka.KafkaListenerEndpointContainer#1-0-C-1]
 [o.a.k.c.FetchSessionHandler] - [Consumer clientId=consumer-4, groupId=realtime1] 
 Node 0 was unable to process the fetch request with (sessionId=1423337916, epoch=1079): 
 INVALID_FETCH_SESSION_EPOCH.

报错时,消费速率大大的减慢。
(2)问题原因
kafka的segement是可以滚动的,比如配置了
“log.roll.hours”: 24
那么每24小时就会滚动一次
或者配置了
“log.retention.hours”: 48
48小时以前的就会被删除
每次kafka滚动或者删除时消费者就会报这个错
(3)解决方案
这是一个kafka的bug,在高版本修复。2.0.0及之前的版本有问题,升级到2.0.4之后解决了这个问题。升级后虽然会继续报错,但不会影响任何东西。

5 kafka的默认__consumer_offsets自动创建失败

kafka在0.10.x版本后默认将消费者组的位移提交到自带的topic__consumer_offsets里面,当有消费者第一次消费kafka数据时就会自动创建,它的副本数不受集群配置的topic副本数限制,分区数默认50(可以配置),默认压缩策略为compact。

因为创建kafka的topic时可以通过命令指定。

kafka-topic.sh --create
--zookeeper pda1:2181
--replication-factor 1
--partitions 1
--topic test

也会在客户端未指定一些参数时,使用默认参数。

broker.id=1
listeners=PLAINTEXT://pda1:9092
log.dir=/usr/local/kafka/datalog
num.partitions=5
log.retention.hours=24
zookeeper.connect=pda1:2181
zookeeper.connection.timeout.ms=60000
offsets.topic.replication.factor=1

注意offsets.topic.replication.factor=1这个参数跟broker的个数相关,如果只有一个broker则只能设为1。否则会出问题,默认的__consmer_offsets不会自动创建。

6 Rebalance触发条件

rebalance触发的条件有以下3个。
(1)组成员发生变更,比如新consumer加入组,或已有consumer主动离开组,再或是已有consumer崩溃时则触发rebalance。
#tail -f server.log
在这里插入图片描述一般在重新启用程序时,会发生一次rebalance。

(2)组订阅topic数发生变更,比如使用基于正则表达式的订阅,当匹配正则表达式的新topic被创建时则会触发rebalance。

(3)组订阅topic的分区数发生变更,比如使用命令脚本增加了订阅topic的分区数。

真实应用场景中引发rebalance最常见的原因就是违背了第一个条件,特别是consumer崩溃的情况。这里的崩溃不一定就是指consumer进程“挂掉”或consumer进程所在的机器宕机。当consumer无法在指定的时间内完成消息的处理,那么coordinator就认为该consumer已经崩溃,从而引发新一轮rebalance。

相关的配置参数如下:

6.1 max.poll.interval.ms

max.poll.interval.ms参数用于指定consumer两次poll的最大时间间隔(默认5分钟),如果超过了该间隔consumer client会主动向coordinator发起LeaveGroup请求,触发rebalance;然后consumer重新发送JoinGroup请求。

max.poll.interval.ms默认值是5分钟,如果需要加大时长就需要给这个参数重新赋值。为什么要修改这个参数:因为第一次接收kafka数据,需要加载一堆基础数据,大概执行时间要8分钟,而5分钟后,kafka认为我没消费,又重新发送,导致我这边收到许多重复数据,所以我需要调大这个值,避免接收重复数据
max.poll.interval.ms = 600000

使用建议
(1)实际应用中,消费到的数据处理时长不宜超过max.poll.interval.ms,否则会触发rebalance。
(2)如果处理消费到的数据耗时,可以尝试通过减小max.poll.records的方式减小单次拉取的记录数(默认是500条)。

max.poll.records
该属性用于控制单次调用 call() 方法能够返回的记录数量,可以帮你控制在轮询里需要处理的数据量。

session.timeout.ms

该属性指定了消费者在被认为死亡之前可以与服务器断开连接的时间,默认是 3s。

如果消费者没有在 session.timeout.ms 指定的时间内发送心跳给群组协调器,就被认为已经死亡,协调器就会触发再均衡,把它的分区分配给群组里的其他消费者。

该属性与 heartbeat.interval.ms 紧密相关。heartbeat.interval.ms 指定了 poll() 方法向协调器发送心跳的频率,session.timeout.ms 则指定了消费者可以多久不发送心跳。

所以,一般需要同时修改这两个属性,heartbeat.interval.ms 必须比 session.timeout.ms 小,一般是 session.timeout.ms 的三分之一。如果session.timeout.ms 是 3s,那么 heartbeat.interval.ms 应该是 1s。把 session.timeout.ms 值设得比默认值小,可以更快地检测和恢复崩溃的节点,不过长时间的轮询或垃圾收集可能导致非预期的再均衡。把该属性的值设置得大一些,可以减少意外的再均衡,不过检测节点崩溃需要更长的时间。

7 kafka生产中消费速度慢的问题

最近在生产中,发现消费速度跟不上生产速度,kafka号称高吞吐,难道是kafka吐的太慢了?后来查了很多资料,发现是自己的消费者消费能力不行导致。

生产者一般不会有啥问题,因为是写进kafka,数据如果要处理的话,处理中的数据和kafka还没关系,等数据处理完要最终写入kafka的时候,这时候才是kafka吞的时候,一般不会有什么问题。

而消费者经常会有问题,大部分时候不是kafka吐数据能力不行,而是自己写的消费数据的程序不行,这个消费能力会受到比较多的因素影响,比如消费了一条数据就要把这条数据发给第三方接口,或者要经过复杂的逻辑处理等。这样一条数据消费完了才能继续消费下条数据。所以说要向实现消费追上甚至超过生产能力的话,就要多线程消费,批量消费。

(1)如果是Kafka消费能力不足,则可以考虑增加Topic的分区数,并且同时提升消费组的消费者数量,消费者数=分区数。(两者缺一不可)
(2)如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压。

多线程消费:
既然一个线程消费不过来,那么就多开线程,开十个线程,消费能力就提高了10倍。但前提是,要消费的topic的partition数也要相应的提高到10(partition数的大小决定最大消费线程数)。
举个例子:一个topic类似于一个蓄水池,而partition则是把这个蓄水池分成多个不同的小蓄水池,一个topic默认一个partition,而一个消费者就是一个人在这蓄水池取水,而这时候说的消费能力不足就是这个人取水的速度慢于蓄水池进水的速度,这样数据就会一直增加。
解决办法:
(1)提高这个人取水的速度(但这在实际生产中一般都是有上限的)
(2)多个一样的人一起取水(也就是上面说的多线程了),但是一个蓄水池(topic)只有一个分区(partition)开十个消费者线程(consumer )也是没用的,因为一个蓄水池只能同时由一个人来取水,其他九个就空闲了。而一个蓄水池分成十个小蓄水池后但只有一个消费者同样也是没用的,这个消费者的消费能力固定且要负责十个蓄水池的取水。所以分区消费者数量一样是合理的。
批量消费:
一次消费一批数据,然后在封装处理,总比一次消费一条数据来得快,但要注意,处理这一批数据的时间可能比处理一条数据的时间来的久,如果处理时间太久,超过了kafka的认定时间,kafka就会认为这个消费者挂了,从而踢掉重新分配一个消费者。
处理方式可以是:
(1)一次不拉过多的数据。
(2)kafka认定消费者挂了的时间设置久点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮冰燃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值