Kafka如何配置高可用
前言
电话面试的时候,发现去总结Kafka
如何保证高可用时,整个脑袋是懵的,其实Kafka
的原理我是懂的,可就是说不出来,这篇文章用来描述下Kafka
在不同的情况下,如何保证高可用。
具体Kafka
原理解析,请移步Kafka数据可靠性深度解读
消息中间件出问题的可能性
Producer
发送到消息中间件时出问题(从Producer
发送消息开发,到中间件返回成功为止)- 消息中间件收到消息,处理时出问题(即中间件向
Producer
返回成功开始算起,到消息存储到硬盘设备为止) Consumer
消费消息时出问题(从消息中间件拿到消息开始,到向中间件返回消费完成为止)
Producer
发送到消息中间件时出问题
- 发送消息到中间件遇到网络问题
此时,Producer
会收到异常,尝试重新发送即可。此时中间件还是仅收到一条消息 - 中间件返回
Producer
成功遇到网络问题
此时,Producer
会受到异常,尝试重新发送即可。此时中间件就可能重复收到多条消息,这个就无法避免了。
消息中间件收到消息,处理时出问题
该内容后续着重介绍,消息中间件出问题,也主要是这部分出的问题
Consumer
消费消息时出问题
- 中间件发送到
Consumer
时遇到网络问题
此时,由于中间件未收到消费成功的返回,且超过timeout
时间,该消息可以被重新消费。即保证至少被成功消费一次。 Consumer
返回消费成功时遇到网络问题Consumer
不管是遇到网络问题,还是消费时抛出异常,都无法给中间件消费成功的返回,那在timeout
之后,该消息可以被重新消费。即保证至少被成功消费一次。跟上面的处理方式类似,为了保证消息不会被重复消息,需要业务侧提供消息去重的逻辑。
Kafka
可靠性级别(request.required.acks
)
1
(默认):这意味着Producer
在ISR
中的Leader
已成功收到的数据并得到确认后发送下一条message
。如果Leader
宕机了,则会丢失数据。0
:这意味着Producer
无需等待来自Broker
的确认而继续发送下一批消息。这种情况下数据传输效率最高,但是数据可靠性确是最低的。-1
:Producer
需要等待ISR
中的所有Follower
都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失。
Kafka
可靠性级别为1
,即仅Leader
收到消息即算成功
如果Leader
收到消息返回成功,可还未同步Follower
时,Leader
就宕机了。此时消息永远回不来的了。概率性问题,如果对消息发送成功的要求较高,不建议使用这个配置。
Kafka
可靠性级别为0
,即Producer
无需确认Kafka
是否成功存储消息
该可靠性最低,但是数据传输效率最高,如果对消息发送成功的要求较低,可使用该配置。
Kafka
可靠性级别为-1
,即Leader
必须等到所有ISR
中所有Follower
确认成功
该可靠性最高,可也并不是配置了这个可靠性之后就无忧了,同时还需要额外一些配置来保证消息确实存储成功。
- 配置
replication
的副本数(default.replication.refactor
) - 配置
ISR
中最小副本数(min.insync.replicas
)
ISR
最大的数量就是replication
的副本数,如果ISR
数量小于要求数量,write
功能是肯定不能提供了。根据是否还有存活的ISR
来判断是否还能有read
功能。
假设所有Follower
都已同步Leader
的消息,此时Leader
宕机,可直接从ISR
中选举Leader
,消息不会丢失。
假设Leader
宕机时,各个Follower
同步Leader
消息的进度不同,此时会在ISR
中重新选举Leader
,并向Producer
抛异常,让Producer
重新发送消息。
这个时候,新的Leader
会让Follower
截取消息到上次的HW
,这样Leader
和Follower
的消息就同步,并且抛弃掉上个Leader
宕机时对应的未处理的消息。此时Producer
重新发送的消息,Leader
就不会有重复消息了。
在后续,如果之前Leader
恢复了,也要截取消息到上面所有的HW
的位置,然后再从新的Leader
中同步消息,自己成为了Follower
。