要解决这个问题,就要从 Kafka 的高可用实现开始讲起。
Kafka 的多副本冗余设计
不管是传统的基于关系型数据库设计的系统,还是分布式的如 zookeeper 、 redis 、 Kafka 、 HDFS 等等,实现高可用的办法通常是采用冗余设计,通过冗余来解决节点宕机不可用问题。

逻辑模型

Broker (节点):Kafka 服务节点,简单来说一个 Broker 就是一台 Kafka 服务器,一个物理节点。
Topic (主题):在 Kafka 中消息以主题为单位进行归类,每个主题都有一个 Topic Name ,生产者根据 Topic Name 将消息发送到特定的 Topic,消费者则同样根据 Topic Name 从对应的 Topic 进行消费。
Partition (分区):Topic (主题)是消息归类的一个单位,但每一个主题还能再细分为一个或多个 Partition (分区),一个分区只能属于一个主题。主题和分区都是逻辑上的概念,举个例子,消息1和消息2都发送到主题1,它们可能进入同一个分区也可能进入不同的分区(所以同一个主题下的不同分区包含的消息是不同的),之后便会发送到分区对应的Broker节点上。
Offset (偏移量):分区可以看作是一个只进不出的队列(Kafka只保证一个分区内的消息是有序的),消息会往这个队列的尾部追加,每个消息进入分区后都会有一个偏移量,标识该消息在该分区中的位置,消费者要消费该消息就是通过偏移量来识别。

就这么简单?是的,基于上面这张多副本架构图就实现了 Kafka 的高可用。当某个 Broker 挂掉了,甭担心,这个 Broker 上的 Partition 在其他 Broker 节点上还有副本。你说如果挂掉的是 Leader 怎么办?那就在 Follower中在选举出一个 Leader 即可,生产者和消费者又可以和新的 Leader 愉快地玩耍了,这就是高可用。
你可能还有疑问,那要多少个副本才算够用?Follower 和 Leader 之间没有完全同步怎么办?一个节点宕机后 Leader 的选举规则是什么?
Follower 和 Leader 之间并不是完全同步,但也不是完全异步,而是采用一种 ISR机制( In-Sync Replica)。每个Leader会动态维护一个ISR列表,该列表里存储的是和Leader基本同步的Follower。如果有 Follower 由于网络、GC 等原因而没有向 Leader 发起拉取数据请求,此时 Follower 相对于 Leader 是不同步的,则会被踢出 ISR 列表。所以说,ISR 列表中的 Follower 都是跟得上 Leader 的副本。
Zab、
Raft、
Viewstamped Replication、微软的
PacificA等。而 Kafka 的 Leader 选举思路很简单,基于我们上述提到的
ISR列表,当宕机后会从所有副本中顺序查找,如果查找到的副本在ISR列表中,则当选为Leader。另外还要保证前任Leader已经是退位状态了,否则会出现脑裂情况(有两个Leader)。怎么保证?Kafka 通过设置了一个 controller 来保证只有一个 Leader。
Ack 参数决定了可靠程度
request.required.asks参数。
Asks=All就不会出现丢失消息的情况吗?答案是否。当ISR列表只剩Leader的情况下,
Asks=All相当于
Asks=1,这种情况下如果节点宕机了,还能保证数据不丢失吗?因此只有在
Asks=All并且有ISR中有两个副本的情况下才能保证数据不丢失。
解决问题
Broker节点数是3,
Topic是副本数为3,
Partition数为6,
Asks参数为1。
__consumer_offset上,
__consumer_offset是一个 Kafka 自动创建的
Topic,用来存储消费者消费的
offset(偏移量)信息,默认
Partition数为50。而就是这个Topic,它的默认副本数为1。如果所有的 Partition 都存在于同一台机器上,那就是很明显的单点故障了!当将存储
__consumer_offset的 Partition 的 Broker 给 Kill 后,会发现所有的消费者都停止消费了。
__consumer_offset删除,注意这个Topic是Kafka内置的Topic,无法用命令删除,我是通过将
logs删了来实现删除。
offsets.topic.replication.factor为3来将
__consumer_offset的副本数改为3。通过将
__consumer_offset也做副本冗余后来解决某个节点宕机后消费者的消费问题。
__consumer_offset的 Partition 会出现只存储在一个 Broker 上而不是分布在各个 Broker 上感到困惑。后面继续给大家进行分析。




