栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MIT6.824 Spanner论文精读

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MIT6.824 Spanner论文精读

文章目录
  • Introduction
  • Implementation
    • Spanserver Software Stack
    • Directories and Placement
    • Data Model
  • TrueTime
  • Concurrency Control
    • Timestamp Management
      • Paxos Leader Leases
      • Assigning Timestamps to RW Transactions
      • Serving Reads at a Timestamp
      • Assigning Timestamps to RO Transactions
    • Details
      • Read-Write Transactions
      • Read-Only Transactions
      • Refinements

Introduction

Spanner是Google的全球分布式数据库,它主要具有以下特点:

  • 可细粒度动态控制数据副本的配置,包括数据的分片方式,数据的迁移等。
  • 读和写操作的外部一致性
  • 一个时间戳下跨数据库的全球一致性读

Spanner能提供全球范围内的有序事务提交时间戳,而这个功能基于TrueTime API及其实现。

Implementation


一个Spanner的部署被称为一个universe,其包含如下部分:

  • universe master:管理和控制zone的状态和信息
  • placement driver:周期性和spanservers交互,发现需要转移、更新的数据。
  • 多个zone,每个zone代表了一个数据存储单元,其包含:
    • zonemaster:管理当前zone的spanservers(如分配数据)
    • spanserver:存储和提供数据
    • local proxy:给客户端定位提供数据的spanservers
Spanserver Software Stack


Spanserver的软件协议栈各部件功能如下:

  • tablet:spanserver中的数据结构,是一个具有版本的key-value条目,其形式为(key:string, timestamp:int64) -> string。tablet的状态存储在Colossus分布式文件系统当中,并且存储于类似B+树的文件和WAL中。
  • Paxos group:每个tablet运行在Paxos协议下,代表一份数据副本,Paxos协议的状态(如log等)也存储在tablet中。多个replica组成一个Paxos group,并有一个leader进行管理。
    • leader的选举租约为10s。
    • 写操作必须经过leader,并由Paxos保证半数复制,读操作可以直接访问最新的副本。
    • leader维护lock table,用于存储如2PL的锁状态。
    • leader拥有transaction manager,用于维护事务状态和事务并发控制。
  • participant leader:基于transaction manager创建,用于协调跨Paxos group的事务,以完成2PC事务提交。
Directories and Placement


Spanner中定义了directory的概念,它是数据放置的最小单位:

  • 每个Paxos group可拆成多个目录,每个目录由一系列共同前缀的键所对应的数据项组成(实际为将tablet进行划分)。
  • directory中的所有数据都具有相同的replication configuration。
  • 目录的replica在其所在的Paxos group中。
  • 目录可以转移到不同的Paxos group,以调整负载,转移操作可以在执行client operations时进行(50MB转移只需要几秒)。
  • Movedir background task用于在Paxos groups间转移目录。
  • 若一个目录过大,会被分片到不同的Paxos group,Movedir实际上移动的时分片而不是目录。
Data Model

Spanner的对外数据特征为:

  • schematized semi-relational tables:每个表的行都必须有名称,可定义外键和级联的关系。
  • a query language:一个查询语言(类SQL)。
  • general purpose transactions:通用的事务(基于2PC+2PL)

Spanner中的Data Model实例如下所示,其结构如下:

  • database由client分割成多个不同层级的hierarchy table(INTERLEAVE IN关键字)
  • 每个hierarchy table的top row为directory table,并包含key K。

TrueTime


TrueTime的实现机制:

  • 底层为GPS + atomic clock。 GPS可能会因为天线等故障出现误差,atomic clock可能会因为长时间使用导致的频率误差产生时钟漂移。
  • 每个datacenter中配置有多个time master
    • 一些使用GPS获取时间,一些使用atomic clock获取时间
    • time master之间互相校对时间,若差距过大则会将自己驱逐出去
  • 每个server中都有一个timeslave daemon
    • 每个server收集time master的时间,使用类Marzullo算法同步本地server时钟。
    • 考虑到延迟等影响,引入了时间误差 ϵ epsilon ϵ
Concurrency Control

基于TrueTime API实现了一个重要特性:在timestamp t时产生的读操作,会看到所有在t之前提交的事务。

Timestamp Management

Spanner支持以下几种读写事务:

  • Read-Write:使用pessimistic lock进行并发控制。
  • Read-Only
    • 必须声明不含写操作
    • 时间戳由leader决定,无锁,可在任何足够新的副本执行
  • Snapshot Read
    • 可读取历史数据,无锁
    • 时间由客户端决定,可以是时间戳,也可以是时间下限(由Spanner具体决定,满足条件即可)

