1.分区原因:
负载均衡+提高并发性
2.分区原则
封装为一个ProducerRecord对象
参数 : topic、partion(int)、时间戳、key、value、headers信息
如果没有指定分区,则根据你key的hash值进行%分区数去余数
如果没有指定key,第一次生成随机整数,与可用分区数,进行直接roundrobin-轮训算法发送
3.分区数据保证性
1.发送端发送到leader或者follower之后,进行确认ack消息确认机制(同zookeeper相同机制,进行控制,当与半数的follower同步数据结束且成功之后,则直接进行ack确认成功机制)。仍然还是半数以上存活才允许服务正常运行。
❤️(kafka选择方法) 2.如果全部进行确认后,延迟会很大,但是只有有一台符合ok,就没有问题。
❤️(kafka新版本选择)1.ISR机制,leader维护了一个保持同步到follower结合中,当ISR中的follower完成数据同步后,leader就会给follower发送ack。如果follower长时间未向leader同步数据,则该follower会被提出ISR,改时间阈值有replica.lag.time.max.ms参数设置。leader发生故障之后,会从ISR中选举此新leader(个人认为属于offset最大的那个当做新leader)。
2.还有一种情况是根据条数差值,在范围内会在ISR加进来,否则踢出去。
为什么选择第一条,会因为如果productor批次发送生成数据之后,就会频繁拉入kafka-ISR以及提出ISR,所以摒弃了第二条时间值。
4.ack应答机制(数据完整性)
因为在数据一致性或者允许丢失的情况下,leader可以不必要等所有ISR的follower都返回数据。因此分为三种级别:0,1,-1(all)
提供了三种级别:
❤️ 0:producer不等待broker的ack信号,最低延迟,broker在没有真正存入硬盘就返回,此时可能会因为broker故障导致数据丢失。
❤️ 1:producer等待broker的ack,partion的leader落盘存入成功后,直接返回ack,如果在follower同步成功之前leader故障了,会丢失数据。
❤️ -1(all):producer等待broker的ack,partion的leader落盘存入成功以及ISR所有的follower同步结束,直接返回ack,如果存在leader故障了可能会存在重复数据。(当然如果存在ISR中只有有一个leader没有follower的情况,也会退化到(ack=1)的情况)。
5.数据一致性(消费+log存储)
leader如果写了10
follower1写了9条
follower2写了8条
leader挂了,如果follower1被选成了新leader后(fallover),旧leader恢复了(fallback),这样子就会出现消费一致性的问题。会出现消费紊乱问题。
❤️ 解决办法:每一个partition分配HW(高水位线)【所有follower和leader中选出最小的offset值,你可以理解为木桶效应,去所有分区中LEO最小的值,作为所有分区的HW,当然最小的那个分区,LEO和HW是相同的】和每一个partition分配一个LEO(最大值offset值)。
❤️这个大家共同的HW高水位线,就是面向于所有consumer的可见值offset,保证大家同步一致。(数据无法保证丢失)。
1.follower故障
❤️ follower如果出现故障了则会被提出ISR,代回复之后,会自动读取本地磁盘上次记录的HW,并将log文件高于HW的部分截取掉,从HW开始想leader进行同步。等该follower的LEO大于等于该partition的HW,就说明追上了leader了,就可以重新加入ISR了。
2.leader发生故障之后
❤️选取一个新的leader之后,为保证多个副本之间的数据一致性,其余的follower会将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。
但是这些挽救措施,只能保证副本和leader之间的数据一致性,并不能保证数据的完整性。
Exactly Once语义
ack=-1 至少一次(数据重复)
幂等性机制:broker端进行处理重复数据操作。无需消费者自己处理。
❤️开启幂等性机制配置:enable.idompotence为true,则自动直接进行开启 ack=-1状态。
(每一个生产者会被分配一个PID),发送到同一个partition的序列号,broker端只会对PID+partition+序列化好,会做缓存,如果重复只会存储一份。
❤️只会保持单分区单会话之内的幂等性。
ack=0 最多一次(数据丢失)
网友评论