java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2474|回复: 0

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

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

    [LV.Master]出神入化

    2025

    主题

    3683

    帖子

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    66151

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

    发表于 2017-3-4 14:06:55 | 显示全部楼层 |阅读模式
    7.3 Google Spanner
    ! k3 p# w: u  h. [Google Spanner是Google的全球级分布式数据库(Globally-Distributed
    # K1 e2 T& r3 DDatabase)。Spanner的扩展性达到了全球级,可以扩展到数百个数据中心,数百万
    % i$ T1 k+ D$ E台机器,上万亿行记录。更为重要的是,除了夸张的可扩展性之外,它还能通过同
    $ l" t  o! O+ m3 G步复制和多版本控制来满足外部一致性,支持跨数据中心事务。9 e; [+ s6 n2 q7 h
    无论从学术研究还是工程实践的角度看,Spanner都是一个划时代的分布式存储
    # C, x* F% O/ @3 e" H6 I! L) H0 f系统。Spanner的成功说明了一点,分布式技术能够和数据库技术有机地结合起来,2 E# t. @) U4 b) @' q6 D
    通过分布式技术实现高可扩展性,并呈现给使用者类似关系数据库的数据模型。1 Y' L+ c! C2 o! s* `1 h
    7.3.1 数据模型
    ' S; A$ N$ E1 N: i4 zSpanner的数据模型与6.2节中介绍的Megastore系统比较类似。0 M# o* @( H  W* D+ h5 p9 U
    如图7-6所示,对于一个典型的相册应用,需要存储其用户和相册,可以用上面  _0 w0 B! x+ r
    的两个SQL语句来创建表。Spanner的表是层次化的,最底层的表是目录表5 Y% D8 d) w: ^& f. z# N
    (Directorytable),其他表创建时,可以用INTERLEAVE IN PARENT来表示层次关
    , z- Q9 F" |2 s% z6 t系。Spanner中的目录相当于Megastore中的实体组,一个用户的信息(user_id,email)
      m9 E8 S% [) `& Y2 g( [7 c# u以及这个用户下的所有相片信息构成一个目录。实际存储时,Spanner会将同一个目" e% L, U4 v/ @; |  \  v: Y6 F
    录的数据存放到一起,只要目录不太大,同一个目录的每个副本都会分配到同一台
    + D3 K. G' y+ v: ~2 k机器。因此,针对同一个目录的读写事务大部分情况下都不会涉及跨机操作。
    * x# T7 g- ~6 Z$ Y: J- O2 G图 7-6 Spanner数据模型
    4 M6 j* V* X& u  e# F! ~! q9 R7.3.2 架构
    1 A  o4 w( I0 q3 ^8 x! l3 NSpanner构建在Google下一代分布式文件系统Colossus之上。Colossus是GFS的延
    ( D% X- t4 }  N: e# z0 X续,相比GFS,Colossus的主要改进点在于实时性,并且支持海量小文件。
    # r2 a! R7 F" d/ W3 g* [由于Spanner是全球性的,因此它有两个其他分布式存储系统没有的概念:/ U3 {4 ?) H& v/ ?/ Z( Z) i3 h
    ●Universe。一个Spanner部署实例称为一个Universe。目前全世界有3个,一个开, F& C5 o5 z* h: h
    发、一个测试、一个线上。Universe支持多数据中心部署,且多个业务可以共享同一
    6 Y% Y) X/ r  R个Universe。
    ( R9 P8 n2 `# [" k●Zones。每个Zone属于一个数据中心,而一个数据中心可能有多个Zone。一般
    6 \( j# E, i/ D. p来说,Zone内部的网络通信代价较低,而Zone与Zone之间通信代价很高。* w; H. A) w4 a( f7 w
    如图7-7所示,Spanner系统包含如下组件:; u3 l/ e' K% [$ a" t$ T6 B) U) R+ U1 V+ w
    图 7-7 Spanner整体架构7 x% W3 Y! V2 F; w2 a# @
    ●Universe Master:监控这个Universe里Zone级别的状态信息。* I7 e( \, s. y, |8 y2 K
    ●Placement Driver:提供跨Zone数据迁移功能。
    ' r- t! v9 k! ]+ G●Location Proxy:提供获取数据的位置信息服务。客户端需要通过它才能够知道6 S+ t5 b" \) [) [
    数据由哪台Spanserver服务。
    # K. v5 L, S- E2 q7 d+ t$ V●Spanserver:提供存储服务,功能上相当于Bigtable系统中的Tablet Server。0 w7 v1 d5 c; D
    每个Spanserver会服务多个子表,而每个子表又包含多个目录。客户端往Spanner
    3 L# k/ t3 V7 w  b( e7 D6 N0 K发送读写请求时,首先查找目录所在的Spanserver,接着从Spanserver读写数据。
    " H/ X) B  @7 z这里面有一个问题:如何存储目录与Spanserver之间的映射关系?假设每个用户
    ; w5 H# x* R# G4 {- d: i% |对应一个目录,全球总共有50亿用户,那么,映射关系的数据规模为几十亿到几百; _$ Q  n! b3 S! m5 Y) w% I* j
    亿,单台服务器无法存放。Spanner论文中没有明确说明,笔者猜测这里的做法和
    % s9 `' B6 m! W7 ]1 r: GBigtable类似,即将映射关系这样的元数据信息当成元数据表格,和普通用户表格采# w2 [4 e, O& k  [" O$ |& T
    取相同的存储方式。
    ! t+ I0 Z, Z7 P4 ?6 }+ L7.3.3 复制与一致性& R- i6 h) C6 ?% L% h( ?4 @
    如图7-8所示,每个数据中心运行着一套Colossus,每个机器有100~1000个子
    3 @5 t+ X9 f) p. Z表,每个子表会在多个数据中心部署多个副本。为了同步系统中的操作日志,每个
    " V# t  \" X- ~8 q2 ~子表上会运行一个Paxos状态机。Paxos协议会选出一个副本作为主副本,这个主副本' M# ]5 b' S5 X' v# o+ G2 F- d5 q
    的寿命默认是10秒。正常情况下,这个主副本会在快要到期的时候将自己再次选为8 [) X4 B' J. y/ b7 J* X. ^" f
    主副本;如果出现异常,例如主副本所在的spanserver宕机,其他副本会在10秒后通
    ! p+ V/ Y1 L9 M1 S+ x1 h& c: Z过Paxos协议选举为新的主副本。
    $ Y1 y% O+ V9 i: t  z图 7-8 Spanner多集群复制
    3 v9 {. {8 [+ Q5 `9 m! S+ N通过Paxos协议,实现了跨数据中心的多个副本之间的一致性。另外,每个主副
    * t0 G- i& p) d  t; W- I本所在的Spanserver还会实现一个锁表用于并发控制,读写事务操作某个子表上的目
    7 v" X1 ?7 Z  {录时需要通过锁表避免多个事务之间互相干扰。( G  i4 u# T5 @" B- c
    除了锁表,每个主副本上还有一个事务管理器。如果事务在一个Paxos组里面," b- U& f1 O. s: z" }5 Y$ v0 T
    可以绕过事务管理器。但是一旦事务跨多个Paxos组,就需要事务管理器来协调。2 @$ ?; e3 I! D3 Q- x2 F* y# g- V
    锁表实现单个Paxos组内的单机事务,事务管理器实现跨多个Paxos组的分布式事4 I# B- n- u. t1 `7 U
    务。为了实现分布式事务,需要实现3.7.1节中提到的两阶段提交协议。有一个Paxos
    9 p2 J! N1 N- y, ^/ [) `组的主副本会成为两阶段提交协议中的协调者,其他Paxos组的主副本为参与者。3 Y* V# b- G' `3 s0 |
    7.3.4 TrueTime
    & [" P! s( H& Q5 s: ?4 W4 e+ X; A5 b$ ?为了实现并发控制,数据库需要给每个事务分配全局唯一的事务id。然而,在分; }) D8 L: E: q) X; F
    布式系统中,很难生成全局唯一id。一种方式是采用Google Percolator(Google
    % r/ U5 d2 o1 A5 I" eCaffeine的底层存储系统)中的做法,即专门部署一套Oracle数据库用于生成全局唯# m. s9 ]; ]+ f4 e  V/ W; D% ]
    一id。虽然Oracle逻辑上是一个单点,但是实现的功能单一,因而能够做得很高效。
    ( E* M3 ^# d, x0 K1 XSpanner选择了另外一种做法,即全球时钟同步机制TrueTime。3 I9 }7 c: Y) Y
    TrueTime是一个提供本地时间的接口,但与Linux上的gettimeofday接口不一样的
    # d$ s4 Y& {# M0 N是,它除了可以返回一个时间戳t,还会给出一个误差e。例如,返回的时间戳是20点
    - G' ~) G4 n% \+ X! K+ M+ H4 A* }23分30秒100毫秒,而误差是5毫秒,那么真实的时间在20点23分30秒95毫秒到105毫) J4 h+ H9 ?) i6 Q7 k) r. o0 F
    秒之间。真实的系统e平均下来只有4毫秒。* }( n1 U0 |; J8 Y4 M) J
    TrueTime API实现的基础是GPS和原子钟。之所以要用两种技术来处理,是因为
    8 a' W) s) x$ i- S4 D: l导致这两种技术失效的原因是不同的。GPS会有一个天线,电波干扰会导致其失灵。
    7 r7 J3 m; L, J原子钟很稳定。当GPS失灵的时候,原子钟仍然能保证在相当长的时间内,不会出现/ n' l, a; I/ c4 m( q* `5 i- q
    偏差。8 T. I# e4 r$ Y0 F0 d
    每个数据中心需要部署一些主时钟服务器(Master),其他机器上部署一个从时9 c  P* I  w: j5 E1 r+ U+ b
    钟进程(Slave)来从主时钟服务器同步时钟信息。有的主时钟服务器用GPS,有的
    , E) F8 V" `5 y1 z' f3 N主时钟服务器用原子钟。每个从时钟进程每隔30秒会从若干个主时钟服务器同步时
    2 }; J# y; I+ E% {2 v钟信息。主时钟服务器自己还会将最新的时间信息和本地时钟比对,排除掉偏差比* b$ e7 J9 |9 y8 H# X5 k
    较大的结果。
    , T+ l9 C, @1 G7 d% A2 [7.3.5 并发控制4 K8 _; {; n0 i7 u
    Spanner使用TrueTime来控制并发,实现外部一致性,支持以下几种事务:- V( G$ t) ~) r8 E
    ●读写事务5 p7 j: Q% X3 Y. K' e3 E5 C
    ●只读事务
    ; Q& i( B& Z4 I. o! s- s" A3 F  m●快照读,客户端提供时间戳3 m$ r6 D3 a; i# z
    ●快照读,客户端提供时间范围; n6 A( Y/ t& R# A& z: ?3 \# Y
    1.不考虑TrueTime0 d8 u: m) r0 w
    首先,不考虑TrueTime的影响,也就是说,假设TrueTime API获得的时间是精确; M$ Q7 A8 G( M4 v% l# `
    的。如果事务读写的数据只属于同一个Paxos组,那么,每个读写事务的执行步骤如
    ) G9 i5 b  V) S, q" d% F下:1 }$ I- R( k4 e2 b  H
    1)获取系统的当前时间戳;6 Z. \" ?: |% D2 O
    2)执行读写操作,并将第1步取得的时间戳作为事务的提交版本。
    & c, s5 w6 u# a  e  {/ j3 W# E6 N! I每个只读事务的执行步骤如下:
    + b% _" l( ^# y+ y' s1)获取系统的当前时间戳,作为读事务的版本;, R  a  i, |$ {
    2)执行读取操作,返回客户端所有提交版本小于读事务版本的事务操作结果。3 F( z" b* e( m: J+ E4 ^& o
    快照读和只读事务的区别在于:快照读将指定读事务的版本,而不是取系统的
    . h1 V, l' g: T- f当前时间戳。- T8 s* w, O5 k! D0 ?
    如果事务读写的数据涉及多个Paxos组,那么,对于读写事务,需要执行一次两+ c' z) H% }$ c$ Y. R: Z% S3 V2 v
    阶段提交协议,执行步骤如下:
    ; c( {# F' k  d+ `* \% \1)Prepare:客户端将数据发往多个Paxos组的主副本,同时,协调者主副本发9 H) w0 j: l+ I6 |2 q8 C; a. t
    起prepare协议,请求其他的参与者主副本锁住需要操作的数据。) G0 X5 m  x5 N1 g* Y
    2)Commit:协调者主副本发起Commit协议,要求每个参与者主副本执行提交操
      \8 Z9 j' l  U1 w! e% L! [作并解除Prepare阶段锁定的数据。协调者主副本可以将它的当前时间戳作为该事务
    1 R& Q) Q( {% G7 {1 K- H1 V的提交版本,并发送给每个参与者主副本。
    % ~% r( l& ]7 L' y/ J  \1 \只读事务读取每个Paxos组中提交版本小于读事务版本的事务操作结果。需要注% a" b/ `# `" @, @
    意的是,只读事务需要保证不会读到不完整的事务。假设有一个读写事务修改了两
    ( C: P. n1 v, q. n$ l个Paxos组:Paxos组A和Paxos组B,Paxos组A上的修改已提交,Paxos组B上的修改还未
    0 T; L! {8 s) l3 N4 b) `提交。那么,只读事务会发现Paxos组B处于两阶段提交协议中的Prepare阶段,需要
    7 l& f7 B. S. h% S0 n4 J, s+ [等待一会,直到Paxos组B上的修改生效后才能读到正确的数据。, e1 K8 _3 j. e3 A# I
    2.考虑TrueTime
    $ @+ O' q8 g8 E7 ~' {+ _如果考虑TrueTime,并发控制变得复杂。这里的核心思想在于,只要事务T1的
    7 I2 w' ]. t7 S: e6 C3 J+ J8 d提交操作早于事务T2的开始操作,即使考虑TrueTime API的误差因素(-e到+e之间,( D3 H/ z+ B0 R7 G4 v3 m
    e值平均为4ms),Spanner也能保证事务T1的提交版本小于事务T2的提交版本。
    , k0 ]6 C. z! ^0 tSpanner使用了一种称为延迟提交(Commit Wait)的手段,即如果事务T1的提交版本$ {* _( B$ U" J
    为时间戳t commit ,那么,事务T1会在t commit +e之后才能提交。另外,如果事务T2开始/ ^( m/ ^* u4 [& m  c) e
    的绝对时间为t abs ,那么事务T2的提交版本至少为t abs +e。这样,就保证了事务T1和T2
    2 E" y  p  h; d1 E- T之间严格的顺序,当然,这也意味着每个写事务的延时至少为2e。从这一点也可以
    9 ~# R$ F& L# A2 A9 \. R+ [" h看出,Spanner实现功能完备的全球数据库是付出了一定代价的,设计架构时不能盲) C2 d. B& A& z6 [8 k
    目崇拜。6 B8 R9 z7 N% I
    7.3.6 数据迁移( R- S& h6 Y( L6 Q* e+ O7 h
    目录是Spanner中对数据分区、复制和迁移的基本单位,用户可以指定一个目录1 t- J( w6 i# h+ T8 B
    有多少个副本,分别存放在哪些机房中,例如将用户的目录存放在这个用户所在地
    . G+ T- u, T. u5 `! e1 \区附近的几个机房中。& Z- U) b" h+ v) C" {5 ~
    一个Paxos组包含多个目录,目录可以在Paxos组之间移动。Spanner移动一个目
    6 X0 u( `7 M& U4 h9 g2 J$ |录一般出于以下几种考虑:
    ! b& `4 y4 W& C& ~, ~- e7 H. R3 `6 V5 T●某个Paxos组的负载太大,需要切分;6 D; F' n9 i% H. F- R, c, b
    ●将数据移动到离用户更近的地方,减少访问延时;1 |& n5 Q- j+ R5 Y3 \3 C3 a4 ^
    ●把经常一起访问的目录放进同一个Paxos组。8 L+ c9 w4 |& c7 M: J
    移动目录的操作在后台进行,不影响前台的客户端读写操作。一般来说,移动* d# A* M& [1 f1 B' D( a1 n+ m
    一个50MB的目录大约只需要几秒钟时间。实现时,首先将目录的实际数据移动到指
    ; _6 v/ P6 W6 U4 g/ E定位置,然后再用一个原子操作更新元数据,从而完成整个移动过程。
    % x& k( ]* F/ p7 @; E7.3.7 讨论$ `" E' ?, r! E
    Google的分布式存储系统一步步地从Bigtable到Megastore,再到Spanner,这也印
    5 f+ O1 Q7 v  O证了分布式技术和传统关系数据库技术融合的必然性,即底层通过分布式技术实现" T+ a7 A3 _$ y, e- k2 I  }3 {
    可扩展性,上层通过关系数据库的模型和接口将系统的功能暴露给用户。
    ' m/ k+ G* S2 s2 @0 b2 f阿里巴巴的OceanBase系统在设计之初就考虑到这两种技术融合的必然性,因* G4 j% J2 w: t+ w0 l
    此,一开始就将系统的最终目标定为:可扩展的关系数据库。目前,OceanBase已经
    $ L( R. a: r+ L开发完成了部分功能并在阿里巴巴各个子公司获得广泛的应用。本书第三篇将详细9 V0 K9 ]( h7 j( K
    介绍OceanBase的技术细节。& i1 N7 U3 t2 @# Z/ |# z
    1 L* X+ p/ A; K
    6 k9 W; j, x6 X: k
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-6-16 05:58 , Processed in 0.060044 second(s), 29 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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