Paxos Leader Leases

Paxos的leader租约具有以下特点:

  • leader lease的默认时间为10s
    • 成功执行一次写操作会延展leader lease
    • leader lease快到期前会申请延长
  • leader可主动放弃该身份
  • 不同leader的lease interval不同
  • 假设前一个leader使用过的最大时间戳为 s m a x s_{max} smax​,则下一个leader的租约起始时间必须满足 T T . a f t e r ( s m a x ) TT.after(s_{max}) TT.after(smax​)。
Assigning Timestamps to RW Transactions

读写事务需要依赖2PL。Spanner是用在提交事务时的Paxos写操作的时间戳作为事务时间戳。

Spanner提供了读写事务时间戳的两个保证,Paxos group内单调递增和外部一致性。

Paxos group内读写事务timestamp单调递增由以下机制保证:

  • leader不同租约区间互不相交
  • leader分配的时间戳只能在自己租约区间内

WR事务的外部一致性保证为:如果事务 T 2 T_2 T2​发生在事务 T 1 T_1 T1​提交之后,则事务 T 2 T_2 T2​的提交时间戳一定大于事务 T 1 T_1 T1​的提交时间戳,即 t a b s ( e 1 c o m m i t ) < t a b s ( e 2 c o m m i t ) ⇒ s 1 < s 2 t_{abs}(e_1^{commit}) < t_{abs}(e_2^{commit}) Rightarrow s_1 < s_2 tabs​(e1commit​)

其中一些记号标识说明如下:

  • e i s t a r t e_i^{start} eistart​:事务 T i T_i Ti​开始事件。
  • e i c o m m i t e_i^{commit} eicommit​:事务 T i T_i Ti​提交事件。
  • s i s_i si​:事务 T i T_i Ti​的commit timestamp。
  • s i s e r v e r s_i^{server} siserver​:coordinate leader收到commit request事件。

WR事务的外部一致性通过以下机制保证:

  • Start: s i s e r v e r ≤ s i s_i^{server} leq s_i siserver​≤si​。
  • Commit Wait: s i < t a b s ( e i c o m m i t ) s_i < t_{abs}(e_i^{commit}) si​

证明如下:

Serving Reads at a Timestamp

每个replica都会维护一个 t s a f e t_{safe} tsafe​,表示副本最近更新的最大时间戳,当读事务的时间戳为 t t t时,可以在满足 t ≤ t s a f e t leq t_{safe} t≤tsafe​的副本上读取且 t s a f e = m i n ( t s a f e P a x o s , t s a f e T M ) t_{safe}=min(t_{safe}^{Paxos},t_{safe}^{TM}) tsafe​=min(tsafePaxos​,tsafeTM​)。

t s a f e P a x o s t_{safe}^{Paxos} tsafePaxos​为Paxos write的最近事件, t s a f e T M t_{safe}^{TM} tsafeTM​为副本对应的transaction manager维护的安全时间,其具体取值如下:

  • 若当前Paxos group没有已经prepare但没commit的事务(即没夹在2PC中间阶段的事务),则 t s a f e T M = ∞ t_{safe}^{TM}= infty tsafeTM​=∞。
  • 若Paxos group中存在多个这种事务,则 t s a f e T M = m i n i ( s i , g p r e p a r e ) − 1 t_{safe}^{TM}=min_i(s_{i,g}^{prepare})-1 tsafeTM​=mini​(si,gprepare​)−1,其中 s i , g p r e p a r e s_{i,g}^{prepare} si,gprepare​为Paxos group leader为事务 T i T_i Ti​回复prepare消息的timestamp。
Assigning Timestamps to RO Transactions

只读事务分为两个阶段进行:

  • 由Paxos group leader分配一个timestamp s r e a d s_{read} sread​。
    • s r e a d s_{read} sread​的通常选择为 T T . n o w ( ) . l a t e s t TT.now().latest TT.now().latest
    • 若 t s a f e t_{safe} tsafe​不够大,可能需要阻塞,因此 s r e a d s_{read} sread​可能为一个满足外部一致性的最小时间戳
    • s r e a d s_{read} sread​也会增大 s m a x s_{max} smax​,保证不同leader lease不相交。
  • 进行 s r e a d s_{read} sread​的快照读,可在任何足够新的副本上读
Details Read-Write Transactions

