Kafka中的数据可靠性保证---ack应答机制简解

1,867 阅读4分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

大数据集群框中基本都会使用Kafka,被数千家公司用于高性能的数据管道和关键任务应用。它的主要作用就是接收上游生产者的信息,然后传输给下游消费者,但这个接收上游信息的过程怎么才能保证数据的完整性呢,也就是如何做到接收过程不丢数据。

那么这就要说到Kafka的数据可靠性保证相关知识,为了做到数据的安全传输,Kafka使用了 ack应答机制,这就类似于网络安全中常用的 TCP的三次握手四次挥手

ack应答机制

在生产者(producer)往Kafka发送数据的过程中,为了保证数据可以发送到指定的topic中,topic中的每一个partition在收到数据后,都需要向生产者发送 ack(ackacknowledgement)。如果 producer 在一定的时间内收不到应答,那么producer会再次向Kafka发送此条数据。

那么这就类似于写信,假设我们写一封信给某人,然后我们会在一段时间后收到一封回信,但如果超过了一个月我们还没有收到回信,就会猜测是不是信件丢失了,会将这封信进行重新发送,直到收到回信为止。

image.png

1. 那么此时会有个问题,什么时候发送ack?

首先肯定不会在leader收到信息之后立马就发送ack,因为假设此时leader突然挂掉,没有备份,数据会永久丢失。所以会有这样的三个关键点:(1)leader在内存中接收到producer发送的数据(外网);(2)leader接收到数据之后会立马进行落盘(写入磁盘) (3)所有的folloewr同步落盘后的数据(内网)

image.png

副本数据的同步策略有两种:

  • 半数以上完成同步,就发送ack;
  • 全部完成同步,才会发送ack

kafka使用第二种同步策略,也就是等到全部的follower完成同步后,leader才会发送ack。

2. ISR机制

等到全部的follower完成同步后才会发送ack,那么这种方法有一个很大的缺陷就是:所有follower同步落盘的数据,但是有一个follower,因为某种故障,迟迟不能进行同步,那leader就要一直等下去,直到它完成同步,才能发送ack。针对此缺陷,Kafka采用了一个ISR机制,in-sync replica set,意为和 leader保持同步的follower集合。

如果 ISR 中的 follower 长时间未向 leader 同步数据,则该 follower 将被踢出ISR,该时间阈值由replica.lag.time.max.ms(10s) 参数设定。Leader发生故障之后,就会从ISR中选举新的leader。

3. ack的三种应答级别

Kafka为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,选择以下的配置。因为对于一些不重要的数据,我们能够容忍数据的少量丢失,所以不必等ISR中的folloewr全部接收成功。

acks参数配置:

0
能够提供了一个最低的延迟,leader接收到producer的消息后还没有写入磁盘就已经返回ack。那么当leader故障时或断电时就有可能 丢失数据

1
leader接收到数据并且落盘成功后返回ack,但如果在ISR中的follower同步数据成功之前leader发生故障,那么将大概率发生 丢失数据 的情况;

这是因为里面的一种机制会导致数据丢失--follower的上位机制。leader接收数据进行落盘并且发送ack后突然挂掉,但follower并没有同步到leader中的数据。此时follower需要上位成为新的leader,新的leader需要和剩下的follower进行数据同步,询问它们的分区offset是从几号开始的,因为它们之前并没有同步 "Hello" 那条数据,所以可以认为它们的分区号都是从0号开始。但反观producer,因为已经收到ack应答,所以不会再重复发送 "Hello" 这条数据,会直接进行下一条数据的传输。而且如果之前挂掉的leader重新启动后,它会作为follower重新加入ISR,它就会去询问新的leader数据的存储情况,因为新的leader中并没有 "Hello" 这条数据,所以这个follower会认为数据存储错误,把 "Hello" 数据删除。

image.png

image.png

-1(all)
leader接收数据并且落盘后,同时ISR中的follower全部同步成功后,leader才会发送ack,这是最安全的也是唯一一种不会造成数据丢失的应答级别。但是这种应答级别也会存在缺陷,比如如果在follower同步完成后,leader还未发送ack之前,leader发生故障,那么就有可能造成数据重复

follower同步完数据后,leader还未发送ack突然挂掉,生产者会再次向新的leader发送同一条数据,因此造成数据的重复。

image.png

image.png