1. 背景
在Kafka集群中,Topic的最佳配置也是最受欢迎的配置如下
replicas=3,min.insync.replicas=2,acks=-1
虽然这样的配置持久性最好,但是延时性也最差,因为需要ISR列表中所有副本确认收到消息之后才算成功。今天在社区的KIP中,发现已经有人实现了针对此场景的优化,今天分享给大家,翻译的内容可能与原版存在偏差,有兴趣可以查看原版。
2. 介绍
通常把Topic配置成replicas=3,min.insync.replicas=2,akcs=-1,目的是保证数据不丢,但是我们发现P999会出现很多毛刺,因为Producer请求需要ISR列表中所有副本确认收到数据之后才算成功,所以ISR列表中最慢的副本决定了P999的延迟。在生产环境,我们通常配置replica.lag.time.max.ms=10,防止ISR列表中的副本出现频繁抖动,但有时候会发现客户端在没有任何错误与重试的情况下,P999直接猛增到replica.lag.time.max.ms配置的值,原因是有副本拉取落后几秒钟,但依然在ISR列表里。
![](https://img.haomeiwen.com/i13417372/2a1b91a992d90e6b.png)
上边是Kafka集群P999一天的监控数据,大部分时间花费在了远程复制阶段(replicas=3 and acks=-1)。我们集群的P99已经相当稳定了,如果能把P999降低到与P99一样,将会使我们的服务更加稳健
3. 设计
针对上述场景我们想到了替代方案,此方案包括两部分
-
Topic级别增加新的配置项
配置项quorum.required.acks,默认-1表示此功能关闭,该配置的取值范围小于副本数(如果等于副本数,延迟比acks=-1还要槽糕)且大于1(如果设置为1,我们应该使用acks=1关闭此功能)。 -
改进新的Leader选举逻辑
在出现Leader选举时,选择具有最大LEO的副本作为新的Leader。当前最流行的配置如下,表明ISR列表中3个副本都得到消息确认就算动,当一台Broker出现问题,提交的消息就不会丢失。
如果我们使用以下配置,表明ISR列表中至少2个副本得到消息确认就算提交成功,然后立即返回给客户端。如果Leader出现问题,从剩下的2个副本中选择较大的LEO做为Leader,这样就保证了上一个Leader的所有消息replicas=3, ack=-1, min.insync.replicas=2
replicas=3, quorum.required.acks=2
以下是配置replicas=4,quorum.required.acks=2,4000QPS,单条数据2KB的P999延迟与配置的replicas=3,quorum.required.acks=2结果是非常相似的
image.png
网友评论