数据一致性是所有分布式系统的一个全局问题。星云图形作为分布式图形数据库也不例外。

由于查询层和存储层之间的分离,星云图仅在存储层中公开简单的 kv 接口。星云图使用 RocksDB 作为后端 kv 库,通过Raft 协议确保多个副本之间的强数据一致性。

虽然木筏比Paxos更容易理解,但它在分布式系统中的实践是棘手的。

另一个具有挑战性的问题是如何测试基于 Raft 的分布式系统。目前,星云图验证与杰普森的数据一致性。在我们之前在星云图中练习杰普森测试框架后,我们详细介绍了Jepsen测试框架的工作原理,您可以看看它,以获得一些关于Jepsen的基本理解。

在这篇文章中,我们将解释如何验证分布式星云图形 kv 存储的数据一致性。

解释强数据一致性

让我们从强数据一致性的定义开始。引用《设计数据密集型应用程序》一书

在线性系统中,一旦一个客户端成功完成写入,从数据库读取的所有客户端都必须能够看到刚刚写入的值。

强数据一致性或线性性的基本思想是使分布式系统看起来好像只有一个数据副本,并且对它的所有操作都是原子的。来自任何客户端的任何读取请求都会获取写入系统的最新数据。

使用杰普森进行线性验证

以杰普森时间线测试为例。在此测试中,我们使用单寄存器模型。客户端只能在寄存器上执行读取或写入操作。所有操作都是原子的,没有中间状态。

假设有四个客户端同时向系统发送请求。图中的每个条形指示客户端发出的请求,其中条形的顶部是发送请求的时间,条形的底部是客户端收到响应的时间。

从客户端的角度来看,任何请求都将在发送到收到响应之间的任何时间进行处理。从上图看,三个操作,由客户端 1 写入 1(即 1: write1),写入 4 由客户端 3(即 3: write4),读取 1 由客户端 4(即 4: read1),在处理时间重叠。但是,我们知道系统通过不同客户端接收的响应进行实际的请求处理序列。

下面以及如何:

初始值为空,但客户端 4 获取 1 的读取请求,这表示客户端 4 的读取操作必须在客户端 1 的写入 1 操作之后开始,并且客户端 3 的写入 4 必须在写入 1 之前发生,或者客户端 4 将返回较旧的值 4 以表示读取请求。因此,三个操作的顺序是写入 4 -> 写入 1 -> 读取 1。

虽然从上图中看,请求读取 1 是先发送的,它是最后一个处理。以后的操作不会及时重叠,也就是说,它们是按顺序发送的。客户端 2 的读取请求返回最后一个写入值 4。

整个过程不违反强数据一致性的规则,因此通过验证。

如果客户端 3 的读取请求返回旧值 4,则系统不强一致。根据前面的分析,最后一个成功的写入值为 1。如果客户端 3 获取陈旧值 4,则系统的线性可伸缩性将断开。

实际上,Jepsen 使用类似的算法验证分布式系统的强数据一致性。

在 Jepsen 测试中发现的数据一致性问题

下面给出了如何在星云图中的 Raft 组(三个副本)中处理请求的示例,以便更好地理解数据一致性。

读取请求处理相对简单,因为只有当选的领导服务器才能与客户端进行交互。领导者在检查其仍为领导者后,从状态机获取相应的结果并发送回客户端。

写入请求处理有点复杂。这些步骤如下图所示:

  1. 领导者(绿色圆圈)接收来自客户端的请求,并写入其 WAL(提前写入日志)。
  2. 领导者将 WAL 中的相应日志条目发送给其关注者,并进入等待阶段。
  3. 跟随者接收日志条目并写入自己的 WAL,然后返回成功。
  4. 当至少有一个跟随者返回成功时,领导者将更新状态机并向客户端发送响应。
    Raft paper

    数据一致性示例 2:领导者确保自己成为领导者

    通过杰普森测试我们发现的另一个问题就是:领导者如何确保自己仍然是领导者?此类问题发生在网络分区上。当领导由于网络故障而无法连接到仲裁时,如果仍然允许读取,则可能会返回一个过时的值。

    为了避免这种情况,我们引入了领导者租赁概念。

    当节点被选为领导者时,它需要定期向其他节点发送检测信号。如果大多数节点成功接收检测信号,则获得一段时间的租约,并且在此期间将没有任何新的领导。因此,保证节点上的数据恢复性,在此期间可以正常处理读取请求。

    星云图与 Tikv 的过程不同, 由于不同节点的时钟偏斜漂移, 因此不将心跳间隔— —一些系数视为租约时间

    在分区网络时,尽管存在隔离,但旧领导者仍在租约期间处理读取请求(写入请求由于隔离而失败)。当租约过期时,读取和写入请求都将失败。当跟随者节点在等待来自领导者节点的检测信号时,将发生领导者选举。

    结论

    您需要长期压力测试和故障模拟来发现分布式系统中的问题。Jespen 是一个很好的帮助者,它能够在各种故障下验证分布式系统。

    将来,我们将引入其他混沌工程工具来验证星云图中的数据一致性。这样,我们可以不断提高性能,同时确保高数据可靠性。

Comments are closed.