P13 Spanner
提供了针对分布范围很广的分离数据的分布式事务。
使用了两阶段提交 + paxos
架构
将数据拷贝存放至多个数据中心的原因
- 若一个城市供电故障了,可以使用其他城市的数据
- 能让靠近该数据中心的不同client去请求该数据中心的数据,网络传输距离减少。
两种挑战
- 想从本地数据中心中获取数据,但Paxos遵循大多数投票原则,本地数据中心数据可能有滞后。
- 一个事务可能会涉及到多个数据分片,即多个Paxos组,因此需要分布式事务。
读写型事务
Spanner 提供两阶段提交以及两阶段锁的支持,两阶段锁来获取有序性、两阶段提交来获得使用分布式事务的能力。
使用多台服务器组成的Paxos组来充当参与者和事务协调器的角色,来提高容错能力。
- client选择TID来给事务打标记
- 当client想进行读操作时,会先对数据分片所属的paxos组中的leader发送一个读请求,leader会返回x的当前值,并加锁。
- client获取到数据之后,会根据事务操作进行相对应的计算,后准备进行写回操作。
- 选择一个paxos组来作为事务协调器使用,并标明id
- client发送写请求给leader,请求中包含写的新值以及事务协调器的id
- 当每个组的leader都收到写请求时,会发送prepare消息给follower,并写入到日志中,当收到大多数follower的响应时,会发送yes给事务协调器。
- 当事务协调器收到该事务数据分片组所属的所有paxos组中leader(如何知道)的响应后,若均为yes则会提交这个事务。
- 事务协调器在commit请求安全落地到日志后,发送commit给自己的follower,以及其余paxos组的leader
- 执行写操作,并释放锁。
Spanner解决了事务协调者宕机造成block的问题,事务协调者所在paxos组中的任意一个follower都可以接收该工作。
网络消息较多,跨数据中心通信耗时较长
只读事务
读操作可以看到在它执行之前的那个事务的所有写操作所执行的结果。
获取外部一致性的能力
不能简单的读取最新的值
快照隔离
时间戳
读写事务:时间戳为提交时间
只读事务:时间戳为开始时间
拥有一个多版本的数据库,数据的每个副本与时间戳都是相关联的。
对于只读事务来说,会去访问数据库中该数据对象的多个版本,并去获取时间戳最高的那个版本,但这个时间戳要比只读事务的时间更低。
时钟同步
确保不同服务器所获得的时钟是同一个值。
只读事务的时间戳太大 —> 正确但是因为需要等待更新时间戳而缓慢
只读事务的时间戳太小 —> 违反外部一致性而不正确