cs-6.824第13讲 Spanner
cs-6.824第13讲 Spanner
一个系统如何在数据广泛分散的情况下提供分布式事务。这些数据可能散布在互联网及不同的数据中心中。
将数据分布在整个网络中也非常可取,这既是为例容错,也是为了数据可以就近存在。
在实现这一目标的过程中,Spanner至少采用了两个巧妙地设计理念.
其中一点是它们运行两阶段提交,但实际上是通过paxos复制者参与者来执行地,以此来规避两阶段提交因协调器崩溃导致所有人阻塞地问题。
另一个有趣的思路是,他们利用同步时间来实现非常高效的只读事务。
这个系统在google内部被很广泛的使用。开源项目cockroachDB就是采用了这个设计。
最早促使他们开始设计Spanner的原因是因为他们在Google内部已经拥有大型数据库系统,尤其是广告系统,其数据被分散存储在众多独立的mysql和bigtable数据库中。而维护这种数据分片,确是一个笨拙又费时且需要人工操作的过程。此外,他们之前的广告数据库系统不支持跨越一个基本服务器的事务,但他们确实希望能够在更广泛的范围内分散数据以提高性能,并能在数据的多个分片上进行事务处理。
对于他们的广告数据库,显示工作负载主要是只读事务。论文的图6可以看到这一现象,其中包含了数十亿次的只读交易和仅数百万次的读写交易。因此他们对仅执行读操作的只读事务的性能非常感兴趣。
显然,他们还需要强一致性,即特性事务的一致性,他们希望事务是可串行化的,并且也希望外部一致性。如果一个事务提交了,在该事务提交完成后另一个事务开始,第二个事务需要看到第一个事务所做的任何修改。
不同数据中心存在多个副本有两个原因, 一个是防止某个数据中心放生故障,例如整个城市的电力中断,发生地震、火灾等不可抗力时,您希望在其他数据中心拥有其他副本,这些数据中心可能不会同时遭遇故障。但是这也是有代价的,因为现在的paxos可能需要跨越较长的距离,与不同数据中心的更随者进行通信。 另一个原因是这样可以是不同的客户端可以使用附近的数据副本。假设你有一份数据可能同时在加州和纽约被读取,那么拥有该数据的两个副本或许是个不错的选择,一份存在加州,一份存在纽约。
设计中的很多重点在于确保从本地、最近的副本读取数据既快速又准确。
最后Paxos与多个数据中心之间的另一个有趣的交互是,如果raft一样,Paxos仅需要多数派同意即可复制日志条目并继续。这意味着,即使存在一个速度较慢,距离较远或者不稳定的数据中心,Paxos系统仍能持续运行并接受新请求。
对于这种架构,论文讨论了几个需要解决的问题: 1.他们确实希望从本地数据中心进行读取操作,但是由于使用了paxos算法,且paxos仅需每个日志条目在多数节点上复制,这意味着,少数副本可能滞后,未能获取已经确认的最新数据。这意味着,如果我们允许客户端从本地副本快速读取数据,那么当他们的副本恰好属于未接收到最新更新的少数派时,他们可能读到过期的数据。但是,由于需要要求正确性,要求这种外部一致性的概念,即每次读取都应该看到最新数据,他们必须要有一个方法来应对。 2.一个事务可能涉及多个分片,因此涉及多个Paxos组。因此在进行读取或者写入操作时,单个事务可能同时在数据库中读取或写入多个记录,这些记录存储在多个分片和多个paxos组中,因此需要分布式事务。
接下来解释事务是如何工作的。
Spanner实际上对读写事务的处理和实现方式和只读事务大相径庭。接下来会从读写事务开始讲起,这些事务更为传统一些。
r/w transactions
BEGIN
x=x+1
y=y-1
END
首先,客户端会选取一个唯一的交易ID,该ID将伴随所有这些消息,以便系统知晓所有不同的操作都与单个交易相关联。
需要先读出x和y的值。为了维持锁的状态,每当读取或写入数据项是,负责该数据项的服务器必须为其关联一个锁。锁的管理保持不变, Spanner中的读锁仅在Paxos领导节点上维护。
当客户端需要读取x时,它会向Spanner发送一个读取X的请求,该请求指向X所在分区的领导者,所在分区的领导返回x的当前值,并同时对X设置一个锁。当然如果锁已经设置,那么在当前持有数据所的事务通过提交释放锁之前,它不会对客户端做出响应。接下来,y可能位于数据中心一,那么本地的数据中心领导节点将负责处理这次读取操作,因此速度会块。该读操作在Paxos领导节点上设置对y设置锁,随后返回。到此位置,客户端已经完成了所有读取操作,它进行了内部计算,并确定了想要执行的写入操作,即想要写入x和y的值。
接下来,客户端将要发送想要写入的更新值。它会在事务结束时一次性完成这些操作。
因此需要选取一个Paxos组作为事务协调者,必须这么做,提前选择并发出身份信息,即哪个Paxos组将充当事务协调者。
DC1 DC2 DC3
x x x
c
y y y
两阶段提交,因为其特性而广受诟病,因为一旦事务协调器发生故障,或变得无法访问,它所管理的任何事务都将无限期阻塞,直到事务协调器恢复运行,在此期间锁不会释放。因此人们在实际应用中普遍对使用两阶段提交持谨慎态度,因为它具有阻塞性。
Spanner通过复制事务管理器来解决这一问题。事务管理器本身是一个基于Paxos的事务管理机。比如记住是否已经提交,都会被复制到Paxos日志中,因此,如果这里的领导者发生故障,尽管它当时正在管理事务,但由于采用了raft的复制机制,这两个副本的任意一个都能够迅速激活,接管领导权,并同时接管事务管理职责。
只读事务
Spanner在其只读事务设计中,消除了两大成本,去除了读写事务中存在的两项成本,去除了读写事务中存在的两项成本。首先,它从本地副本中读取所需要的数据,即本地数据中心内的所需数据,这个过程只需要毫秒级的时间开销,相较之下,若需跨地域访问,则可能耗时数十毫秒。但是需要注意的是,这里的有一个风险,任何给定的副本可能不是最新的。因此这背后一定有一些机制。只读设计中的另一大优势是,它不使用锁。不适用面向提交,也不需要事务管理器。这样可以避免跨数据中心或数据中心向Paxos领导者的消息传递,由于无需获取锁,这不仅使得只读事务执行速度更快,还避免读写事务因等待只读事务持有的锁而导致延迟。
表三和表六显示只读事务相较于读写事务在延迟上提升了10倍。
外部一致性
实际上等同于先前所说的线性一致性。如果一个事务提交完成,而另一个事务在第一个事务完成后的时间开始,第二个事务必然能够看到第一个事务的写入操作。
快照隔离
安全事件
时钟同步
GPS卫星
WWB无限广播,用于广播当前事件
NTP时间