BigTable、MegaStore、Spanner三个概念并行,有各自不同的应用场景
Spanner数据库最核心的贡献(个人感觉):True Time
细节描述链接:http://nil.csail.mit.edu/6.824/2020/notes/l-spanner.txt
在多个Data Center储存数据:
1、为了avaiability
2、为了快速相应,locality
读写,写写,读读等场景特性和设计要考虑的内容不一致,无论是单机数据库还是分布式数据库,都需要针对不同场景进行不同的考虑
同时会带来下面两个问题
1、因为paxos只要求一半以上的机器有记录,所以可能出现少部分机器信息延迟的问题,导致local无法读取最新的数据(for speed may fail to get latest)
2、执行一个事务可能会牵扯到多个shard,每个shard有多个分片,对应一个paxos group,操作比较麻烦
Read/Write transaction
涉及2-phase commit,2-phase locking
红色虚线标记的是一个shard的replica paxos group
一个框的是paxos group leader
两个框的是paxos group leader + transaction coordinator
执行流程
1、client发送请求给对应的paxos group leader, leader给对应数据加锁,并发送prepare信息给组员,一半以上组员回复ok后可以发送回复(对应paxos规则)给TC
2、TC收集齐回复后发送commit要求给leader,leader再次分发要求,一半以上执行完毕后返回ack
use 2-phase locking来保证serializability
人们不愿意用2-phase locking,因为如果TC崩溃的话会持续持有锁极大程度影响效率
Spanner解决方法:paxos group内部其他机器可以无缝替代leader
上图一大问题:大量信息跨data center远距离传递,传递一次花费ms单位
R/W事务执行起来流程太复杂太慢了,Read Only事务执行起来完全没必要这么麻烦
Read Only Transaction
读的时候不需要加锁,吞吐量增大10倍
依然需要满足:
1、Serializable
2、External Consistency(对应linearizable)
二者区别参考链接:
Spanner - External consistency - 知乎
关于Spanner中的TrueTime和Linearizability - 知乎
如果R O事务什么都不做,直接读最新的数据会发生什么
不管T3怎么排都无法获得serializable的数据(xy不是同一版本互相矛盾)
Spanner使用了类似MVCC的方法
设计时间戳标记每个事务
RW事务对应commit时间,RO事务对应start时间;
RW继续加锁和2-phase commit,RO直接读版本之前的信息
示例:
执行时间不一致,通过时间戳强行serializable
类似MVCC开始的View操作
问题:
Spanner让机器倾向于从local读取数据,如果读取的server不是majority而是少数,即没获得最新的数据怎么办呢?
Spanner引入了新机制,safe time
local进行delay,如果发现最新time stamp是13,则只有获得timestamp大于等于15的时候才会回答15的问题
新问题:各个机器的表不完全同步,不可能完全一致
What If Clock is not Synced?
RW事务没有任何影响,通过2-phase commit机制依然可以顺利执行
RO事务需要进行深入分析
时间戳太大时,需要等待log entry收到当前时间戳信息,正确但是太慢;
时间戳太小时,无法读到最新的内容,也与实际的serializable违背。
解决方法:通过GPS等机制广播通知当前时间
获得实时数据的示例图:
snapshot:快照机制