java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2485|回复: 0

《大规模分布式存储系统》第10章 数据库功能【10.4】

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

    [LV.Master]出神入化

    2096

    主题

    3754

    帖子

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    66788

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

    发表于 2017-3-10 13:50:05 | 显示全部楼层 |阅读模式
    10.4 OLAP业务支持0 D8 r' p6 @* z7 r
    OLAP业务的特点是SQL每次执行涉及的数据量很大,需要一次性分析几百万行7 N% d. C8 x- @
    甚至几千万行的数据。另外,SQL执行时往往只读取每行的部分列而不是整行数据。
    3 G0 t- d& E# x9 N# W8 B5 a) a为了支持OLAP计算,OceanBase实现了两个主要功能:并发查询以及列式存8 _! V9 l; |! t
    储。并行查询功能允许将SQL请求拆分为多个子请求同时发送给多台机器并发执行,; j; N2 S( X2 M6 S1 H
    列式存储能够提高压缩率,大大降低SQL执行时读取的数据量。本节首先介绍并发查
    , i; n* j4 R4 k1 p" R* |询功能,接着介绍OceanBase的列式存储引擎。) f% o1 h: k/ i* w7 Q0 i
    10.4.1 并发查询
    $ s' c9 B6 p9 p. E/ u2 `如图10-13所示,MergeServer将大请求拆分为多个子请求,同时发往每个子请求1 c5 s" _8 n9 P
    所在的ChunkServer并发执行,每个ChunkServer执行子请求并将部分结果返回给
    # t, }1 s- T% R1 a# w: L/ `3 w) b) h. fMergeServer。MergeServer合并ChunkServer返回的部分结果并将最终结果返回给客户6 w8 |* \! z3 w5 Y9 i, z+ [
    端。4 K/ k& D3 V" Z, g, F* o: V
    图 10-13 OceanBase并发查询
    / R2 t8 c" P5 w+ DMergeServer并发查询执行步骤如下:. ]7 \' u" h! Y$ E: v( ?
    1)MergeServer解析SQL语句,根据本地缓存的子表位置信息获取需要请求的& n- m/ e7 N# [
    ChunkServer。
    ( |+ ]4 G9 M( s# e( O2)如果请求只涉及一个子表,将请求发送给该子表所在的ChunkServer执行;如
    % z# C+ D0 U  C8 \8 ^/ n9 X: e果请求涉及多个子表,将请求按照子表拆分为多个子请求,每个子请求对应一个子
    1 c5 [' P' b( r6 `0 E/ d表,并发送给该子表所在的ChunkServer并发执行。MergeServer等待每个子请求的返
    ; p- g/ ]* U' K( y- j$ o回结果。
    " ~' x* I3 R. c' y3)ChunkServer执行子请求,计算子请求的部分结果。SQL执行遵从10.2.4节提( J' ^% ]1 {% t0 T$ U. c" w
    到的本地化原则,即能让ChunkServer执行的尽量让ChunkServer执行,包括Filter、1 z& I- X& l% O( y
    Project、子请求部分结果的GroupBy、OrderBy、聚合运算等。
    8 \4 w# P; b4 Y/ I# j' @% j4)每个子请求执行完成后,ChunkServer将执行结果回复MergeServer,Merge-9 c, S* h; `1 _
    Server首先将每个子请求的执行结果保存起来。如果某个子请求执行失败,1 u7 [" w  D3 H% w1 o( c7 S
    MergeServer会将该子请求发往子表其他副本所在的ChunkServer执行。
    & z( _  E6 p4 T( }! t% J5)等到所有的子请求执行完成后,MergeServer会对全部数据排序、分组、聚合" s- d3 V; y6 u5 c
    并将最终结果返回给客户。OceanBase还支持批量读取(multiget)操作一次性读取多" v8 U: A* B5 t% Y7 J% O3 D
    行数据,且读取的数据可能在不同的ChunkServer上。对于这样的操作,MergeServer8 e0 B/ [- Z, \9 ^+ p6 r
    会按照ChunkServer拆分子请求,每个子请求对应一个ChunkServer。假设客户端请求5) ~5 s% F& F9 j9 i
    行数据,其中第1、3、5行在ChunkServer A上,第2、4行在ChunkServer B上。那么,% o6 g7 k  L3 n; ^. h- H
    该请求将被拆分为(1、3、5)和(2、4)两个子请求,分别发往ChunkServer A和0 G+ L+ |+ p5 n5 O1 ]! Y# s
    B。
    / _$ n( H3 c! Y' r1 P" IClass ObMsSqlRequest, E( J& J3 ~# B/ K
    {
    7 t6 c- j/ f5 J5 F; P+ Cpublic:9 ?+ F8 G6 U5 k- l3 g' E5 b5 o
    //唤醒正在等待的工作线程
    6 H) L$ D5 S' Lint signal(ObMsSqlRpcEvent&event);
    0 Y  P1 w6 h% o. Q" g: f//等待某个子请求返回
    0 ]. S- e' J2 k8 J7 T$ t2 ?9 Y9 Dint wait_single_event(int64_t&timeout);
    " g6 L8 c5 ^3 e+ g7 F5 k//处理某个子请求的返回结果
    - ~% Y& v" g; Bvirtual int process_result(const int64_t timeout,ObMsSqlRpcEvent*event,bool&  f+ @, X7 R  f! Z- X
    finish)=0;
    ) F+ S0 z0 c5 K7 I' r# w; Q/ V: k};8 }! v8 S& }4 \4 ?. }/ z
    ObMsSqlRequest类用于实现并发查询,相应地,ObMsSqlScanRequest以及ObMs-7 d- F: W" g( m# W6 H: Q2 L  S( y
    SqlGetRequest类分别用于实现并发扫描和并发批量读取。MergeServer将大请求拆分
    , p% w- i+ r5 q+ z; s" B  y( ~为多个子请求,每个子请求对应一个子请求事件(ObMsSqlRpcEvent)。工作线程将
    ! U. b9 p# A+ }, _0 S/ @3 d4 m子请求发给相应的ChunkServer后开始等待(调用wait_single_event方法),/ Y, X6 N+ l3 N9 ~! ~* g
    ChunkServer执行完子请求后应答MergeServer。MergeServer收到应答包后回调signal2 p. p1 o( m7 T3 N9 ^
    函数,唤醒工作线程,工作线程接着调用process_result进行处理。  S- h9 |; g# T& d" n3 F+ J7 S% s: A
    ObMsSqlScanRequest和ObMsSql-GetRequest实现了process_result接口,将每个子请求" n3 l! A7 G' D& R+ d7 P" p
    返回的部分结果保存到结果合并器merge_operator_中。如果所有的子请求全部执行完
    9 B% l# e$ Q9 O$ B成,process_result函数返回的finish变量将置为true,这时,merge_operator_中便保存& }2 |( L8 W' P( J* [/ j
    了并发查询的最终结果。
    5 b2 x1 C1 [3 x: ?1 G: f  Y细心的读者可能会发现,OceanBase这种查询模式虽然解决了绝大部分大查询请+ o) O/ L+ L2 o5 H4 |
    求的延时问题,但是,如果查询的返回结果特别大,MergeServer将成为性能瓶颈。
    $ f6 I! ~$ q+ L% G7 i! E2 l因此,新版的OceanBase系统将对OLAP查询执行逻辑进行升级,使其能够支持数据; s2 ~! }6 Q$ c
    量更大且更加复杂的SQL查询。( n3 d9 }$ J: K4 ?$ v3 m  H/ B
    10.4.2 列式存储! R: d" ^# j: g, C0 N) y
    列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全
    ( I1 A( M, }8 e/ `" G部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一
    3 `7 e) L; r) t7 O起,能够极大地提高数据压缩率。; ]! \6 T; g: E1 ^
    列组(Column Group)0 }5 _5 R5 g" u
    OceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
      ?* K! s% E+ \- l  }如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存
    . S2 A' b' `  \# M" k& Y储。分为几种情况:
    ) e* a/ K# G% a: q' W1 |7 [5 w$ W图 10-14 OceanBase列组设计
    ) A5 j  n' q( }7 Q  W●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这
    / Q/ w, N, M' ?3 U6 y+ f& E种方式。  `, u# @) O$ b/ u/ l) w
    ●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较
    / V% U* }# D' V% P1 t1 g+ C. Z少见。1 y8 H; d2 U" [9 ?4 Y
    ●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应/ G) O2 Z2 ?/ y1 ~; r
    用往往配置为这种方式。
    ' _/ g2 D( ^( l5 l/ |# t7 |OceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性
    ' J/ c; C+ V5 h4 B  @. Q能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3,
    3 Y/ D) a& g1 M  A7 o4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访
    + A6 R) Q( K4 w2 Z问只需要读取一个列组,避免了多个列组的合并操作。  i3 X4 c6 \  N8 R& i' u
    列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初% {9 y( _: p  M3 u
    的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨2 n# y- M& S0 I
    胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出" W0 }! B4 k: T+ V  d- k
    来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,
    6 E8 X" w# L! E0 g) x3 {6 Q3 n: W$ K否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重
    $ e3 u* P: @+ q) s( `# m新设计列式存储引擎。
    1 Z* h8 e* ^1 O0 x
    - s$ Z  ^4 w) H% Q: y4 Y  |
    , R5 W6 Z$ E* `
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-4-1 13:45 , Processed in 0.120433 second(s), 31 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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