# 4.7 Test-and-Set 服务

最后还有一个细节。我一直都假设Primary出现的是fail-stop故障（详见4.1最开始），但是这不是所有的情况。一个非常常见的场景就是，Primary和Backup都在运行，但是它们之间的网络出现了问题，同时它们各自又能够与一些客户端通信。这时，它们都会以为对方挂了，自己需要上线并接管服务。所以现在，我们对于同一个服务，有两个机器是在线的。因为现在它们都不向彼此发送Log条目，它们自然就出现了分歧。它们或许会因为接收了不同的客户端请求，而变得不一样。

因为涉及到了计算机网络，那就可能出现上面的问题，而不仅仅是机器故障。如果我们同时让Primary和Backup都在线，那么我们现在就有了脑裂（Split Brain）。这篇论文解决这个问题的方法是，向一个外部的第三方权威机构求证，来决定Primary还是Backup允许上线。这里的第三方就是Test-and-Set服务。

Test-and-Set服务不运行在Primary和Backup的物理服务器上，VMware FT需要通过网络支持Test-and-Set服务。这个服务会在内存中保留一些标志位，当你向它发送一个Test-and-Set请求，它会设置标志位，并且返回旧的值。Primary和Backup都需要获取Test-and-Set标志位，这有点像一个锁。为了能够上线，它们或许会同时发送一个Test-and-Set请求，给Test-and-Set服务。当第一个请求送达时，Test-and-Set服务会说，这个标志位之前是0，现在是1。第二个请求送达时，Test-and-Set服务会说，标志位已经是1了，你不允许成为Primary。对于这个Test-and-Set服务，我们可以认为运行在单台服务器。当网络出现故障，并且两个副本都认为对方已经挂了时，Test-and-Set服务就是一个仲裁官，决定了两个副本中哪一个应该上线。

对于这种机制有什么问题吗？

> 学生提问：只有在网络故障的时候才需要询问Test-and-Set服务吗？
>
> Robert教授：即使没有网络分区，在所有情况下，两个副本中任意一个觉得对方挂了，哪怕对方真的挂了，想要上线的那个副本仍然需要获得Test-and-Set服务的锁。在6.824这门课程中，有个核心的规则就是，你无法判断另一个计算机是否真的挂了，你所知道的就是，你无法从那台计算机收到网络报文，你无法判断是因为那台计算机挂了，还是因为网络出问题了导致的。所以，Backup看到的是，我收不到来自Primary的网络报文，或许Primary挂了，或许还活着。Primary或许也同时看不到Backup的报文。所以，如果存在网络分区，那么必然要询问Test-and-Set服务。但是实际上没人知道现在是不是网络分区，所以每次涉及到主从切换，都需要向Test-and-Set服务进行查询。所以，当副本想要上线的时候，Test-and-Set服务必须要在线，因为副本需要获取这里的Test-and-Set锁。现在Test-and-Set看起来像是个单点故障（Single-Point-of-Failure）。虽然VMware FT尝试构建一个复制的容错的系统，但是最后，主从切换还是依赖于Test-and-Set服务在线，这有点让人失望。我强烈的认为，Test-and-Set服务本身也是个复制的服务，并且是容错的。几乎可以肯定的是，VMware非常乐意向你售卖价值百万的高可用存储系统，系统内使用大量的复制服务。因为这里用到了Test-and-Set服务，我猜它也是复制的。

你们将要在Lab2和Lab3构建的系统，会帮助你们构建容错的Test-and-Set服务，所以这个问题可以轻易被解决。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mit-public-courses-cn-translatio.gitbook.io/mit6-824/lecture-04-vmware-ft/4.7-testandset-fu-wu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
