《Kafka容错及高可用原理分析.docx》由会员分享,可在线阅读,更多相关《Kafka容错及高可用原理分析.docx(36页珍藏版)》请在第一文库网上搜索。
1、Kafka容错及高可用原理解读Kakfa中topic的基本组成在kafka中以分区作为复制单元。每个topic由一个或多个分区组成,每个分区都包含一个1eader副本及0个或多个fo11ower副本。当你在创建topic时,需要指定分区数及复制因子。通常情况下一个复制因子是3的topic表明它有一个1eader副本及两个fo11ower副本。不论是一个1eader副本还是一个fo11ower副本都会被算作一个数据副本。1个topic的4个分区分布在3个broker上一个独立的Kafka服务器就被称为broker,broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。一个br
2、oker可以包含一个topic的部分或者全部分区数据。所有的读写操作都发生在1eader副本所存在的broker上。Fo11ower会周期性地向1eader发出fetch请求以获取最新的信息。消费者不会从fo11ower上消费数据,fo11ower只为数据冗余及故障切换而存在。1earder与fo11ower分区的故障切换当一个broker失效时,它上面很有可能包含了很多分区的IeacIer副本。如果丢失了Ieader副本,将导致剩余节点上的fo11ower副本被升级为Ieader副本。但事实上这种情况取决于fo11ower是否与IeaeIer保持同步状态,如果不同步,就要看是否允许切换到不同
3、步的分区上,这是一种UnCIean的切换。我们先来看一个简单的情况。当broker3失效时,对于当前topic的2号分区原Ieader也随之失效,同时将在broker2上提升原fo11ower副本而成为新的1eader副本Broker3失效,broker2上原分区2的fo11ower被升级为Ieader之后broker1也失效,1号分区也将丧失其Ieader副本,转而将Ieader切换到broker2Broker1也失效,所有Ieader副本都切换到broker2_t,topic将不再有冗余数据副本然后broker1恢复,重新上线,对于每个数据分区它会生成一个fo11ower副本以增强其数据冗
4、余。但是所有数据分区的Ieader副本仍然集中在broker2上紧接着broker3也恢复,重新上线,但是所有的Ieader副本都仍然集中在broker2上在broker1、3恢复后,Ieader副本出现了不均衡的情况对于这种情况kafka提供了一个比较好的功能来解决这种问题。kafka有个首选复制Ieader的概念。当kafka创建topic的分区时,它会尽量将每个分区的第一个1eader副本均匀地分布在每个broker节点上,同时记录这些1eader副本为首选复制Ieade八随着时间的推移,当发生服务器重启、服务器失效、网络分区等情况时,Ieader可能会在不同于首选复制Ieader的节点
5、上启停,就像我们前面所举的例子一样。为了解决这个问题,kafka提供了两个选项:在broker的配置中设置auto.1eader,reba1ance,enab1e=trueo这样一个后台进程就会在1eader,imba1ance.check,interva1,seconds所指定的时间间隔进行检查,如果Ieae1er的分布数量超过1eader,imba1ance.per.broker,percentage的值就会触发重新分布1eader,控制节点会根据首选复制Ieader来重新分布1eader,最终形成均匀地分布状态管理员也可以通过执行kafka-Preferred-rep1ica-e1ect
6、ion,sh脚本来手工执行,以达到我们期望的理想状态1eader副本再均衡这是简单情况下的Ieader副本故障切换。以此为开端,我们即将面临更复杂的场景,通过这种方式我们逐步引入更多的概念。接下来我们讲讲ISR(In-SyncRep1icas)。In-SyncRep1icas(ISR)ISR是一组保持在同步状态下的分区副本的集合。在ISR里面始终会有一个Ieader副本(在有可用数据副本的情况下)以及0个或多个fo11ower副本。如果一个fo11ower在设定的rep1ica.1ag.time.max.ms时间周期内时刻保持与1eader的数据更新,则认为该fo11ower是同步的,它将被1
7、eader保留在ISR列表中,反之将被从ISR中剔除。在acks=a11写入数据时,只有ISR中所有的副本都返回ACK,这时1eader才能commit该数据并认为该数据写入成功,然后返回生产者写入成功标记。处于同步状态时的fo11ower副本意味着是1eader的一个准确数据副本。在下列场景中fo11ower将会被移除ISR列表: fo11ower在rep1ica,fetch,wait.max.ms指定的时间范围内不能向1eader发出fetch操作请求(假定fo11ower已死) 最新数据的更新时间已经比rep1ica.1ag.time.max.ms指定的时间还要落后(被认为是一个慢fo1
8、1ower)fo11ower应该在rep1ica,fetch,wait.max.ms指定的时间周期内定时向1eader发出fetch操作请求,其缺省值为500ms。如果fo11ower没有发出任何fetch操作请求或者与1eader的最新数据已经落后rep1ica,1ag.time.max.ms所指定的时间,那么fo11ower会被Ieader移除ISRorep1ica.fetch,wait.max.ms设置需要小于rep1ica.1ag.time.max.msorep1ica.1ag.time.max.ms在最新版本的缺省值为3000OmS(30seconds)o为了更好地说明ISR的作用,
9、我们从生产者的确认信息来看一些故障切换场景。在broker发出写入成功确认信息前,生产者端可以进行如下的设置: acks=0,broker不需要返回任何确认信息(生产者只要发送完数据即认为已经写入成功) acks=1,当Ieader副本在本地日志中已经写入数据,broker即可向生产者返回写入成功的确认信息(早期版本的缺省值) acks=a11,当所有在ISR列表中的副本都在本地日志中完成数据写入,broker才向生产者返回写入成功的信息确认(最新版本的缺省值)在kafka的术语中,一旦ISR持久化消息,消息就会被提交。虽然Acks=a11会导致数据处理延迟,但对于生产者来说却是最安全的一个选
10、项。我们将通过两个故障切换的案例来举例说明在生产端对acks的设置是如何与ISR相互影响的。Acks=I与ISR在本案例中,我们可以看到在持久化数据的时候当Ieader不再等待fo11ower的情况下,1eader发生故障切换极有可能导致数据丢失。是否允许在故障切换中将新1eader切换到数据不同步的fo11ower可以通过配置参数UnCIean.1eader,e1ection,enab1e来控制,其缺省值是fa1se,缺省不允许将1eader切换到不同步的fo1Iowero在本次测试中我们在生产端设置acks=1,这也是大多数生产端的缺省设置。我们的数据分区分布在所有的3个broker上。B
11、roker3已经出现数据延迟,它最新的数据是Ieader8秒以前的,具体落后7456条数据。Borker1相对来说要快的多,最新数据与Ieader只相差1秒,数据落后123条。由于我们设置acks=1,因此生产端在发送数据后,数据在Ieader副本所在的broker2上写入成功生产端即可接收到ack,完全无需等待任何fo11ower的操作结果,这是非常迅速的。ISR中有三个数据副本这个时候broker2失效,生产端将出现连接错误。与此同时在丢失123条数据的情况下新的Ieader切换到brokerIo在发生故障切换时,虽然broker1在ISR列表中,但由于数据不是完全同步,仍然会出现数据丢失
12、。故障切换中发生数据丢失由于在生产端的bootstrap,servers中配置了多个broker地址信息,因此生产端能够很容易地知道新的IeaC1er在哪个broker上。它将创建新的连接,并继续向新的1eader发送数据。短暂的中断后数据得以继续发送BrOker3的延迟进一步加大。时间延迟达到14秒,数据延迟达到15286。它虽然仍在向Ieader发出fetch操作的请求,却始终不能跟上Ieader的脚步。这可能是由于两个broker之间的网络或者存储出现故障所导致。最终broker3从ISR列表中被Ieader移除。现在在ISR中就只有一个数据副本存在,就是Ieader本身!生产端仍然继续
13、发送数据同时接收确认。Broker3从ISR中被移除这时Broker1出现故障,在丢失15286条数据后新的Ieader被切换到broker3!产生这样的结果是因为我们设置了unc1ean,1eader,e1ection,enab1e=true,会导致新1eader被允许切换到并不在ISR列表中的broker节点,这意味着数据严重不同步的broker节点有可能成为新的Ieader,导致大量的数据丢失。如果unc1ean,1eader,e1ection,enab1e=fa1se,那么这样的故障切换就不会发生,同时客户端所发出的所有读写请求都会被拒绝。在这种情况下我们只能把broker1恢复起来才
14、能继续工作。Broker1失效,发生故障切换将导致大量数据丢失生产端与最后一个broker建立连接,同时这个broker成为分区0当前的Ieadero生产端将数据发送到broker3.短暂的中断后数据可以继续发送到分区O通过这个案例,我们可以看到,除了短暂的切换外,生产端可以发现新的Ieader并建立新的连接,数据仍然可以被正常发送。这样配置在获得数据可用性的同时,付出的代价是数据的一致性,数据的安全。kafka能够继续执行写入操作,但是丢失了大量已经确认过的数据。Acks=a11与ISR让我们再重演一遍前面的场景,这一次我们将设置acks=a11Broker3将保持与Ieader平均4秒的滞
15、后。生产者在设置acks=a11后向kafka发送数据,但这次收到确认信息将会慢很多。Ieader为了要持久化数据必须等待ISR中所有的数据副本都返回确认信息。由于broker3平均滞后4秒,因此也导致1eader向生产端返回ack比无需等待fo11ower返回多滞后4秒。ISR中有三个数据副本,其中一个数据副本是慢节点,这将对每次写入操作都产生处理延迟经过4秒的延迟以后,broker2将确认信息返回给了生产者。所有的数据副本在这一时刻是一致的。所有的数据都已经持久化,同时确认信息已返回Broker3的持续落后将最终导致其从ISR中被移除。由于慢节点的消失使处理延迟也得到缩短。Broker2现在处理数据只需要等待broker1的响应即可,而broker1平均只滞后250mso因此也导致1eader向生产端返回ack比无需等待fo11ower返回多滞后250msoBroker3从ISR中被移除这时broker2出现故障,导致Ieader切换到broker1,这一过程没有出现数据丢失Broker2出现故障生产端发现新的Ieader,同时将数据发送给它。数据操作延迟仍然较低,因为这时ISR中只有一个数据副本,即Ieader本身。因此即使我们设置acks=a11,但当ISR中只有一个数据副本的时候我们仍然不能保证数据的冗余O切换到broker1,没有发生数据