java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2406|回复: 0

《大规模分布式存储系统》第7章 分布式数据库【7.3】

[复制链接]
  • TA的每日心情
    开心
    2021-5-25 00:00
  • 签到天数: 1917 天

    [LV.Master]出神入化

    2025

    主题

    3683

    帖子

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    66101

    宣传达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2017-3-4 14:06:55 | 显示全部楼层 |阅读模式
    7.3 Google Spanner
    5 ^* T: Z8 e9 T* D' }/ I% cGoogle Spanner是Google的全球级分布式数据库(Globally-Distributed5 a: W% _, y6 f) ^2 y& @2 N' t
    Database)。Spanner的扩展性达到了全球级,可以扩展到数百个数据中心,数百万% \/ d- G. i6 D# V
    台机器,上万亿行记录。更为重要的是,除了夸张的可扩展性之外,它还能通过同
    " I% {0 I3 Q; G! d, i2 c8 g步复制和多版本控制来满足外部一致性,支持跨数据中心事务。& {0 L& a( }5 j* a5 H
    无论从学术研究还是工程实践的角度看,Spanner都是一个划时代的分布式存储
    ' B$ I- X' X" @- ^系统。Spanner的成功说明了一点,分布式技术能够和数据库技术有机地结合起来,
    ! ^+ ^2 F) b3 {/ t9 _6 m3 {$ n通过分布式技术实现高可扩展性,并呈现给使用者类似关系数据库的数据模型。. Z( j" L8 @5 Q6 `+ `* M# `
    7.3.1 数据模型  v% i5 F. U4 S9 O' [8 e
    Spanner的数据模型与6.2节中介绍的Megastore系统比较类似。$ a/ j5 E0 c  b$ D$ K
    如图7-6所示,对于一个典型的相册应用,需要存储其用户和相册,可以用上面
    6 q8 T' Q4 d8 z  h: X1 y( }/ e; X的两个SQL语句来创建表。Spanner的表是层次化的,最底层的表是目录表
    & \9 d: p. P+ Q, C' U3 F(Directorytable),其他表创建时,可以用INTERLEAVE IN PARENT来表示层次关8 M$ h& o. z& P) ?/ [" E# D
    系。Spanner中的目录相当于Megastore中的实体组,一个用户的信息(user_id,email)$ m3 j+ P+ E& k6 }$ h9 f
    以及这个用户下的所有相片信息构成一个目录。实际存储时,Spanner会将同一个目
    1 P6 N% @- T' }3 e! p9 {- b3 m录的数据存放到一起,只要目录不太大,同一个目录的每个副本都会分配到同一台( x$ Q) {- u8 Q
    机器。因此,针对同一个目录的读写事务大部分情况下都不会涉及跨机操作。
    : {8 {- d9 \( ?4 q! d图 7-6 Spanner数据模型1 R# n! X- m$ n( A. r  f
    7.3.2 架构) a. |3 O$ j' B( M
    Spanner构建在Google下一代分布式文件系统Colossus之上。Colossus是GFS的延
    / T" G/ ~6 h* A! @  y- y% Y. F续,相比GFS,Colossus的主要改进点在于实时性,并且支持海量小文件。
    + {/ @; \) X2 m7 q+ p1 W由于Spanner是全球性的,因此它有两个其他分布式存储系统没有的概念:$ o9 ~' p+ g' }7 M7 \, L
    ●Universe。一个Spanner部署实例称为一个Universe。目前全世界有3个,一个开0 B$ ]; o" ?& d) c5 O/ |- t7 T- \
    发、一个测试、一个线上。Universe支持多数据中心部署,且多个业务可以共享同一6 x$ u+ Q: S4 Q* g: w- o6 u- b' k
    个Universe。, T" }. o" n, t3 z4 q
    ●Zones。每个Zone属于一个数据中心,而一个数据中心可能有多个Zone。一般1 U6 {+ n$ s, t# a3 I
    来说,Zone内部的网络通信代价较低,而Zone与Zone之间通信代价很高。: q+ v/ |  O- }
    如图7-7所示,Spanner系统包含如下组件:
    : O& C, c; k  Y$ y+ _9 q图 7-7 Spanner整体架构2 S; @+ a5 U( k2 ^; h/ V8 y3 f
    ●Universe Master:监控这个Universe里Zone级别的状态信息。
    $ ^% e6 n- A% e- _' i●Placement Driver:提供跨Zone数据迁移功能。0 e, C" T" O) L9 R3 _, z! X# U
    ●Location Proxy:提供获取数据的位置信息服务。客户端需要通过它才能够知道
    7 Y9 D% l3 R( `; q8 ^% ?% ?数据由哪台Spanserver服务。4 W" U7 ~2 y7 }& L/ I5 X. X
    ●Spanserver:提供存储服务,功能上相当于Bigtable系统中的Tablet Server。* b" f* t6 ]0 _- k' ]* v+ S
    每个Spanserver会服务多个子表,而每个子表又包含多个目录。客户端往Spanner+ R" k8 b! T+ u# Z% g, N
    发送读写请求时,首先查找目录所在的Spanserver,接着从Spanserver读写数据。
    + L, s2 h/ i$ M' Y$ q+ o- x5 O# V这里面有一个问题:如何存储目录与Spanserver之间的映射关系?假设每个用户( b6 f! X- x# D0 H0 ?$ J0 c
    对应一个目录,全球总共有50亿用户,那么,映射关系的数据规模为几十亿到几百/ G* v9 F  ]  P" }
    亿,单台服务器无法存放。Spanner论文中没有明确说明,笔者猜测这里的做法和
    , _  i! y. y1 P! Q5 pBigtable类似,即将映射关系这样的元数据信息当成元数据表格,和普通用户表格采2 M" o) \' W% ]+ |
    取相同的存储方式。! j% s+ b, Q8 Y
    7.3.3 复制与一致性  z2 V, f* \- z+ F. z4 \
    如图7-8所示,每个数据中心运行着一套Colossus,每个机器有100~1000个子
    # @: d. y- f2 u( g表,每个子表会在多个数据中心部署多个副本。为了同步系统中的操作日志,每个
    + T. m- a7 Q9 A$ v& @子表上会运行一个Paxos状态机。Paxos协议会选出一个副本作为主副本,这个主副本% l  E# `5 A; d; e1 ]
    的寿命默认是10秒。正常情况下,这个主副本会在快要到期的时候将自己再次选为& [7 m0 I5 c3 }0 H
    主副本;如果出现异常,例如主副本所在的spanserver宕机,其他副本会在10秒后通" m& g% c3 Q5 K
    过Paxos协议选举为新的主副本。
    , ]9 j% A# A2 |% f5 Z3 V图 7-8 Spanner多集群复制
    3 Q/ e. n' t- L/ l) y通过Paxos协议,实现了跨数据中心的多个副本之间的一致性。另外,每个主副
    / K4 l$ G/ i; I" m/ u& c' F0 e' Y本所在的Spanserver还会实现一个锁表用于并发控制,读写事务操作某个子表上的目1 @2 I* O5 m  Y: K3 m* n7 @3 B5 ~
    录时需要通过锁表避免多个事务之间互相干扰。. L) S* L6 j; x) T
    除了锁表,每个主副本上还有一个事务管理器。如果事务在一个Paxos组里面,
    6 f1 c7 m/ \4 B$ m可以绕过事务管理器。但是一旦事务跨多个Paxos组,就需要事务管理器来协调。
    ' _: @, L) h: Y( k9 s- u锁表实现单个Paxos组内的单机事务,事务管理器实现跨多个Paxos组的分布式事
    6 |4 ~* H  M# r* C务。为了实现分布式事务,需要实现3.7.1节中提到的两阶段提交协议。有一个Paxos
    # ?5 @: @* C$ i: Y6 l  j+ }0 M组的主副本会成为两阶段提交协议中的协调者,其他Paxos组的主副本为参与者。/ s9 O2 G+ B" m- O* A8 k
    7.3.4 TrueTime& ?; I; f9 w* L5 z0 m  M% `
    为了实现并发控制,数据库需要给每个事务分配全局唯一的事务id。然而,在分
    3 E& P. k1 T& l5 ]  A: z- X# G布式系统中,很难生成全局唯一id。一种方式是采用Google Percolator(Google  P- z8 r0 s1 m/ g0 [+ p
    Caffeine的底层存储系统)中的做法,即专门部署一套Oracle数据库用于生成全局唯
    8 U6 z; g$ e8 K# K一id。虽然Oracle逻辑上是一个单点,但是实现的功能单一,因而能够做得很高效。
    ' s/ [4 F( n% c0 Y: m  fSpanner选择了另外一种做法,即全球时钟同步机制TrueTime。
    + b; E" x! ~5 ^4 n4 `: gTrueTime是一个提供本地时间的接口,但与Linux上的gettimeofday接口不一样的
    6 M  p1 s* D+ n& E: M是,它除了可以返回一个时间戳t,还会给出一个误差e。例如,返回的时间戳是20点7 r+ ]) k1 a" c
    23分30秒100毫秒,而误差是5毫秒,那么真实的时间在20点23分30秒95毫秒到105毫
    - |4 X) o6 q' s+ j秒之间。真实的系统e平均下来只有4毫秒。
    . }! ?# ~6 N' p/ U5 R! hTrueTime API实现的基础是GPS和原子钟。之所以要用两种技术来处理,是因为8 q( @: \1 [6 b$ B9 y
    导致这两种技术失效的原因是不同的。GPS会有一个天线,电波干扰会导致其失灵。
    8 d* y" N8 V" }  V( @/ w; A原子钟很稳定。当GPS失灵的时候,原子钟仍然能保证在相当长的时间内,不会出现+ {" y1 \) C! P, a* I  r
    偏差。- O* g1 l+ A2 N, V8 m9 I8 b' D
    每个数据中心需要部署一些主时钟服务器(Master),其他机器上部署一个从时
    * ~4 d2 q" m/ v- \/ L5 `8 c钟进程(Slave)来从主时钟服务器同步时钟信息。有的主时钟服务器用GPS,有的
    , q2 T; d' j, P' h* g9 c主时钟服务器用原子钟。每个从时钟进程每隔30秒会从若干个主时钟服务器同步时/ m  W) E- S+ l. _
    钟信息。主时钟服务器自己还会将最新的时间信息和本地时钟比对,排除掉偏差比9 G2 G) y8 I. Q
    较大的结果。
    9 t) m- Y& w" P% C* _/ e& L7.3.5 并发控制, M! a+ C: g7 m( d
    Spanner使用TrueTime来控制并发,实现外部一致性,支持以下几种事务:
    4 U  b) l% s" V0 P& c; f' ]" c●读写事务
    # H0 V* v9 _2 n# F! f7 O& ~2 O●只读事务2 _% m' _, {  X+ D( U3 E7 m$ @
    ●快照读,客户端提供时间戳
    + O0 q! g# L# |1 W2 S7 y, C●快照读,客户端提供时间范围9 I* B, G1 l( R& I5 D/ \4 ~' v
    1.不考虑TrueTime# G& Y/ ]0 ~* Q* R' r2 P1 A# p
    首先,不考虑TrueTime的影响,也就是说,假设TrueTime API获得的时间是精确' l. e& ]( ^* x6 p$ h
    的。如果事务读写的数据只属于同一个Paxos组,那么,每个读写事务的执行步骤如' W; [& v/ \1 U4 p+ U0 l' s% D
    下:
    3 s- P8 o# k& Q3 u1 r2 {( m# r1)获取系统的当前时间戳;- P) e+ ]+ s- q2 V0 E
    2)执行读写操作,并将第1步取得的时间戳作为事务的提交版本。
    * a1 Q& X$ ?$ L: _' Z+ v# `5 ^每个只读事务的执行步骤如下:# \. K/ o! P1 w( S! p: X& }6 j2 U
    1)获取系统的当前时间戳,作为读事务的版本;
    ! ~6 R4 J3 C8 O6 H# z2)执行读取操作,返回客户端所有提交版本小于读事务版本的事务操作结果。- ?* o. ^( x4 S& O- C: _' Z
    快照读和只读事务的区别在于:快照读将指定读事务的版本,而不是取系统的% D) I! H& t2 F/ q8 Q
    当前时间戳。3 X: K5 v* Y! Q; ]; r+ ^
    如果事务读写的数据涉及多个Paxos组,那么,对于读写事务,需要执行一次两5 o5 |4 ]  N' d! S
    阶段提交协议,执行步骤如下:
    , y) b# L2 Q. h1)Prepare:客户端将数据发往多个Paxos组的主副本,同时,协调者主副本发" ^) B/ s7 @' S' u
    起prepare协议,请求其他的参与者主副本锁住需要操作的数据。
    1 n* r. l! ?9 ?3 c; e3 i2)Commit:协调者主副本发起Commit协议,要求每个参与者主副本执行提交操. R3 Z% e! ^. R9 |& r
    作并解除Prepare阶段锁定的数据。协调者主副本可以将它的当前时间戳作为该事务/ D" U3 q- z' b9 i4 N: L
    的提交版本,并发送给每个参与者主副本。6 m$ i% A! h* v( Z3 t
    只读事务读取每个Paxos组中提交版本小于读事务版本的事务操作结果。需要注3 X$ o' F9 F7 k: k. i; _
    意的是,只读事务需要保证不会读到不完整的事务。假设有一个读写事务修改了两3 V' I8 P( _( ^& y% ~9 o
    个Paxos组:Paxos组A和Paxos组B,Paxos组A上的修改已提交,Paxos组B上的修改还未
    6 N! `/ k- g. P: ~( i提交。那么,只读事务会发现Paxos组B处于两阶段提交协议中的Prepare阶段,需要  v7 S# O$ \) H/ X, v& v) {
    等待一会,直到Paxos组B上的修改生效后才能读到正确的数据。- ~, Y4 L6 F- @/ q% g# K
    2.考虑TrueTime2 |+ M! p( V0 U1 C8 j
    如果考虑TrueTime,并发控制变得复杂。这里的核心思想在于,只要事务T1的7 T9 D3 g# d* \4 q7 ^
    提交操作早于事务T2的开始操作,即使考虑TrueTime API的误差因素(-e到+e之间,* R9 T) r/ x2 D
    e值平均为4ms),Spanner也能保证事务T1的提交版本小于事务T2的提交版本。
    ' t* {! r6 u. O1 N+ r" n& s1 ~Spanner使用了一种称为延迟提交(Commit Wait)的手段,即如果事务T1的提交版本
    7 K; `' l+ W2 M  e9 b, O9 S, L为时间戳t commit ,那么,事务T1会在t commit +e之后才能提交。另外,如果事务T2开始+ \. a3 G8 ]5 s4 i1 v% u' `
    的绝对时间为t abs ,那么事务T2的提交版本至少为t abs +e。这样,就保证了事务T1和T2. r4 x4 v' @) H3 d
    之间严格的顺序,当然,这也意味着每个写事务的延时至少为2e。从这一点也可以
    % a' y  g7 L. H" s看出,Spanner实现功能完备的全球数据库是付出了一定代价的,设计架构时不能盲! |4 g0 ]& H" o( l/ m+ t
    目崇拜。
    5 e* f7 S! j/ @7.3.6 数据迁移# d! R9 W1 ]# p0 C6 |
    目录是Spanner中对数据分区、复制和迁移的基本单位,用户可以指定一个目录% I" k: z1 f1 F) a1 l
    有多少个副本,分别存放在哪些机房中,例如将用户的目录存放在这个用户所在地
    ! A/ _9 j( t2 }2 I* A3 E- g区附近的几个机房中。
    % {* k' \* A5 k7 J9 Y! C一个Paxos组包含多个目录,目录可以在Paxos组之间移动。Spanner移动一个目+ v! M/ f; {' ]8 d8 p; X4 X
    录一般出于以下几种考虑:* S4 X5 A* B) A% {2 z
    ●某个Paxos组的负载太大,需要切分;
    / L% E" d+ n, U' v8 H7 w+ J. G●将数据移动到离用户更近的地方,减少访问延时;* x/ ^# d3 j  G$ c' b6 K
    ●把经常一起访问的目录放进同一个Paxos组。
    # ?! g1 u' T! |8 _移动目录的操作在后台进行,不影响前台的客户端读写操作。一般来说,移动
    0 Z3 @  u5 T, o  Z# |4 T2 n6 z5 M' S一个50MB的目录大约只需要几秒钟时间。实现时,首先将目录的实际数据移动到指
    ' }2 j; r8 d4 m5 `  ]6 e& `( o定位置,然后再用一个原子操作更新元数据,从而完成整个移动过程。
    + T8 k* Z5 h! ?: ?6 y/ A7.3.7 讨论- d% b4 ]7 K+ E( M* ?6 o. ?
    Google的分布式存储系统一步步地从Bigtable到Megastore,再到Spanner,这也印6 r  e& C/ u6 @+ N" q1 ?0 K- `1 D
    证了分布式技术和传统关系数据库技术融合的必然性,即底层通过分布式技术实现5 S! B& V( V% P
    可扩展性,上层通过关系数据库的模型和接口将系统的功能暴露给用户。9 w6 q5 a; v2 u- u+ U( _* e
    阿里巴巴的OceanBase系统在设计之初就考虑到这两种技术融合的必然性,因
    $ Q! a  y1 v- H. G* Q此,一开始就将系统的最终目标定为:可扩展的关系数据库。目前,OceanBase已经/ ]) e  t8 Q) _: l
    开发完成了部分功能并在阿里巴巴各个子公司获得广泛的应用。本书第三篇将详细" d% S' P, I! u8 a
    介绍OceanBase的技术细节。
    / C( P% h, x; u5 h& n6 c: e9 n4 O/ R* ^2 c8 e- R2 U# f3 G7 a2 b

    ; ?: a- T, H2 l4 [0 g
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|Java自学网

    GMT+8, 2024-4-29 07:20 , Processed in 0.115435 second(s), 31 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

    快速回复 返回顶部 返回列表