共计 2930 个字符,预计需要花费 8 分钟才能阅读完成。
Kafka 有两个很重要的配置参数,acks
与 min.insync.replicas
. 其中acks
是 producer 的配置参数,min.insync.replicas
是 Broker 端的配置参数,这两个参数对于生产者不失落数据起到了很大的作用. 接下来,本文会以图示的形式解说这两个参数的含意和应用形式。通过本文,你能够理解到:
- Kafka 的分区正本
- 什么是同步正本(In-sync replicas)
- 什么是 acks 确认机制
- 什么是最小同步正本
- ack=all 与最小同步正本是如何发挥作用的
分区正本
Kafka 的 topic 是能够分区的,并且能够为分区配置多个正本,改配置能够通过 replication.factor
参数实现. Kafka 中的分区正本包含两种类型:领导者正本(Leader Replica)和追随者正本(Follower Replica),每个分区在创立时都要选举一个正本作为领导者正本,其余的正本主动变为追随者正本. 在 Kafka 中,追随者正本是不对外提供服务的,也就是说,任何一个追随者正本都不能响应消费者和生产者的读写申请. 所有的申请都必须由领导者副原本解决. 换句话说,所有的读写申请都必须发往领导者正本所在的 Broker,由该 Broker 负责解决. 追随者正本不解决客户端申请,它惟一的工作就是从领导者正本 异步拉取 音讯,并写入到本人的提交日志中,从而实现与领导者正本的同步.
Kafka 默认的正本因子是 3,即每个分区只有 1 个 leader 正本和 2 个 follower 正本. 具体如下图所示:
下面提到生产者客户端仅写入 Leader broker,跟随者异步复制数据。因为 Kafka 是一个分布式系统,必然会存在与 Leader 不能实时同步的危险,所以须要一种办法来判断这些追随者是否跟上了领导者的步调, 即追随者是否同步了最新的数据. 换句话说,Kafka 要明确地通知咱们,追随者正本到底在什么条件下才算与 Leader 同步?这就是上面所要说的 ISR 同步正本机制.
同步正本(In-sync replicas)
In-sync replica(ISR)称之为同步正本,ISR 中的正本都是与 Leader 进行同步的正本,所以不在该列表的 follower 会被认为与 Leader 是不同步的. 那么,ISR 中存在是什么正本呢?首先能够明确的是:Leader 正本总是存在于 ISR 中. 而 follower 正本是否在 ISR 中,取决于该 follower 正本是否与 Leader 正本放弃了“同步”.
尖叫提醒:对于 ”follower 正本是否与 Leader 正本放弃了同步 ” 的了解如下:
(1)下面所说的同步不是指齐全的同步,即并不是说一旦 follower 正本同步滞后与 Leader 正本,就会被踢出 ISR 列表.
(2)Kafka 的 broker 端有一个参数
replica.lag.time.max.ms
, 该参数示意 follower 正本滞后与 Leader 正本的最长工夫距离,默认是 10 秒. 这就意味着,只有 follower 正本落后于 leader 正本的工夫距离不超过 10 秒,就能够认为该 follower 正本与 leader 正本是同步的,所以哪怕以后 follower 正本落后于 Leader 正本几条音讯,只有在 10 秒之内赶上 Leader 正本,就不会被踢出出局.(3)如果 follower 正本被踢出 ISR 列表,等到该正本追上了 Leader 正本的进度,该正本会被再次退出到 ISR 列表中,所以 ISR 是一个动静列表,并不是动态不变的。
如上图所示:Broker3 上的 partition1 正本超过了规定工夫,未与 Leader 正本同步,所以被踢出 ISR 列表,此时的 ISR 为[1,3].
acks 确认机制
acks 参数指定了必须要有多少个分区正本收到音讯,生产者才认为该音讯是写入胜利的,这个参数对于音讯是否失落起着重要作用,该参数的配置具体如下:
- acks=0,示意生产者在胜利写入音讯之前不会期待任何来自服务器的响应. 换句话说,一旦呈现了问题导致服务器没有收到音讯,那么生产者就无从得悉,音讯也就失落了. 改配置因为不须要等到服务器的响应,所以能够以网络反对的最大速度发送音讯,从而达到很高的吞吐量。
acks=1,示意只有集群的 leader 分区正本接管到了音讯,就会向生产者发送一个胜利响应的 ack,此时生产者接管到 ack 之后就能够认为该音讯是写入胜利的. 一旦音讯无奈写入 leader 分区正本(比方网络起因、leader 节点解体), 生产者会收到一个谬误响应,当生产者接管到该谬误响应之后,为了防止数据失落,会从新发送数据. 这种形式的吞吐量取决于应用的是异步发送还是同步发送.
尖叫提醒:如果生产者收到了谬误响应,即使是从新发消息,还是会有可能呈现丢数据的景象. 比方,如果一个没有收到音讯的节点成为了新的 Leader,音讯就会失落.
- acks =all, 示意只有所有参加复制的节点 (ISR 列表的正本) 全副收到音讯时,生产者才会接管到来自服务器的响应. 这种模式是最高级别的,也是最平安的,能够确保不止一个 Broker 接管到了音讯. 该模式的提早会很高.
最小同步正本
下面提到,当 acks=all 时,须要所有的正本都同步了才会发送胜利响应到生产者. 其实这外面存在一个问题:如果 Leader 正本是惟一的同步正本时会产生什么呢?此时相当于 acks=1. 所以是不平安的.
Kafka 的 Broker 端提供了一个参数min.insync.replicas
, 该参数管制的是音讯至多被写入到多少个正本才算是 ” 真正写入 ”, 该值默认值为 1,生产环境设定为一个大于 1 的值能够晋升音讯的持久性. 因为如果同步正本的数量低于该配置值,则生产者会收到谬误响应,从而确保音讯不失落.
Case 1
如下图,当 min.insync.replicas= 2 且 acks=all 时,如果此时 ISR 列表只有[1,2],3 被踢出 ISR 列表,只须要保障两个正本同步了,生产者就会收到胜利响应.
Case 2
如下图,当 min.insync.replicas=2,如果此时 ISR 列表只有[1],2 和 3 被踢出 ISR 列表,那么当 acks=all 时,则不能胜利写入数;当 acks= 0 或者 acks= 1 能够胜利写入数据.
Case 3
这种状况是很容易引起误会的,如果 acks=all 且 min.insync.replicas=2,此时 ISR 列表为[1,2,3], 那么还是会等到所有的同步正本都同步了音讯,才会向生产者发送胜利响应的 ack. 因为 min.insync.replicas= 2 只是一个最低限度,即同步正本少于该配置值,则会抛异样,而 acks=all,是须要保障所有的 ISR 列表的正本都同步了才能够发送胜利响应. 如下图所示:
总结
acks=0,生产者在胜利写入音讯之前不会期待任何来自服务器的响应.
acks=1, 只有集群的 leader 分区正本接管到了音讯,就会向生产者发送一个胜利响应的 ack.
acks=all, 示意只有所有参加复制的节点 (ISR 列表的正本) 全副收到音讯时,生产者才会接管到来自服务器的响应,此时如果 ISR 同步正本的个数小于 min.insync.replicas
的值,音讯不会被写入.
公众号『大数据技术与数仓』,回复『材料』支付大数据资料包