1. Kafka数据存储流程和log日志
- Kafka 采取了分片和索引机制,将每个partition分为多个segment,每个segment对应2个文件 log 和 index
- 新增备注
例子
#分段一 00000000000000000000.index 00000000000000000000.log #分段二 数字 1234指的是当前文件的最小偏移量offset,即上个文件的最后一个消息的offset+1 00000000000000001234.index 00000000000000001234.log #分段三 00000000000000088888.index 00000000000000088888.log
2.分布式应用核心CAP知识
- CAP定理: 指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得
- 一致性(C):所有节点都可以访问到最新的数据;锁定其他节点,不一致之前不可读
- 可用性(A):每个请求都是可以得到响应的,不管请求是成功还是失败;被节点锁定后 无法响应
- 分区容错性(P):除了全部整体网络故障,其他故障都不能导致整个系统不可用,;节点间通信可能失败,无法避免
- CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡
结论
- 分布式系统中P,肯定要满足,所以只能在CA中二选一
- 没有最好的选择,最好的选择是根据业务场景来进行架构设计
- CP : 适合支付、交易类,要求数据强一致性,宁可业务不可用,也不能出现脏数据
- AP: 互联网业务,比如信息流架构,不要求数据强一致,更想要服务可用
3.Kafka数据可靠性保证原理之副本Replica+ACK介绍
- 背景
- Kafka之间副本数据同步是怎样的?一致性怎么保证,数据怎样保证不丢失呢
- kafka的副本(replica)
- topic可以设置有N个副本, 副本数最好要小于broker的数量
- 每个分区有1个leader和0到多个follower,我们把多个replica分为Learder replica和follower replica
- 生产者发送数据流程
- 保证producer 发送到指定的 topic, topic 的每个 partition 收到producer 发送的数据后
- 需要向 producer 发送 ack 确认收到,如果producer 收到 ack, 就会进行下一轮的发送否则重新发送数据
- 副本数据同步机制
- 当producer在向partition中写数据时,根据ack机制,默认ack=1,只会向leader中写入数据
- 然后leader中的数据会复制到其他的replica中,follower会周期性的从leader中pull数据,
- 对于数据的读写操作都在leader replica中,follower副本只是当leader副本挂了后才重新选取leader,follower并不向外提供服务,假如还没同步完成,leader副本就宕机了,怎么办?
问题点:Partition什么时间发送ack确认机制(要追求高吞吐量,那么就要放弃可靠性)
- 当producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别
- 副本数据同步策略 , ack有3个可选值,分别是0, 1,all。
- ack=0
- producer发送一次就不再发送了,不管是否发送成功
- 发送出去的消息还在半路,或者还没写入磁盘, Partition Leader所在Broker就直接挂了,客户端认为消息发送成功了,此时就会导致这条消息就丢失
- ack=1(默认)
- 只要Partition Leader接收到消息而且写入【本地磁盘】,就认为成功了,不管他其他的Follower有没有同步过去这条消息了
- 问题:万一Partition Leader刚刚接收到消息,Follower还没来得及同步过去,结果Leader所在的broker宕机了
- ack= all(即-1)
- producer只有收到分区内所有副本的成功写入全部落盘的通知才认为推送消息成功
- 备注:leader会维持一个与其保持同步的replica集合,该集合就是ISR,leader副本也在isr里面
- 问题一:如果在follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复
- 数据发送到leader后 ,部分ISR的副本同步,leader此时挂掉。比如follower1和follower2都有可能变成新的leader, producer端会得到返回异常,producer端会重新发送数据,数据可能会重复
- 问题二:acks=all 就可以代表数据一定不会丢失了吗
- Partition只有一个副本,也就是一个Leader,任何Follower都没有
- 接收完消息后宕机,也会导致数据丢失,acks=all,必须跟ISR列表里至少有2个以上的副本配合使用
- 在设置request.required.acks=-1的同时,也要min.insync.replicas这个参数设定 ISR中的最小副本数是多少,默认值为1,改为 >=2,如果ISR中的副本数少于min.insync.replicas配置的数量时,客户端会返回异常
- ack=0
4.Kafka的in-sync replica set机制讲解
- 什么是ISR (in-sync replica set )
- leader会维持一个与其保持同步的replica集合,该集合就是ISR,每一个leader partition都有一个ISR,leader动态维护, 要保证kafka不丢失message,就要保证ISR这组集合存活(至少有一个存活),并且消息commit成功
- Partition leader 保持同步的 Partition Follower 集合, 当 ISR 中的Partition Follower 完成数据的同步之后,就会给 leader 发送 ack
- 如果Partition follower长时间(replica.lag.time.max.ms) 未向leader同步数据,则该Partition Follower将被踢出ISR
- Partition Leader 发生故障之后,就会从 ISR 中选举新的 Partition Leader。
- OSR (out-of-sync-replica set)
- 与leader副本分区 同步滞后过多的副本集合
- AR(Assign Replicas)
- 分区中所有副本统称为AR
5.Kafka的HighWatermark的作用
- 背景 broker故障后
- ACK保障了【生产者】的投递可靠性
- partition的多副本保障了【消息存储】的可靠性
- hw的作用是啥?
- 备注:重复消费问题需要消费者自己处理
- HW作用:保证消费数据的一致性和副本数据的一致性
- Follower故障
- Follower发生故障后会被临时踢出ISR(动态变化),待该follower恢复后,follower会读取本地的磁盘记录的上次的HW,并将该log文件高于HW的部分截取掉,从HW开始向leader进行同步,等该follower的LEO大于等于该Partition的hw,即follower追上leader后,就可以重新加入ISR
- Leader故障
- Leader发生故障后,会从ISR中选出一个新的leader,为了保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于hw的部分截掉(新leader自己不会截掉),然后从新的leader同步数据
本文作者为DBC,转载请注明。