问:kafka是如何保障消息的可靠性的(一)
- 答:我在rabbitMQ系列分别从生产者,队列和消费者三方面,讨论了消息可靠性保证。而本系列要讨论的kafka和rabbit系列有诸多相似之处。
RabbitMQ传送门
本系列主要从以下几个方面来讨论下kafka的消息可靠性保证:
使用过kafka的小伙伴很清楚,kafka一大功能就是存储数据。既然是存储数据,就会有存储失败的可能性。大家使用kafka都希望我的数据能够不多不少存储到kafka中,加入一次不成功,那多试几次就好了。
问题就出现在这多试几次,和rabbitMQ一样,kafka也有消息落盘confirm机制。假如我的消息已经成功写入磁盘,但在返回confirm时由于网络中断等原因,返回响应失败了,producer就会认为没有写入成功,浴室就会触发retry机制。
一般我们为了保证消息正确写入磁盘会配置重试如下:
spring.kafka.producer.retries=3
触发重试机制后,producer会重新发送发送上次的消息,于是就有了生产端重复消息,这是我们不愿看到的。
设置幂等性
大家都听说过这一名词,即f(x)=f(f(x)).
// 启用幂等性 configs.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
Kafka为了实现幂等性,它在底层设计架构中引入了 ProducerID 和 SequenceNumber 。
问:4、kafka消息一致性
- 答:考虑如下一个问题:
某个topic下的某个partition, 假设他有3个副本(1个leader,2个follower);
在某个时刻,leader里有100条数据, 第1个follower里有80条数据, 第2个follower里有90条数据;
这个就是kafka数据一致性问题;
两个概念:
LEO( L og E nd O ffset):指每个副本的最大offset;
HW( H igh W ater):高水位,ISR队列里最小的 LEO ;
针对上面的例子, 三个partition的LEO分别是100、80、90,而三个partition的HW都是80(ISR队列中的最小的LEO);
处理方式是 新官上任三把火 ,当leader发生故障,重新选举新的leader后,新的ledaer要求其余follower将高于HW的数据接去掉,然后从新的leader重新同步数据;
注:这个只能保证副本之间数据的一致性,并不能保证数据不丢失或者不重复,数据丢失与否或者重复与否,是 ack 的值(0、1、或-1)来管的;
问:Kafka 如何保证消息的传递可靠性
- 答:kafka是一个分布式发布-订阅消息系统。其主要架构为:
基本保障:
Broker可靠性:
acks参数制定了必须有多少分区副本收到消息,生产者才会确认消息是写入成功的
retries 参数决定了生产者可以重发消息的次数。在充实过程中,消息会有一个主键,保证不会出现数据重复
当生产者写入消息遇到错误时: