简介:
Kakfa 是一个分布式的基于发布/订阅模式的消息队列(message queue),主要应用于大数据的实时处理领域。
其具有高吞吐低延迟的消息出来,支持客户端高并发,集群可扩展,消息的持久性可靠性及节点失败的容错性等特性。
可以在需要模块间解耦,数据可恢复性,消息队列缓冲及削峰填谷应对突发流量,模块间异步通信等场景进行应用。

kafka的可靠性
kafka的可靠性主要通过副本技术来实现,在kafka 0.8.0之前kafka没有副本的概念,只用于存储些不重要的消息,kafka存储的消息经常因为没有副本而丢失。0.8.0版本增加了对分区副本的支持,每个分区可以配置为几个副本,可以创建topic时指定,也可以通过default.replication.factor指定默认值。
在分区的副本中有一个是Leader,其余是follower,数据的读写操作都经过Leader进行,同时follwer会定期地去Leader同步数据。当Leader挂了之后,其中一个follwer会选举成为新的Leader。kafka通过分区副本引入数据冗余提供了数据可靠性, 支持副本数n-1的分区机器崩溃而不丢数据。
producer在向kafka的broker发送消息时提供了消息确认机制,即可以通过配置producer的acks参数来决定消息发送到对应分区的几个副本才认为是成功。

  • acks=0:这种情况如果producer把数据通过网络把消息发送出去就认为成功,这种情况非常容易发生错误,且不会收到提示。此时吞吐量和带宽利用率很高。
  • acks=1:这种情况下若Leader收到了消息并写入了分区中就返回确认响应,不一定同步磁盘。这是若发生Leader崩溃,而follower尚未同步就容易丢消息。
  • acks=all:这种配置下只有Leader收到了所有副本的响应消息才会向producer返回确认或错误的响应。生产者在继续发送其他消息之前需要等待所有副本都收到了,因而这种最可靠,但也是最慢的。取值all也可以为-1。这里也只是保证后面说的ISR中的所有副本都收到了消息,kafka不丢消息的保证可以理解为:对没有提交成功的消息不做任何保证,而对于ISR中至少有一个存活的完全同步的副本的情况下成功提交的消息保证不会丢失。

我们根据应用场景对可靠性的要求设置不同的acks值。

前面讲了分区的副本有Leader与Follower的区分,在Leader挂了时就需要进行选举。每个分区的leader会维护一个ISR(in-sync replicas)的列表,只有能及时与leader消息同步的follower才在ISR列表里,跟不上的就会被移到OSR(Out-of-Sync Replicas)中,这个延时允许的间隔通过replica.lag.time.max.ms配置。不用等待OSR中的副本都保存完成才进行确认,OSR中的副本会尽力追赶进度。注:replica.lag.max.messages在0.9.0中已经被移除。

unclean.leader.election.enable:这个参数在0.11.0之前其默认值为true,而之后的版本其默认值为false。这个选项的意思是,在leader选举时是否在没有活着的ISR副本时从OSR中的最早follower选举。如果为true会造成可靠性的下降,因为会将有很多消息尚未同步的follower在ISR全挂了时选举为Leader而造成消息的丢失,尽管如此但其提升了可用性。



Notable changes in 0.11.0.0 Unclean leader election is now disabled by default.  
The new default favors durability over availability.  
Users who wish to to retain the previous behavior should set  the broker config 
unclean.leader.election.enable to true.



总结下要保证数据的可靠性,我们最少需要配置一下几个参数:

  • producer 级别:acks=all(或者 request.required.acks=-1),同时producer类型配置为同步 producer.type=sync
  • topic 级别:设置 replication.factor>=3,并且 min.insync.replicas>=2;
  • broker 级别:关闭不完全的 Leader 选举,即 unclean.leader.election.enable=false

kafka的一致性
kafka的副本采用的是异步拉取机制,也没有开放follower的读能力,其读操作仍然由该分区的Leader提供,因而一致性保证机制相对算简单。
kafka的一致性指分区的leader发生切换前后,读取的消息是一致的。这个通过HighWatermark实现,高水位取分区的ISR副本中最小的LEO,消费者只能读取到HW的上一条记录,这里LEO表示LogEndOffset,指该副本中当前日志的下一条。如图所示,只能读到消息Message2。




kafka支持同步刷盘吗 kafka 同步 异步_数据