提高并发,以分区 partition 为单位进行读写操作
这三种策略的前提都是明确知道具体的topic1. 明确知道partition index,则直接进入指定partition中2. 不知道partition index,给出了消息对应的key,则 hash(key)mod(num(partitions)) 获取对应的分区partition编号3. 不知道partition index, 但给出了消息的value,第一次调用时生成一个整数,并记录下来,后面每次调用在这个整数上自增,将这个值与topic 可用 的partition 总数取余 得到partition值,也是常说的 round-robin 算法
kafka 通过 leader partition发送ack
机制实现消息的可靠传输;
确保有follower与leader同步完成
,leader 再发送ack, 这样能保证leader挂掉之后,follower可以容灾,并从follower中选举出新的leader;与leader同步的follower个数也有两种不同的策略
:问题1
如果 follower 副本在同步leader 数据的过程中,有一个副本挂掉了,长时间不能跟leader同步,那么leader就要一直等下去,直到挂掉的follower也同步了 leader 的数据,才发送ack,这个问题该如何解决?
kafka 通过在leader partition 维护一个动态的ISR即 同步副本
(是个set),来保存与leader保持同步的follower集合。
follower如何被选定为ISR?older version: 同步时间快慢 + 与leader 差异的数据条数 (尽最大努力同步) 0.9 版本 new version 去掉了与leader 差异的数据条数因为会频繁操作zk(想象一下 batch_size > 差异数据num策略),保留了同步时间策略,用来作为选取follower作为ISR元素的依据;默认10s
为什么需要ack应答机制在某些场景下可以容忍数据丢失的情况,对数据的可靠性要求不高,能够容忍数据的少量丢失,所有没有必要等待ISR中的Follower全部接收成功 所以对于不同场景下的数据可靠性传输、与数据传输性能上的要求,kafka对应给出了如下三种ack应答机制配置策略。
0
:producer 不等待 leader partition所在的broker 回传的ack,这个操作提供了一个最低的延迟,broker接收到(还没有写入磁盘的时候就已经返回返回),当broker 故障时有可能丢失数据 1
:producer 等待 leader partition 所在的broker 回传的ack,leader partition 落盘成功后返回ack,如果follower同步之前leader故障, 那么将会丢失数据。-1
: producer 等待 leader partition 所在的broker 回传的ack,partition 的leader 和follower 全部落盘成功后才返回ack。
但是,注意在 acks = -1时,在极端情况下还是可能会出现数据丢失的情况(这种情况很少见,但不代表没有),而且最容易出现的情况是数据重复 下面简单清晰的描述下这两种场景:
acks = -1,数据丢失 ISR 中的follower副本数量恰好为0,即当前leader partition接收的数据,没有follower 需要同步,且leader partition 发完ack之后挂掉了,那数据就丢失了。acks = -1, 数据重复 如果ISR 中维护的 followers 同步完数据,leader 在发送ack给producer 之前挂掉了,那么producer就会重发数据给新晋升的leader。此时,数据就会重复发送。
场景描述: leader 接收了新一批数据,但是ISR 中follower还未同步完之前就挂掉了,如下图所示,假如consumer已经消费到了19,那么接下来将消费18,此时 leader挂掉,新的follower成为leader,那么去消费offset为18(当前最老的数据)就会报错。为应对以上问题,kafka通过 HW
& LEO
的机制解决消费一致性问题:
解决方案:HW - High water 高水位 即ISR 中所有 follower 中最小的LEO LEO - 每个副本的最后一个offset
注意: HW 来保证数据一致性,高水位之前的数据是消费者可见的。
可能出现脑裂问题 ,leader 挂掉,follower 被选举为新leader, 先前挂掉的leader又重新活了起来,产生脑裂,如果此时producer又新发一批次数据, 这两个leader都会接收到数据,那么数据就发生混乱且不一致了。将来消费的数据都不一样 。脑补一下场面就可以了,那么如何解决脑裂产生数据不一致问题呢? 新官上任三把火: 告诉所有在ISR中记录的follower,将数据截取到HW, 跟新leader的存储数据保持一致注意 HW只能保证副本数据的一致性,并不能保证数据丢不丢失,或者重不重复,即要少都少,要多都多
以上问题讨论的都是ISR 记录的Follower 范围。