ZooKeeper 始终是 CP 是否正确(根据 CAP 定理)?或者无论如何将它用作服务发现需求的AP?
3 回答
Zookeeper不是A,也不能掉P,所以明明叫CP。就 CAP 定理而言,“C”实际上意味着线性化。
线性化:如果操作 B 在操作 A 成功完成后开始,则操作 B 必须看到系统处于与操作 A 完成时相同的状态,或者更新的状态。
但是,Zookeeper 具有顺序一致性——来自客户端的更新将按照它们发送的顺序应用。
ZooKeeper 实际上并没有在客户端视图之间同时保持一致。 http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_zkGuarantees
ZooKeeper 不保证在每个实例中,两个不同的客户端将拥有相同的 ZooKeeper 数据视图。由于网络延迟等因素,一个客户端可能会在另一个客户端收到更改通知之前执行更新。考虑两个客户端 A 和 B 的场景。如果客户端 A 将 znode /a 的值从 0 设置为 1,然后告诉客户端 B 读取 /a,客户端 B 可能会读取旧值 0,具体取决于哪个服务器它连接到。如果客户端 A 和客户端 B 读取相同的值很重要,客户端 B 应该在执行读取之前从 ZooKeeper API 方法调用 sync() 方法。
ZooKeeper 提供“顺序一致性”。这比线性化弱,但仍然非常强大,比“最终一致性”强得多。ZooKeeper 还提供了一个同步命令。如果您调用同步命令然后读取,则可以保证读取至少看到在同步开始之前完成的最后一次写入。
linearizability
,写入应该是瞬时的。不精确的是,一旦写入完成,所有后续读取(其中“稍后”由挂钟开始时间定义)都应返回该写入的值或稍后写入的值。一旦读取返回特定值,所有后续读取都应返回该值或后续写入的值。”
在 Zookeeper 中,他们有 sync() 方法可以在我们需要线性化之类的地方使用。
Serializability
是关于事务或对一个或多个对象的一个或多个操作组的保证。它保证在多个项目上执行一组事务(通常包含读取和写入操作)等效于事务的某些串行执行(总排序)。
参考 :
不,您不能像在其他一些系统中那样更改当前版本的 ZooKeeper 中的一致性保证。
您可以向客户端添加本地缓存,这将使它们在集群出现故障时具有只读数据,但就 CAP 而言,它仍然不是 A,因为它需要可用于更新和读取。
如果 ZK 为您的服务发现需求提供了太强的一致性级别,您应该尝试研究其他选项,例如 Eureka、Consul 或 etcd。
可能相关阅读:
一个很好的问题。
就 CAP 定理而言,“C”实际上意味着线性化:
如果操作 B 在操作 A 成功完成后开始,则操作 B 必须看到系统处于与操作 A 完成时相同的状态,或者更新的状态。
由于 ZooKeeper 中的写入在 quorum 确认后被认为已完成,因此仍然可能存在带有旧数据的陈旧节点。因此,严格来说,ZooKeeper 默认不是 CP 系统,尽管它提供了相当高的一致性水平。您可以通过在读取之前使用sync
命令来确保线性化。
关于网络分区下的可用性,那些不是多数的节点不能再处理写请求,因为它们没有仲裁。
也可以看看: