Skip to content

Commit

Permalink
[Polish] Polish the whole paper
Browse files Browse the repository at this point in the history
  • Loading branch information
mapleFU committed Jun 16, 2020
1 parent 74a5461 commit 22367da
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,25 +228,25 @@ 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 处理。

作为 agreement protocol 的一部分,写请求会被转发给单一的被称为 *leader* 的服务器,其他的 *ZooKeeper* 服务器被称为 *follower* ,它们从 leader 接受包含状态变更的 proposal, 并就状态的更改达成一致。

### 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

所有更新 ZooKeeper 的请求都会被转发给 leader, leader 执行请求,并用 `Zab` ,一个原子广播协议,广播 ZooKeeper 的状态变更。Zab 默认使用简单的 majority quorum 来决定一个 proposal,所以 Zab 和 Zookeeper 只有在大多数机器正确相应的时候才能工作(*2f+1* 台服务器,我们可以容忍 *f* 个错误)。

为了达到高吞吐量,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重新传递至少上一个快照开始之后传递的所有消息。(译者:这段话我看了下一节才看懂)。

Expand Down

0 comments on commit 22367da

Please sign in to comment.