次要从三方面来介绍,音讯发送端保证数据不失落,kafka 服务保障音讯不失落,消费者保障音讯不失落。
基础知识
- kafka 能够保障分区音讯的程序,同一个分区,先发送到 kafka 分区的音讯,会被先生产掉。
- kafka 是通过一个集群对外提供服务,只有是集群中多个正本中有一个正本是沉闷的,那么收到的音讯就不会失落。
kafka 集群保证数据不失落
先思考一个问题:
kafka 集群什么时候会失落音讯?
这就要从 kafka 的复制机制开始讲了。
kafka 每个 topic 有多个分区,分区存储在磁盘上,kafka 能够保障分区的数据是有序的,每个分区能够有多个正本。
正本依照是否是领袖,能够分为领袖正本和跟随者正本(这里对应的就是 kafka 集群中的 leader 和 follower)。
所有的音讯都是发送给 leader 的,音讯生产也是从 leader 获取的。领袖正本第一工夫收到音讯,或者生产音讯,他肯定是同步正本。
其余 follower 都是和 leader 放弃通信,同步 leader 的音讯。当 leader 不可用时,会选举一个 follower 会变成 leader。
对于一个主一个从的两个 kafka,做的集群来说。
(此时的 kafka 复制系数是 2. 对应的配置参数是replication,factor)
一个是 leader 正本,一个是 follower 正本。当 follower 正本始终能与 leader 正本放弃同步的时候 follower 正本是 同步正本,当 follower 与 leader 无奈放弃同步的时候 follower 正本则变成非同步正本。
如果 leader 宕机,这时候零碎须要选举一个 follower 来作为领袖,kafka 优先选择同步正本作为领袖,当零碎没有同步正本的时候。kafka 如果抉择非同步正本作为领袖,则会失落一部分数据,(这一部分数据就是非同步正本无奈及时从领袖正本更新的音讯)。kafka 如果不抉择非同步正本作为领袖,则此时 kafka 集群不可用。
kafka 抉择非同步正本作为领袖正本的行为叫做,不齐全领袖选举。如何管制 kafka 在 leader 宕机时,同步正本不可用时,是否抉择非同步 作为领袖?通过 kafka 的另外一个参数来管制的:unclean.leader.election. 如果是 true 则会产生不齐全领袖选举。
正本数倡议 3 个就能够,多的话须要更多的磁盘,unclean.leader.election
倡议 false.
对于两个 kafka 做的集群来说,必定是不平安的。那么三个节点的 kafka 平安吗?
答案是 也不肯定平安
因为即便三个正本,也有可能是两个从都是非同步正本,此时主宕机,从要么不可用(影响高可用),要么成为主(数据失落)。
这里就须要保障 kafka 零碎中至多有两个同步正本。一个必定是领袖正本,另外一个是从的正本。
此时须要 kafka 的另外一个参数 最小同步正本数 min,insync.replicas
只有保障 kafka 收到生产者的音讯之后,至多有“最小同步正本数“的正本收到音讯,能力保障在主宕机时音讯不失落。
这个参数的意思是 kafka 收到生产者音讯之后,至多几个同步正本,同步之后,才给客户端音讯确认。数量多能保障高可用,然而就义效率。
kafka 如何判断一个 follower 正本是不是同步正本?
满足两个条件
- 在过来 10 秒内从领袖获取过音讯,并且是最新消息。
- 过来 6 秒内 和 zk 间接发送过心跳。
疑难:如果 kafka 长时间未收到音讯,第一条如何满足?
音讯发送者正确的发送姿态
音讯怎么才算是产生胜利?
音讯的生产者向 kafka 集群发送音讯,须要期待 kafka 集群确认,这里波及到一个参数 acks
他的值有三个 0, 1, all
如果是 0,那么代表发送过来,不期待 kafka 音讯确认,认为胜利
肯定会失落音讯,可能 kafka 集群正在选举,此时就无奈收到任何异样。
如果是 1,那么代表发送过来,期待领袖正本确认音讯,认为胜利
领袖必定收到了音讯,写入了分区文件(不肯定落盘)。
如果是 all, 那么代表发送过来之后,音讯被写入所有同步正本之后,认为胜利。
留神这里是 所有同步正本,不是所有正本。具体是多少同步正本,还要取决于 kafka 集群设置的最小同步正本数,和集群以后的同步正本数。抉择这种配置,会牢靠,然而就义效率,能够通过,增大批和应用异步模式,提高效率。
如果音讯产生异样怎么办?重试吗?
哪些异样须要重试?
网络异样和集群无主,或者正在选举的异样是能够重试的。
哪些不须要重试?
配置异样。
其余异样怎么办?
序列化异样,内存溢出,栈溢出等。
重要的配置参数
如果网络异样收不到响应,则期待,这里有个配置等待时间 request.timeout.ms
发送音讯等待时间。
metadata.fetch.time.out 从 kafka 获取元数据的等待时间。
max.block.ms : 配置管制了 KafkaProducer.send()并将 KafkaProducer.partitionsFor()被阻塞多长时间。
因为缓冲区已满或元数据不可用,这些办法可能会被阻塞止。用户提供的序列化程序或分区程序中的阻塞将不计入此超时 重试次数 retries
重试间接的等待时间,默认是 100 ms , 能够通过 retry.backoff.ms 配置 多个音讯发送给同一个分区的时候,生产者会把音讯打成一个批,批大小设置 batch.size 过大占内存,过小发送频繁,并且生产者不是 必须满零售送,有个等待时间,linger.ms 设置 期待多久批不满则发送。
音讯消费者正确的生产姿态
消费者须要向 kafka 集群提交 曾经生产的音讯的 offset 来确定音讯生产到了那里。
音讯队列的生产形式有两种,一种是公布订阅模式,一种是队列模式。
- 公布订阅模式 一个音讯能够被多个消费者生产。
- 队列模式多个消费者只能生产到一部分音讯。
kafka 是通过 group-id 来辨别生产组的。一个 topic 被 同一个生产组的不同消费者生产,相当于是队列模式。被不同生产组生产相当于是 订阅模式。一个 partition 在同一个时刻只有一个 consumer instance 在生产。对于正确的模式,咱们须要配置正确的 group-id
auto.offset.reset
没有偏移量能够提交的时候,零碎从哪里开始生产。有两种设置:earliest
和latest
。
enable.auto.commit
主动提交,如果开启了主动提交,那么零碎会主动进行提交 offset。可能会引起,并未生产掉,就提交了 offset. 引起数据的失落。
与主动提交相干的是主动提交的间隔时间 auto.commit.interval.ms
默认是 5 秒钟提交一次,能够通过查看 kafka config 目录下的 配置文件,查问配置的默认值。
主动提交 还可能引起音讯的反复生产,特地是 多个客户端间接呈现重均衡时。
只有三方面都保障了。才能够保证数据不失落。