次要从三方面来介绍,音讯发送端保证数据不失落,kafka服务保障音讯不失落,消费者保障音讯不失落。

基础知识

  1. kafka 能够保障分区音讯的程序,同一个分区,先发送到kafka分区的音讯,会被先生产掉。
  2. 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正本是不是同步正本?

满足两个条件

  1. 在过来10秒内从领袖获取过音讯,并且是最新消息。
  2. 过来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 没有偏移量能够提交的时候,零碎从哪里开始生产。 有两种设置 :earliestlatest


enable.auto.commit

主动提交 ,如果开启了主动提交,那么零碎会主动进行提交offset。可能会引起,并未生产掉,就提交了offset.引起数据的失落。

与主动提交相干的是主动提交的间隔时间 auto.commit.interval.ms 默认是5秒钟提交一次,能够通过查看 kafka config目录下的 配置文件,查问配置的默认值。

主动提交 还可能引起音讯的反复生产,特地是 多个客户端间接呈现重均衡时。

只有三方面都保障了。才能够保证数据不失落。