同步机制
Kafka中topic的每个partition有一个预写式日志文件,每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中,partition中的每个消息都有一个连续的序列号叫做offset,确定他在partition中的唯一位置。
kafka每个topic的partition有N个副本,其中N是topic的复制因子,Kafka通过多副本机制实现故障自动转移,当Kafka集群中一个Broker失效情况下,仍可保证服务可用。在Kafka中发生复制时确保partition的预写式日志有序地写到其他节点上。N个replicas中,其中一个replica为leader,其他都为follower,leader处理partition的所有读写请求,与此同时,follower会被动定期地区复制Leader上的数据。
ISR
Kafka提供了数据复制算法,如果leader发生故障或挂掉,一个新leader被选举并被接受客户端的消息成功写入。Kafka确保从同步副本列表中选举一个副本为leader,或者说follower追赶leader数据。leader负责维护和根据ISR(In-Sync Replicas的缩写,表示副本同步队列)中所有消息,follower之后的桩体。当producer发送一条消息到broker后,leader写入消息,并复制到所有follower。消息提交之后才被成功复制到所有的同步副本。消息复制延迟受最慢的follower限制,重要的是快速检测慢副本,如果follower“落后”太多或者失败,leader将会把他从ISR中删除。
默认情况下,Kafka topic的replica数量为1,即每个partition都有一个唯一的leader,为了确保消息的可靠性,通常应用中将其值(由broker的参数offsets.topic.replication.factor指定)大小设定为1。所有的副本(replicas)统称为AR (Assigned Replicas)。ISR是AR的一个子集,由leader维护ISR列表,follower从Leader同步数据有一些延迟,任意一个超过阈值都会把follower踢出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放到OSR中。AR = ISR + OSR
HW
HW(HighWatermark)俗称高水位,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置。另外每个replica都有HW,leader和follower各自负责更新自己的HW的状态。对于leader新写入的消息,consumer不能立即消费,leader会等待该消息被所有ISR中的replicas都同步后,才更新HW,此时消息才能被consumer消费,这样就保证了如果Leader所在的broker失效,该消息仍可从新选举的leader中获取。对于来自内部的broker的读取请求,没有HW的限制。
由此可见,Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。事实上,同步机制要求所有能工作的follower都复制完,这条消息才会被commit,这种复制方式极大的影响了吞吐率。而异步复制方式下,follower异步的从leader复制数据,数据只要被Leader写入log就被任务已经commit,这种情况下如果follower没有全复制完,落后与Leader,突然leader宕机,则会丢数据。而Kafka这种使用ISR的方式则很好的均衡了确保数据不丢失以及吞吐率。