在推理ZooKeeper时,考虑原子广播比共识更有意义。但是等等,它们不是等效的吗?是的,从简化的角度来看,它们是,但是它们仍然呈现不同的语义。下边一个错误的推理如何导致问题的简单示例。
假设我们有一个包含三个客户端的系统,一个配置器(C)和两个工作器(W1和W2)。配置器C告诉工作器应该消费的信息,并期望所有工作器都消费相同的信息。协调员选择的信息会随时间变化而变化,并且协调员通过ZooKeeper以容错的方式将其选择传达给工作人员。现在考虑以下步骤序列:
- C将香草写入ZooKeeper
- W1读香草
- C之后立即将巧克力写入ZooKeeper
- W2读巧克力,W1已经在食用香草
显然,由于他们读取了不同的值,工作器会消费不同的信息,但是到底出了什么问题呢?服务不应该让我们达成共识吗?事实证明,ZooKeeper提供的共识是对ZooKeeper状态更新的统一视图。如果两个或更多客户端能够观察到ZooKeeper服务的所有更新,则它们观察到以相同顺序应用的相同更新,但不一定同时。因此,它提供的那种协议不能与始终遵守相同状态混淆。保持一致并不意味着读取的值必须相同。
解决此问题的一种方法是使用序列化更新,以使工作器就该值达成共识,本质上是像我们之前讨论的那样,使用原子广播实现共识。 W1读取一个值后,就可以建议它们消耗香草,因为配置程序已建议这样做。 W2的功能相同,但是由于他们提出了不同的值,因此需要打破平局。他们可以通过选择使用ZooKeeper顺序节点写入的第一个值来做到这一点。
与原始提案相比,该提案为何有效?因为每个工作器都“提出”了一个单一的价值,而且这些价值不会发生变化。随着时间的推移,配置器更改值,他们可以通过运行此简单协议的独立实例来商定不同的值。
请注意,这种情况只是为了说明围绕协议的推理和提供该协议的服务不正确时的问题。解决问题的真正方法将取决于应用程序的精确语义,并且会有多种实现方法。
共识在分布式系统中起着重要作用,使用Apache ZooKeeper之类的服务可以使复制的某些方面更加简单。为了使论点非常具体,我们在这里集中讨论Apache Kafka的复制方案。 Kafka使用Apache ZooKeeper来存储元数据。此元数据有多种用途—持久保留组成topic的brokers,从为其数据提供写服务的副本中选择一个leader,并保留了一些子节点的信息。
在这里我们仅介绍了足以使该参数易于理解的内容。 Kafka暴露了topic的抽象:客户通过topic进行消息生成和消费。为了提高并发的性能,主题被进一步划分为partitions。partitions是Kafka中并行性和复制的基本单位。在分区的一组副本中,有一个会被选为领导者(使用ZooKeeper),其余为跟随者。领导负责分区的所有读取和写入。 Kafka还具有同步副本(ISR)的概念:副本的子集当前处于活动状态,并且已被领导者追上,也就是说leader和副本没有相差太多。
ISR动态更改,并且每次更改时,该集的新成员资格都将保留到ZooKeeper。 ISR有两个重要目的。首先,在领导者宣布它们已提交之前,此集合需要确认所有写入分区的记录。因此,ISR集必须至少包含f + 1个副本才能承受f次崩溃,并且f + 1所需的值由配置设置。其次,由于ISR拥有分区中以前提交的所有消息,为了保持一致性,新领导者必须来自最新的ISR。从最新的ISR中选出一位领导者对于确保在领导者过渡期间不会丢失任何已落实的消息来说很重要。当副本发生故障时,会将其从ISR中删除。当副本在崩溃后重新启动时,它会被告知当前的领导者和ISR(通过从ZooKeeper中读取),然后通过从当前领导者中拉出来同步其数据,直到其赶上并足以成为ISR的一部分为止。在这种复制方案中,ZooKeeper只处理复制的元数据(分区信息和ISR成员资格),实际数据的复制留给应用程序(Kafka)来考虑。
就持久性而言,Kafka的复制协议和ZooKeeper的复制协议之间还有一个重要区别。由于Kafka依赖ZooKeeper成为元数据的“真相之源”,因此ZooKeeper必须提供强大的持久性保证。因此,它只有在将数据同步到ZooKeeper仲裁服务器的磁盘后才会确认写请求。由于Kafka的brokers需要处理的数据量很大,因此无法承受做到这样,也无法将分区数据同步到磁盘。分区的消息将写入相应的文件,但是不会调用fsync/fdatasync,这意味着数据在写入后仍保留在操作系统页面高速缓存中,并不一定要刷新到磁盘介质中。这种设计选择会对性能产生巨大的积极影响,但是具有一个副作用,即正在恢复的副本可能没有先前确认的某些消息。
在复制系统中使用仲裁的一个很大的优势是能够掩盖崩溃。来自足够大的副本子集(例如多数)的投票就足以提交。在以2f + 1方式复制的基于仲裁的系统中,如果有任何f个副本崩溃,则该系统仍可以透明地进行进度(可能会有一些小的问题)。每个写入操作都将到达所有副本,但是只有多数仲裁的响应才需要提交写入。查看下图:
多数仲裁的一个重要缺点是要求至少(n +1)/ 2个确认,所以节点的数量会随着n的增加而增加。这种仲裁系统方案可与ZooKeeper之类的系统很好地协作,因为它处理元数据:体积小且写入很少,通常常见的操作不在关键路径中。
Kafka的ISR方案不使用上边的多数仲裁的方式,而是要求当前ISR的所有成员做出响应:
为了提交写操作,ISR中的所有副本都必须以确认响应,而不仅仅是大多数响应。与经典仲裁方式不同,ISR的大小与副本集的大小脱钩,这为副本集的配置提供了更大的灵活性。例如,我们可以有11个副本,其最小ISR大小为3(f = 2)。对于大多数仲裁,具有11个副本将必然意味着大小为6的副本。
请记住,最小ISR的大小与系统提供的持久性保证直接相关。由于可以通过配置来调整对ISR最小大小的限制,ISR持久性保证类似于ZooKeeper提供的一种保证,即如果失败的副本数低于预期的仲裁大小,则不会进行写操作。如果系统不能保证可以执行新写入,则它在可用性上权衡了可用性,在持久性方面不接受新写入。在这方面,Kafka的复制方案非常灵活。通过让ISR的最小大小可配置,它使主题可以在可用性和耐用性之间进行权衡,反之亦然,而仲裁不需要包含大多数副本。
尽管ISR方案具有更高的可伸缩性并可以容忍更多的故障,但它对副本的某些子集(ISR)的性能也更加敏感。如果基于多数仲裁的方案仅忽略了最慢的副本,则该方案将暂停对分区的所有写入操作,直到最慢的副本(如果它是ISR的一部分)被删除。在大多数故障模式下,副本会被快速删除。对于软故障,在一定的超时后将删除无响应的副本。同样,如果慢速副本落后于配置所定义的值以后,它们也会被删除。
对于像Apache Kafka这样的数据系统,其复制方案的这种灵活性具有对持久性保证提供更细粒度控制的优点,事实证明,这在生产中存储大量数据时非常有用。作为另一个数据点,像Apache BookKeeper这样的系统也使用了类似的方案,其中副本和确认的数量是独立的。但是,BookKeeper不能像Kafka一样提供ISR。
有趣的是,该方案与PacificA的工作[10]中描述的方案很接近。在PacificA的工作中,该框架将副本组的配置管理与实际数据复制分开,就像Kafka一样。它还与Cheap Paxos共享一些属性[11]。使用Cheap Paxos,数据副本仅发送到f + 1个副本,而在Kafka中,数据副本发送到所有副本(以保持副本有效,而不是为了确保正确性)。但是,这两种协议都建议保持f +1副本的固定子集为最新,并在怀疑崩溃时重新配置该集合。 Cheap Paxos从协议内部执行重新配置,而Kafka依赖于外部复制状态机(ZooKeeper)。
在Kafka复制协议中,ISR更新协议掩盖了共识。由于ZooKeeper最终通过将ISR信息存储在ZooKeeper中而最终公开了一个原子广播原语,因此从本质上来说,可以保证对ISR更改的继承达成一致。当副本在崩溃后恢复时,它可以转到ZooKeeper,查找最新的分区元数据(领导者,ISR),并进行相应的同步以获取最新的提交消息。由于所有副本(通过ZooKeeper)都同意最新的ISR是什么,因此不可能出现裂脑情况。
让我们来看一些场景,以更好地了解其工作原理。假设我们有一个分区{A,B,C,D,E}的5个副本,并且ISR集最初包含所有副本。下图说明了这种情况
在某个时候,副本E崩溃。
一旦开始恢复过程,它将从ZooKeeper中读取分区的状态,并得知A是当前ISR的领导者。
完成同步后,将其添加回ISR。
如果不存在ZooKeeper,则副本E将需要与其他副本进行对话,以找出哪个副本进行同步。无法查询像ZooKeeper这样的“真相之源”,查询剩余那些节点会带来各种各样的麻烦,因为副本可能会崩溃或被分割掉,这是在没有ZooKeeper这样的依赖的情况下进行仲裁(多数选择)的关键原因。即使使用ZooKeeper,也可能需要注意一些竞争条件。
这篇文章翻译自:https://www.confluent.fr/blog/distributed-consensus-reloaded-apache-zookeeper-and-replication-in-kafka/,有兴趣的可以看原文,由于水平有限翻译过程中难免有些错误,请大家指正,一定要多拍拍。这篇文章是由Apache Kafka的共同创建者Neha Narkhede和Apache Z...
2.什么是ISR?
ISR全称In-Sync-Replica-Set,意思是与Leader保持同步的的follower集合,当一个Partition写一条数据时,就需要Followers来同步此数据,
目录1. 数据副本简介2. 副本写入流程3. 副本配置步骤4. 副本效果演示
1. 数据副本简介
副本的目的主要是保障数据的高可用性,即使一台 ClickHouse 节点宕机,那么也可以从其他服务器获得相同的数据。只有 MergeTree 系列里的表可以支持副本:
ReplicatedMergeTree
ReplicatedSummingMergeTree
ReplicatedReplacingMergeTree
ReplicatedAggregatingMergeTree
ReplicatedCol
Kafka一.Kafka基础1.Kafka核心概念(1)术语解释(2)分区策略(3)副本策略(4)存储策略2.ZooKeeper与Kafka(1)Broker注册并监控状态(2)Topic注册(3)生产者负载均衡(4)offset维护3.副本同步4.容灾5.高吞吐(1)顺序读写(2)零拷贝(3)分区(4)批量发送(5)数据压缩(6)Consumer的负载均衡6.负载均衡
一.Kafka基础
1.Kafka核心概念
(1)术语解释
Kafka集群由不同的Broker节点组成,每个Broker都有唯一的id(如
Zookeeper 是一个分布式协调服务,可用于服务发现,分布式锁,分布式领导选举,配置管理等。
Zookeeper 提供了一个类似于 Linux 文件系统的树形结构(可认为是轻量级的内存文件系统,但 只适合存少量信息,完全不适合存储大量文件或者大文件),同时提供了对于每个节点的监控与 通知机制。
2. Zookeeper 角色
Zookeeper集群是一个基于主从复制的高可用集群,每个服务器承担如下三种角色中的一种
2.1. Lead
编写不易,转载请注明(http://shihlei.iteye.com/blog/2083614)!
它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
版本:zookeeper-3.4.5-c...
一、ZooKeeper 简介
1.1 ZooKeeper 是什么
ZooKeeper 是 Apache 的顶级项目。ZooKeeper 为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面,ZooKeeper 并没有直接采用 Paxos 算法,而是采用了名为 ZAB 的一致性协议。
ZooKeeper 主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储。但是 ZooKeeper