Kakfa复制机制
- 微信公众号:阿俊的学习记录空间
- 小红书:ArnoZhang
- wordpress:arnozhang1994
- 博客园:arnozhang
- CSDN:ArnoZhang1994
Kafka 将每个主题的分区日志复制到可配置数量的服务器上(可以为每个主题设置不同的复制因子)。这样在集群中某个服务器发生故障时,Kafka可以自动切换到这些副本上,以确保消息在出现故障时依然可用。
其他消息系统也提供与复制相关的功能,但我们认为,这些功能往往是后期添加的,使用较少且存在明显的缺点:副本处于非活跃状态,吞吐量大幅下降,且需要复杂的手动配置等。而 Kafka 默认就设计为支持复制的系统——实际上,我们将非复制的主题视为只有一个副本的复制主题。
Kafka 的复制单位是主题分区。在没有故障的情况下,每个分区都有一个主节点(leader)和零个或多个副节点(follower)。包括主节点在内的所有副本的总数就是复制因子。所有写操作都发送到主节点,读操作则可以从主节点或副节点读取。通常,分区的数量比代理服务器(broker)多,且主节点会均匀分布在代理服务器之间。副节点的日志与主节点的日志相同,具有相同的偏移量和消息顺序(虽然主节点可能会有少量未复制的消息)。
副节点像普通消费者一样从主节点消费消息,并将其应用到自己的日志中。通过让副节点从主节点拉取消息,可以自然地批量处理日志条目。
在分布式系统中,自动处理故障需要明确定义节点何时算作“存活”。在 Kafka 中,有一个特殊的节点称为“控制器”(controller),负责管理集群中代理的注册。代理的存活有两个条件:
- 代理必须与控制器保持活跃会话,以接收定期的元数据更新。
- 作为副节点的代理必须从主节点复制写入操作,并且不能落后太多。
“活跃会话”的定义取决于集群配置。对于 KRaft 集群,活跃会话是通过向控制器发送定期心跳来维护的。如果控制器在配置的 broker.session.timeout.ms
时间内没有收到心跳,节点将被视为离线。
对于使用 Zookeeper 的集群,存活性通过 Zookeeper 上的临时节点间接确定。代理在初始化 Zookeeper 会话时创建一个临时节点,如果代理在 zookeeper.session.timeout.ms
过期前未发送心跳导致会话丢失,该节点将被删除,控制器通过 Zookeeper 的监视机制注意到节点删除并将代理标记为离线。
我们称满足这些条件的节点为“同步”(in sync),以避免“存活”或“失败”的模糊性。主节点会跟踪同步副本集合(ISR)。如果某个代理不满足这些条件,它将从 ISR 中移除。例如,如果一个副节点宕机,控制器会注意到会话的丢失并将其移除。如果副节点落后于主节点太多但仍保持活跃会话,主节点也会将其从 ISR 中移除。滞后副本的判断通过 replica.lag.time.max.ms
配置控制。如果副节点在最大时间内无法追赶上主节点日志的末尾,将被移除出 ISR。
在分布式系统术语中,Kafka 仅处理“故障/恢复”模型的故障,即节点突然停止工作,随后恢复(可能不知自己曾宕机)。Kafka 不处理所谓的“拜占庭故障”,即节点产生任意或恶意响应。
我们可以更精确地定义消息的提交。当分区中所有 ISR 副本都将消息应用到日志时,消息才算提交。只有提交的消息才会提供给消费者。这意味着消费者无需担心在主节点故障时会看到可能丢失的消息。生产者可以选择等待消息提交或立即返回,这取决于他们对延迟和持久性的权衡偏好,该偏好通过生产者的 acks
设置控制。注意,主题还有一个设置用于指定同步副本的最小数量,生产者在请求消息写入所有同步副本时会检查这个数量。如果生产者请求的确认较少,消息可以在同步副本数量低于最小值时提交并被消费(例如,仅主节点也可以提交)。
Kafka 保证已提交的消息不会丢失,只要始终有一个同步副本在线。
Kafka 在节点故障后的短暂切换期间仍然可用,但在网络分区的情况下可能不可用。
复制日志:多数决机制、ISR 和状态机
Kafka 的每个分区本质上是一个复制日志。复制日志是分布式数据系统中最基础的原语之一,有多种实现方法。复制日志可以用作其他分布式系统的原语来实现状态机风格的系统。
复制日志的核心是对一系列值的顺序达成共识(通常按 0、1、2... 编号)。最简单、最快速的实现方式是通过主节点选择值的顺序,只要主节点存活,副节点只需复制主节点的值及其顺序。
当然,如果主节点不会故障,我们就不需要副节点了!当主节点故障时,我们需要从副节点中选出新的主节点。然而,副节点可能落后或宕机,因此我们必须确保选择最新的副节点。日志复制算法的核心保证是:如果我们告诉客户端消息已提交,即使主节点宕机,新选出的主节点也必须有这条消息。这意味着如果主节点等待更多的副节点确认消息提交,可能会有更多可选的主节点。
如果你选择了合适的确认数量,并确保在选举主节点时比较日志时存在交集,那么这被称为“多数决机制”。
一种常见的做法是使用多数票来决定提交和选举主节点。尽管 Kafka 没有采用这种方式,但为了理解其权衡,我们还是先探讨一下。假设有 2f+1 个副本,如果在提交消息前需要 f+1 个副本接收到消息,而在选举主节点时从至少 f+1 个副本中选出日志最完整的副本作为新的主节点,那么在最多 f 个副本故障的情况下,新的主节点将保证拥有所有已提交的消息。多数决机制的一个优势是,延迟只取决于最快的服务器。例如,若复制因子为 3,延迟取决于较快的副节点,而非较慢的副节点。
Kafka 采用的是另一种方式,通过动态维护同步副本集合(ISR)。只有这些副本才有资格选举为主节点。Kafka 在分区写入消息时,只有当所有同步副本都收到消息,写入才被视为提交。ISR 集合在每次变更时保存在集群元数据中,因此只要副本在 ISR 中,就有资格成为新的主节点。
Kafka 允许客户端选择是否在消息提交时阻塞,且由于所需的复制因子较低,Kafka 的吞吐量和磁盘空间利用率也相对较高。
另一个重要的设计区别是 Kafka 并不要求崩溃的节点在恢复后保留其所有数据。许多复制算法依赖于“稳定存储”,即保证在任何故障恢复场景中不会丢失数据。Kafka 的协议允许副本重新加入 ISR 时,确保即便该副本在崩溃时丢失了未刷写的数据,依然可以通过重新同步完全恢复。
标签:副本,Kafka,Kakfa,复制,消息,Apache,日志,节点 From: https://www.cnblogs.com/arnozhang/p/18466150