diff --git a/README.md b/README.md index b656ecb..6a0a930 100644 --- a/README.md +++ b/README.md @@ -228,9 +228,9 @@ Figure 3显示了 YMB 的`znode`数据分布的一部分。 每个 broker 域都 ## 4 ZooKeeper Implementation -ZooKeeper通过在组成服务的每台服务器上复制ZooKeeper数据来提供高可用性。 我们假设服务器因崩溃而失败,并且此类故障服务器稍后可能会恢复。 Figure 4显示了 ZooKeeper 服务的层次组件。 收到请求后,服务器会为执行做 prepare(request processor)。 如果这样的请求需要服务器之间的协调(是写请求),则它们使用 a greement protocol(原子广播的一种实现),最后服务器将更改提交到 ZooKeeper 数据库中,该更改已在整个集成服务器中完全复制。 对于读取请求,服务器仅从本地数据库读取状态并生成对该请求的响应。 +ZooKeeper通过在组成服务的每台服务器上复制 ZooKeeper 数据来提供高可用性。 我们假设服务器因崩溃而失败,并且此类故障服务器稍后可能会恢复。 Figure 4显示了 ZooKeeper 服务的层次组件。 收到请求后,服务器会为执行做 prepare(request processor)。 如果这样的请求需要服务器之间的协调(是写请求),则它们使用 a greement protocol(原子广播的一种实现),最后服务器将更改提交到 ZooKeeper 数据库中,该更改已在整个集成服务器中完全复制。 对于读取请求,服务器仅从本地数据库读取状态并生成对该请求的响应。 -复制数据库是一个包含整个数据树的内存数据库。默认情况下,每个数据库中的 `znode` 最多存储 1MB 的数据,但是这个值是一个可配置的值,在特殊的情况下可以被更改。为了可恢复性,我们高效的把 log 更新在磁盘中,我们强制在写入内存数据库之前写入磁盘。实际上,与 Chubby 一样,我们对于提交的操作维护了一个 replay log (在我们的例子中,是一个 write-ahead log),并周期性的为内存数据库生成快照。 +复制数据库是一个包含整个数据树的内存数据库。默认情况下,每个数据库中的 `znode` 最多存储 1MB 的数据,但是这个值是一个可配置的值,在特殊的情况下可以被更改。为了可恢复性,我们高效的把 log 更新在磁盘中,我们强制在写入内存数据库之前写入磁盘。实际上,与 Chubby 一样,我们对于提交的操作维护了一个重放日志 (在我们的例子中,是一个 write-ahead log),并周期性的为内存数据库生成快照。 每个 ZooKeeper 的服务器都可以连接客户端,客户端只要连接到一个服务器,来提交它的请求,正如我们之前提到的,读请求从每个服务器的本地数据库读取。更新服务器状态的写请求,会被一个 agreement protocol 处理。 @@ -238,7 +238,7 @@ ZooKeeper通过在组成服务的每台服务器上复制ZooKeeper数据来提 ### 4.1 Request Processor -因为 message layer 是 atomic 的,我们保证副本不会出现分歧,尽管在有些时间点有些服务器可能应用的事务会更多。不像客户端的请求,事务是幂等的。领导者收到写请求后,它将计算 apply 写操作时系统的状态,并将其转换为捕获该新状态的事务。 因为可能存在尚未应用到数据库的未完成事务,所以必须计算未来状态。 例如,如果客户端执行 条件`setData`,并且请求中的版本号与正在更新的`znode`的未来的版本号匹配,则该服务将生成一个 `setDataTXN`,其中包含新数据,新版本号和更新的时间戳。 如果发生错误,例如版本号不匹配或要更新的`znode`不存在,则会生成`errorTXN`。 +因为 message layer 是 atomic 的,我们保证副本不会出现分歧,尽管在有些时间点有些服务器可能应用的事务会更多。与客户端的请求不同,事务是幂等的。领导者收到写请求后,它将计算*应用*写操作时系统的状态,并将其转换为捕获该新状态的事务。 因为可能存在尚未应用到数据库的未完成事务,所以必须计算未来的状态。 例如,如果客户端执行 条件`setData`,并且请求中的版本号与正在更新的`znode`的未来的版本号匹配,则该服务将生成一个 `setDataTXN`,其中包含新数据,新版本号和更新的时间戳。 如果发生错误,例如版本号不匹配或要更新的`znode`不存在,则会生成`errorTXN`。 ### 4.2 Atomic Broadcast @@ -246,7 +246,7 @@ ZooKeeper通过在组成服务的每台服务器上复制ZooKeeper数据来提 为了达到高吞吐量,ZooKeeper 尝试维护整个请求处理流水线都在运行。在整个处理流水线中可能有几千个请求。因为状态变更取决于上一个状态,Zab 提供了比一个比原子广播协议强的顺序保证。更确切地说, Zab 保证 leader 广播的变化按照发送的顺序,并且上一个 leader 的变更会在这个 leader 的变更之前发送。 -有一些实现细节可以简化我们的实现,并为我们提供出色的性能。 我们使用TCP进行传输,因此消息顺序由网络保持,这使我们可以简化实现。 我们使用 Zab选择的 leader 作为 ZooKeeper leader,因此创建事务的过程也可以处理它们。 我们使用该日志来跟踪建议,将其作为内存数据库的 write-ahead log,这样就不必将消息两次写入磁盘。 +有一些实现细节可以简化我们的实现,并为我们提供出色的性能。 我们使用 TCP 进行传输,因此消息顺序由网络层保证,这使我们可以简化实现(译者:Raft 等协议可以用 UDP 等实现)。 我们使用 Zab 选择的 leader 作为 ZooKeeper leader,因此创建事务的过程也可以处理事务。 我们使用日志来跟踪 Zab 协议,将其作为内存数据库的 write-ahead log,这样就不必将消息两次写入磁盘。 在正常操作期间,Zab确实按顺序准确地传递了所有消息,但是由于Zab不会永久记录所传递的每个消息的ID,因此Zab可能会在恢复期间重新传递消息。 因为我们使用幂等事务,所以只要按顺序 deliver,就可以接受多次 deliver。 实际上,ZooKeeper要求Zab重新传递至少上一个快照开始之后传递的所有消息。(译者:这段话我看了下一节才看懂)。