Spanner在执行读写事务时:

  • 写入数据先缓存于client,直到提交,因此读操作不会受写操作影响
  • 读取时使用wound-wait机制避免死锁
  • 获取读锁然后读取up-to-date数据
  • 事务活跃时client向participant leader发送心跳包
  • 当client完成所有读操作和缓存所有写操作后,开始变种的2PC

Spanner中变种的2PC协议具体如下:

  • client完成了所有读操作并缓存需要写入内容后,开始进行2PC
  • client会选择一个coordinator group并向所有的participant leader发送写请求(包括coordinator leader),并捎带prepare请求
  • participant leader:
    • 先获取写锁
    • 给回复prepare这个事件赋上时间戳 s i p r e p a r e s_i^{prepare} siprepare​(此时更新了 t s a f e T M t_{safe}^{TM} tsafeTM​)
    • 使用Paxos持久化该事件,写入log(此时更新 t s a f e P a x o s ) t_{safe}^{Paxos}) tsafePaxos​)
    • 回复coordinator leader并携带 s i p r e p a r e s_i^{prepare} siprepare​
  • coordinator leader:
    • 先获取写锁,等待其它participant leader的prepare所有回复
    • 给提交事件附上时间戳 s s s,其需要满足:
      • s > m a x i ( s i p r e p a r e ) s > max_i(s_i^{prepare}) s>maxi​(siprepare​),保证 t s a f e T M t_{safe}^{TM} tsafeTM​的合理性
      • s > T T . n o w ( ) . l a t e s t s > TT.now().latest s>TT.now().latest,保证start阶段约束
    • 使用Paxos持久化该事件,写入log(此时更新 t s a f e P a x o s ) t_{safe}^{Paxos}) tsafePaxos​)
    • 等待 T T . a f t e r ( s ) TT.after(s) TT.after(s)成立,保证commit wait约束
    • 告知客户端 s s s,告知事务提交完成
    • 告知其它participant leader(捎带 s s s),让它们也提交事务(也使用Paxos写入提交事件),并释放锁
Read-Only Transactions

只读事务需要分为时间戳 s r e a d s_{read} sread​,具体原则如下:

  • 若read scope仅限于单Paxos group:
    • 给该组的leader发起只读事务
    • leader为只读事务分配时间戳 s r e a d = L a s t T S ( ) s_{read}=LastTS() sread​=LastTS(), L a s t T S ( ) LastTS() LastTS()为Paxos group最近一次的commit write timestamp
  • 若scope跨多Paxos group,有多种选择:
    • 协商各个组不同的 L a s t T S ( ) LastTS() LastTS()
    • 选择 T T . n o w ( ) . l a t e s t TT.now().latest TT.now().latest,但是可能需要等待 t s a f e t_{safe} tsafe​变大
Refinements

t s a f e T M t_{safe}^{TM} tsafeTM​存在的问题:当存在一个prepared但没commit的事务, t s a f e t_{safe} tsafe​无法变大,会阻塞 s r e a d > t s a f e s_{read}>t_{safe} sread​>tsafe​的读操作,即使可能并没有冲突。

解决方案:建立一个的映射关系,存储在lock table中,在进行读操作时,只检查产生lock confilict的 t s a f e t_{safe} tsafe​

L a s t T S ( ) LastTS() LastTS()存在的问题:当一个事务刚被提交,一个读请求时间戳必须跟在刚提交事务的后面,造成阻塞,即使读操作不会造成冲突

解决方案,建立一个的映射关系,存储在lock table中,在进行读操作时,只选择产生lock confilict的最大 L a s t T S ( ) LastTS() LastTS()。

t s a f e P a x o s t_{safe}^{Paxos} tsafePaxos​:没有发生Paxos write时, t s a f e P a x o s t_{safe}^{Paxos} tsafePaxos​无法变大,会造成读阻塞。
解决方案:每个Paxos group leader维护一个下一个Paxos write可能会发生的最小时间戳 M i n N e x t T S ( n ) MinNextTS(n) MinNextTS(n),并令 t s a f e P a x o s = M i n N e x t T S ( n ) − 1 t_{safe}^{Paxos}=MinNextTS(n) - 1 tsafePaxos​=MinNextTS(n)−1。注意, M i n N e x t T S ( n ) MinNextTS(n) MinNextTS(n)必须在租约内,且如果 M i n N e x t T S ( n ) MinNextTS(n) MinNextTS(n)超过了租约期需要先延长租约。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/931122.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号