更多相关内容可检察
kafka高可用筹划
Apache Kafka 的高可用筹划主要通过以下几个方面来实现:
- 副本机制(Replication):在 Kafka 中,每个 partition 都有多个副本,其中一个作为 leader,其他的作为follower。所有的读写操作都是通过 leader 来进行的,follower 则负责从 leader 同步数据。当 leader出现故障时,会从 follower 中选举出新的 leader,以包管服务的可用性。
- 分区机制(Partitioning):Kafka 的 topic 可以分为多个 partition,每个 partition可以在不同的服务器上,这样即使某个服务器出现故障,也不会影响到其他 partition 的正常服务。
- 斲丧者组(Consumer Groups):Kafka 允很多个斲丧者组同时斲丧同一个 topic,每个斲丧者组都会维护本身的offset,这样即使某个斲丧者组出现故障,也不会影响到其他斲丧者组的斲丧
- ZooKeeper 集群:Kafka 使用 ZooKeeper 来管理集群的元数据信息,如 broker、topic 和
partition 的信息等。ZooKeeper 本身也是一个分布式服务,可以通过多个节点构成集群,提供高可用性。
- ISR(In-Sync Replicas)机制:Kafka 通过 ISR 机制来包管数据的同等性。只有在 ISR 列表中的
follower 才有资格被选为新的 leader,这样可以包管新的 leader 拥有所有的数据副本。
通过以上的筹划,Kafka 可以或许在面临故障时,仍能包管服务的可用性和数据的同等性。
集群架构
Kafka 的服务器端由被称为 Broker 的服务进程构成,即一个 Kafka 集群由多个 Broker 构成
这样如果集群中某一台机器宕机,其他机器上的 Broker 也依然可以或许对外提供服务。这其实就是 Kafka 提供高可用的基础
Kafka集群选举
ISR与OSR
Kafka为了对消息进行分类,引入了Topic(主题)的概念。生产者在发送消息的时候,必要指定发送到某个Topic,然后消息者订阅这个Topic并进行斲丧消息。
Kafka为了提拔性能,又在Topic的基础上,引入了Partition(分区)的概念。Topic是逻辑概念,而Partition是物理分组。一个Topic可以包罗多个Partition,生产者在发送消息的时候,必要指定发送到某个Topic的某个Partition,然后消息者订阅这个Topic并斲丧这个Partition中的消息。
Kafka为了进步体系的吞吐量和可扩展性,把一个Topic的不同Partition放到多个Broker节点上,充实使用机器资源,也便于扩展Partition。
Kafka为了包管数据的安全性和服务的高可用,又在Partition的基础上,引入Replica(副本)的概念。一个Partition包罗多个Replica,Replica之间是一主多从的关系,有两种类型Leader Replica(领导者副本)和Follower Replica(跟随者副本),Replica分布在不同的Broker节点上。
Leader Replica负责读写请求,Follower Replica只负责同步Leader Replica数据,不对外提供服务。当Leader Replica发生故障,就从Follower Replica选举出一个新的Leader Replica继续对外提供服务,实现了故障自动转移。
Kafka为了提拔Replica的同步服从和数据写入服从,又对Replica进行分类。针对一个Partition的所有Replica聚集统称为AR(Assigned Replicas,已分配的副本),包罗Leader Replica和Follower Replica。与Leader Replica保持同步的Replica聚集称为ISR(In-Sync Replicas,同步副本),与Leader Replica保持失去同步的Replica聚集称为OSR(Out-of-Sync Replicas,失去同步的副本),AR = ISR + OSR。
Leader Replica将消息写入磁盘前,必要等ISR中的所有副本同步完成。如果ISR中某个Follower Replica同步数据掉队Leader Replica过多,会被转移到OSR中。如果OSR中的某个Follower Replica同步数据追上了Leader Replica,会被转移到ISR中。当Leader Replica发生故障的时候,只会从ISR中选举出新的Leader Replica
LEO和HW
Kafka为了记载副本的同步状态,以及控制斲丧者斲丧消息的范围,于是引入了LEO(Log End Offset,日志结束偏移量)和HW(High Watermark,高水位)。
LEO表现分区中的下一个被写入消息的偏移量,也是分区中的最大偏移量。LEO用于记载Leader Replica和Follower Replica之间的数据同步进度,每个副本中各有一份。
Leader : LEO 1000 HW : 950
Follower1 : LEO 980
Follower2 : LEO 1000
Follower3 : LEO 950
HW表现所有副本(Leader和Follower)都已乐成复制的最小偏移量,是所有副本共享的数据值。换句话说,HW之前的消息都被视为已提交,斲丧者可以斲丧这些消息。用于确保消息的同等性和只读一次。
LEO和HW的更新流程:
- 初始状态,三个副本中各有0和1两条消息,LEO都是2,位置2是空的,表现是即将被写入消息的位置。HW也都是2,表现Leader Replica中的所有消息已经全部同步到Follower Replica中,斲丧者可以斲丧0和1两条消息。
- 生产者往Leader Replica中发送两条消息,此时Leader Replica的LEO的值增加2,变成4。由于还没有开始往Follower Replica同步消息,所以HW值和Follower Replica中LEO值都没有变。由于斲丧者只能斲丧HW之前的消息,也就是0和1两条消息
- Leader Replica开始向Follower Replica同步消息,同步速率不同,Follower1的两条消息2和3已经同步完成,而Follower2只同步了一条消息2。此时,Leader和Follower1的LEO都是4,而Follower2的LEO是3,HW表现已乐成同步的最小偏移量,值是3,表现此时斲丧者只能读到0、1、2,三条消息
- 所有消息都同步完成,三个副本的LEO都是4,HW也是4,斲丧者可以读到0、1、2、3,四条消息
Kafka分区Leader选举
常见的有以下几种情况会触发Partition的Leader Replica选举:
- Leader Replica 失效:当 Leader Replica 出现故障或者失去毗连时,Kafka 会触发 Leader Replica 选举。
- Broker 宕机:当 Leader Replica 所在的 Broker 节点发生故障或者宕机时,Kafka 也会触发 Leader Replica 选举。
- 新增 Broker:当集群中新增 Broker 节点时,Kafka 还会触发 Leader Replica 选举,以重新分配 Partition 的 Leader。
- 新建分区:当一个新的分区被创建时,必要选举一个 Leader Replica。
- ISR 列表数目镌汰:当 Partition 的 ISR 列表数目镌汰时,大概会触发 Leader Replica 选举。当 ISR 列表中副本数目小于Replication Factor(副本因子)时,为了包管数据的安全性,就会触发 Leader Replica 选举。
- 手动触发:通过 Kafka 管理工具(kafka-preferred-replica-election.sh),可以手动触发选举,以均衡负载或实现集群维护
Leader Replica选举策略
在 Kafka 集群中,常见的 Leader Replica 选举策略有以下三种:
- ISR 选举策略:默认情况下,Kafka 只会从 ISR 聚集的副本中选举出新的 Leader Replica,OSR 聚集中的副本不具备参选资格。
- 不干净副本选举策略(Unclean Leader Election):在某些情况下,ISR 选举策略大概会失败,例如当所有 ISR 副本都不可用时。在这种情况下,可以使用 Unclean Leader 选举策略。Unclean Leader 选举策略会从所有副本中(包罗OSR聚集)选择一个副本作为新的 Leader 副本,即使这个副本与当前 Leader 副本不同步。这种选举策略大概会导致数据丢失,默认关闭
- 首选副本选举策略(Preferred Replica Election):首选副本选举策略也是 Kafka 默认的选举策略。在这种策略下,每个分区都有一个首选副本(Preferred Replica),通常是副本聚集中的第一个副本。当触发选举时,控制器会优先选择该首选副本作为新的 Leader Replica,只有在首选副本不可用的情况下,才会考虑其他副本。
固然,可以使用命令手动指定每个分区的首选副本:
bin/kafka-topics.sh --zookeeper localhost:2181 --topic my-topic-name --replica-assignment 0:1,1:2,2:0 --partitions 3
意思是:my-topic-name有3个partition,partition0的首选副本是Broker1,partition1首选副本是Broker2,partition2的首选副本是Broker0
Leader Replica选举过程
谁来主持选举?
kafka先在brokers内里选一个broker作为Controller主持选举。Controller是使用zookeeper选举出来的,每个broker都往zk内里写一个/controller节点,谁先写乐成,谁就成为Controller。如果Controller失去毗连,zk上的临时节点就会消失。别的的broker通过watcher监听到Controller下线的消息后,开始选举新的Controller。
一个Broker节点相当于一台机器,多个Broker节点构成一个Kafka集群。Controller节点也叫控制器节点 , 他负责直接与zookeeper进行通讯,并负责管理整个集群的状态和元数据信息
Controller的责任
- 监听Broker的变化
- 监听Topic变化
- 监听Partition变化
- 获取和管理Broker、Topic、Partition的信息
- 管理Partition的主从信息
当Leader Replica宕机或失效时,就会触发 Leader Replica 选举,分为两个阶段,第一个阶段是候选人的提名和投票阶段,第二个阶段是Leader的确认阶段。具体过程如下:
lag(滞后)是kafka斲丧队列性能监控的告急指标,lag的值越大,表现kafka的消息堆积越严重
- 候选人提名和投票阶段
在Leader Replica失效时,ISR聚集中所有Follower Replica都可以成为新的Leader Replica候选人。每个Follower Replica会在选举开始时向其他Follower Replica发送成为候选人的请求,并附带本身的元数据信息,包罗本身的当前状态和Lag值。而Preferred replica优先成为候选人。
其他Follower Replica在收到候选人请求后,会根据请求中的元数据信息,计算每个候选人的Lag值,并将本身的选票投给Lag最小的候选人。如果多个候选人的Lag值相同,则随机选择一个候选人。
- Leader确认阶段
在第一阶段结束后,所有的Follower Replica会重新计算每位候选人的Lag值,并投票给Lag值最小的候选人。此时,选举的结果并不愿定出现对候选人的全局共识。为了避免出现这种情况,Kafka中使用了ZooKeeper来实现分布式锁,确保只有一个候选人可以或许成为新的Leader Replica。
当ZooKeeper确认有一个候选人已经获得了分布式锁时,该候选人就成为了新的Leader Replica,并向所有的Follower Replica发送一个LeaderAndIsrRequest请求,更新Partition的元数据信息。其他Follower Replica接收到请求后,会更新本身的Partition元数据信息,将新的Leader Replica的ID添加到ISR列表中
副本机制(Replication)
Kafka 中消息的备份又叫做 副本(Replica)
Kafka 界说了两类副本:
- 领导者副本(Leader Replica): 负责数据读写
- 跟随者副本(Follower Replica): 只负责数据备份
- 当领导者副本所在节点宕机之后, 会从跟随者副本中选举一个节点, 升级为领导者副本 , 对外提供数据读写服务, 包管数据安全
斲丧者组和再均衡
斲丧者组
斲丧者组(Consumer Group)是由一个或多个斲丧者实例(Consumer Instance)构成的群组,具有可扩展性和可容错性的一种机制。斲丧者组内的斲丧者共享一个斲丧者组ID,这个ID 也叫做 Group ID,组内的斲丧者共同对一个主题进行订阅和斲丧,同一个组中只可以或许由一个斲丧者去斲丧某一个分区的数据,多余的斲丧者会闲置,派不上用场。
同一个分区只能被一个斲丧者组中的一个斲丧者斲丧 , 一个斲丧者组中的某一个斲丧者, 可以斲丧多个分区
一个生产者发送一条消息只能被一个斲丧者斲丧 : 让斲丧者处于同一个组中即可
一个生产者发送一条消息必要被多个斲丧者斲丧 : 让斲丧者处于不同的组中
- @Component
- public class KafkaConsumerListener {
- @KafkaListener(topics = "kafka.topic.my-topic1",groupId = "group1")
- public void listenTopic1group1(ConsumerRecord<String, String> record) {
- String key = record.key();
- String value = record.value();
- System.out.println("group1中的消费者接收到消息:"+key + " : " + value);
- }
- @KafkaListener(topics = "kafka.topic.my-topic1",groupId = "group2")
- public void listenTopic1group2(ConsumerRecord<String, String> record) {
- String key = record.key();
- String value = record.value();
- System.out.println("group2中的消费者接收到消息:"+key + " : " + value);
- }
- }
复制代码 再均衡(重均衡)
再均衡就是指 当斲丧者组中的斲丧者发生变动的时候(新增斲丧者, 斲丧者宕机) , 重新为斲丧者分配斲丧分区的过程
当斲丧者组中重新加入斲丧者 , 或者斲丧者组中有斲丧者宕机 , 这个时候Kafka会为斲丧者组中的斲丧者从新分配斲丧分区的过程就是再均衡
重均衡(再均衡)非常告急,它为斲丧者群组带来了高可用性 和 伸缩性,我们可以放心的添加斲丧者或移除斲丧者,不过在正常情况下我们并不希望发生这样的活动。在重均衡期间,斲丧者无法读取消息,造成整个斲丧者组在重均衡的期间都不可用 , 而且在发生再均衡的时候有大概导致消息的丢失和重复斲丧
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |