Kafka 数据文件存储-可靠性保证-ISR核心知识
一、Kafka 数据存储流程和 log 日志讲解
Kafka 采取了分片和索引机制,将每个 Partition 分为多个segment,每个 segment 对应2个文件 log 和 index
index文件中并没有为每一条message建立索引,采用了稀疏存储的方式
每隔一定字节的数据建立一条索引,避免了索引文件占用过多的空间和资源,从而可以将索引文件保留到内存中
缺点是没有建立索引的数据在查询的过程中需要小范围内的顺序扫描操作。
配置文件 server.properties
# The maximum size of a log segment file. When this size is reached a new log segment will be created. 默认是1G,当log数据文件大于1g后,会创建一个新的log文件(即segment,包括index和log) log.segment.bytes=1073741824
例子
#分段一 00000000000000000000.index 00000000000000000000.log #分段二 数字 1234指的是当前文件的最小偏移量offset,即上个文件的最后一个消息的offset+1 00000000000000001234.index 00000000000000001234.log #分段三 00000000000000088888.index 00000000000000088888.log
二、CAP理论
CAP定理: 指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得
- 一致性(C):所有节点都可以访问到最新的数据;锁定其他节点,不一致之前不可读
- 可用性(A):每个请求都是可以得到响应的,不管请求是成功还是失败;被节点锁定后 无法响应
- 分区容错性(P):除了全部整体网络故障,其他故障都不能导致整个系统不可用,;节点间通信可能失败,无法避免
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡
CA: 如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但放弃P的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,这是违背分布式系统设计的初衷的
CP: 如果不要求A(可用),每个请求都需要在服务器之间保持强一致,而P(分区)会导致同步时间无限延长(也就是等待数据同步完才能正常访问服务),一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统
AP:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。
结论:
- 分布式系统中P肯定要满足,所以只能在CA中二选一
- 没有最好的选择,最好的选择是根据业务场景来进行架构设计
- CP:适合支付、交易类,要求数据强一致性,宁可业务不可用,也不能出现脏数据
- AP:互联网业务,比如信息流架构,不要求数据强一致,更想要服务可用
三、Kafka 数据可靠性保证原理之副本机制 Replica 介绍
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 配置的数量时,客户端会返回异常
四、Kafka数据可靠性保证原理之ISR机制
什么是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
五、 Kafka的HighWatermark的作用
背景 Broker 故障后
- ACK 保障了【生产者】的投递可靠性
- Partition 的多副本保障了【消息存储】的可靠性
- HW 的作用是啥?
- 备注:重复消费问题需要消费者自己处理
HW 作用:保证消费数据的一致性和副本数据的一致性
假设没有HW,消费者消费leader到15,下面消费者应该消费16。
此时leader挂掉,选下面某个follower为leader,此时消费者找新leader消费数据,发现新Leader没有16数据,报错。
HW(High Watermark)是所有副本中最小的LEO。
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 同步数据