一、线上机器规划
二、线上问题优化
1、消息丢失的情况
消息发送端:
a:acks=0: 表示producer不需要等待broker确认收到消息的回复就可以继续发送消息;性能高,但很容易丢失消息;
b:acks=1: 表示producer只需要等待leader写入成功的回复消息就可以继续发送消息了,若果follower没有写入成功,leader宕机,则消息丢失;
c:acks=-1或all: 这意味着leader需要等待所有备份(min.insync.replicas配置的备份个数)都成功写入日志,才会回复确认收到的消息,producer才会继续提交消息;当然如果min.insync.replicas配置的是1则也可能丢消息,跟acks=1情况类似。
消费端消费:
如果消费这边配置的是自动提交,消费端未处理完,就自动提交offset了,但是此时你consumer直接宕机了,未处理完的数据丢失了,下次也消费不到了。
2、消息重复消费
消息发送端:发送端配置了超时重试,长时间未得到broker的回复,重新发送消息;
消息消费端:如果消费这边配置的是手动提交,刚拉取了一批数据处理了一部分,但还没来得及提交,服务挂了,重启后再次拉去消费。
解决方案:消费端应做好消费幂等的处理;
3、消费乱序
kafka消息的顺序消费要保证消息发送到同一个partition上,由于消费端消费的是固定的partition,才能保证消费顺序;
消息发送乱序:proudcer发送消息配置了重试,发送1、2、3三条消息,1消息发送失败重试,顺序则变成2、3、1;
kafka保证全链路消息顺序消费,需要从发送端开始,将所有有序消息发送到同一个分区,然后用一个消费者去消费,但是这种性能比较低,可以在消费者端接收到消息后将需要保证顺序消费的几条消费发到内存队列(可以搞多个),一个内存队列开启一个线程顺序处理消息。
4、消息积压
kafka的消息是定期删除的,不是消费完删除,是消费端消费滞后,所以kafka的消息积压指的是用户感知上的消息积压;
a:消息发送方发送过多消息,消费端消费过慢,代码层面做代码优化,提前预知可将消息分散到多个分片上,增加更多的消费者进行消费;(kafka的分片是被固定的消费者消费的,若消费者数量超出分片数量增加再多也没有意义,详见上一张讲解内容);
b:消费端有bug导致无法消费,可在消费的过程中将有问题的消息推送到其它topic(类似死信队列),再做相应处理,避免影响其它正常消费的消息;
5、延时队列(kafka不支持延时队列,需要自己实现)
所谓延时队列指的是消息发送后并不希望立即消费,需要等待一段时间再进行消费;
实现思路:发送延时消息时先把消息按照不同的延迟时间段发送到指定的队列中(topic_1s,topic_5s,topic_10s,...topic_2h,这个一般不能支持任意时间段的延时),然后通过定时器进行轮训消费这些topic,查看消息是否到期,如果到期就把这个消息发送到具体业务处、理的topic中,队列中消息越靠前的到期时间越早,具体来说就是定时器在一次消费过程中,对消息的发送时间做判断,看下是否延迟到对应时间了,如果到了就转发,如果还没到这一次定时任务就可以提前结束了。
6、消息回溯
如果某段时间对已消费消息计算的结果觉得有问题,可能是由于程序bug导致的计算错误,当程序bug修复后,这时可能需要对之前已消费的消息重新消费,可以指定从多久之前的消息回溯消费,这种可以用consumer的offsetsForTimes、seek等方法指定从某个offset偏移的消息开始消费,参见上节课的内容。
7、分区数越多吞吐量越高吗
kafka的分区数量可以根据kafka的脚本进行压测:往test里发送一百万消息,每条设置1KB
throughput 用来进行限流控制,当设定的值小于 0 时不限流,当设定的值大于 0 时,当发送的吞吐量大于该值时就会被阻塞一段时间
bin/kafka‐producer‐perf‐test.sh ‐‐topic test ‐‐num‐records 1000000 ‐‐record‐size 1024 ‐‐throughput ‐1 ‐‐producer‐props bootstrap.servers=192.168.65.60:9092 acks=1
一般情况下分片数量与broker数量一致性能最好(具体还是要通过压测决定),分区越多,多种因素会导致性能反而下降(磁盘,文件系统,I/O)
8、kafka的幂等性
proudcer重试发送多次消息,只需在生产者加上参数 props.put(“enable.idempotence”, true) 即可,默认是false不开启。
消费者发送的时候会自动携带PID+Sequence Number一起发送给broker;下次重发不会再接收;
9、kafka的事务
Kafka的事务不同于Rocketmq,Rocketmq是保障本地事务(比如数据库)与mq消息发送的事务一致性,Kafka的事务主要是保障一次发送多条消息的事务一致性(要么同时成功要么同时失败);
10、kafka高性能的原因
a、磁盘顺序读写
b、读写批量读取以及压缩传输
c、数据传输零拷贝