java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2486|回复: 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业务支持
    ( `8 ~# k& n/ zOLAP业务的特点是SQL每次执行涉及的数据量很大,需要一次性分析几百万行
    $ u3 e" Y; g5 @% K甚至几千万行的数据。另外,SQL执行时往往只读取每行的部分列而不是整行数据。1 b6 }- o" b: v4 f
    为了支持OLAP计算,OceanBase实现了两个主要功能:并发查询以及列式存
    ; P- c" b+ F- @4 _) L) a6 g( {- o储。并行查询功能允许将SQL请求拆分为多个子请求同时发送给多台机器并发执行,8 e' H# ]- F- K8 u& n
    列式存储能够提高压缩率,大大降低SQL执行时读取的数据量。本节首先介绍并发查2 `; h/ G- X+ e- c. ^
    询功能,接着介绍OceanBase的列式存储引擎。9 y# P1 B: ~2 G8 K- X
    10.4.1 并发查询
    6 g9 B/ b: d. ]% q: V如图10-13所示,MergeServer将大请求拆分为多个子请求,同时发往每个子请求
    . l, t3 q. q6 _: l所在的ChunkServer并发执行,每个ChunkServer执行子请求并将部分结果返回给
    $ u3 }6 C. E% V2 @+ wMergeServer。MergeServer合并ChunkServer返回的部分结果并将最终结果返回给客户  U7 }$ {1 J, X7 d, _9 S3 \8 A& S2 S; N
    端。! B' F3 Y9 R3 ]2 A8 k
    图 10-13 OceanBase并发查询
      {3 y- \, m2 _( F) f# Z% SMergeServer并发查询执行步骤如下:. ?! s: R( b) D. H8 M1 q
    1)MergeServer解析SQL语句,根据本地缓存的子表位置信息获取需要请求的2 _& w* u; U6 W% R' T- q; u7 ^8 S
    ChunkServer。
    $ [" p, y( o# o0 c0 r9 r* c) a2)如果请求只涉及一个子表,将请求发送给该子表所在的ChunkServer执行;如
    . k3 j, X0 j0 N; Z( c% w# b果请求涉及多个子表,将请求按照子表拆分为多个子请求,每个子请求对应一个子. \) k" J0 p6 f/ V5 R
    表,并发送给该子表所在的ChunkServer并发执行。MergeServer等待每个子请求的返
    , W( d) ~  ]; D8 n3 ]/ J回结果。
    " b+ Y; T6 u+ N, c1 R6 `' d3)ChunkServer执行子请求,计算子请求的部分结果。SQL执行遵从10.2.4节提
      E/ ]+ I2 g: H7 P% v0 [. ~( u到的本地化原则,即能让ChunkServer执行的尽量让ChunkServer执行,包括Filter、$ K0 ~7 A0 y  G- D; C
    Project、子请求部分结果的GroupBy、OrderBy、聚合运算等。' r% [& n. f6 D" }8 b7 @3 p7 m
    4)每个子请求执行完成后,ChunkServer将执行结果回复MergeServer,Merge-5 v" o5 w& M& q% u+ v9 J( o, ^
    Server首先将每个子请求的执行结果保存起来。如果某个子请求执行失败,8 j  {  k$ ~$ S* j
    MergeServer会将该子请求发往子表其他副本所在的ChunkServer执行。
    7 S% f" E8 p! j% w# l( [  C1 i5)等到所有的子请求执行完成后,MergeServer会对全部数据排序、分组、聚合
    " U' x: L5 d5 w3 i, L; i8 s5 z并将最终结果返回给客户。OceanBase还支持批量读取(multiget)操作一次性读取多2 C; D  n3 u. {8 d/ ^& R
    行数据,且读取的数据可能在不同的ChunkServer上。对于这样的操作,MergeServer
    7 |' b- }" [! w3 D( r会按照ChunkServer拆分子请求,每个子请求对应一个ChunkServer。假设客户端请求5
    6 j: [6 F1 o" ?, n3 G行数据,其中第1、3、5行在ChunkServer A上,第2、4行在ChunkServer B上。那么,
    ( }" H. c0 i, Z该请求将被拆分为(1、3、5)和(2、4)两个子请求,分别发往ChunkServer A和) O0 v0 U3 d+ B9 x' E# N
    B。
    ) R3 ^  ~3 G! `9 C4 Q8 {4 Y6 n3 h0 vClass ObMsSqlRequest4 x. {) C3 u: k6 j& x0 k
    {
    $ n' C+ j& m9 x! f/ x( Y& ]4 wpublic:" p+ ?0 O$ ~# s; N3 _  [
    //唤醒正在等待的工作线程0 R! \( A0 ^, r. A3 O9 J' O
    int signal(ObMsSqlRpcEvent&event);
    $ f; d. |8 p, F' r//等待某个子请求返回
    9 s. O& e) m' s6 {! ^/ Uint wait_single_event(int64_t&timeout);2 D0 M1 v' y; F* P" w8 l
    //处理某个子请求的返回结果
    + z$ q9 L$ c+ p3 [  V2 N3 l' ]* x; nvirtual int process_result(const int64_t timeout,ObMsSqlRpcEvent*event,bool&& j1 {! L  y( T) u* e4 d
    finish)=0;
    0 ^2 {) c+ E  N6 {4 }) t/ B};
    5 h2 h& K: G. [ObMsSqlRequest类用于实现并发查询,相应地,ObMsSqlScanRequest以及ObMs-
    6 m3 @8 Z$ m* a! ESqlGetRequest类分别用于实现并发扫描和并发批量读取。MergeServer将大请求拆分4 x, J; i$ r( G
    为多个子请求,每个子请求对应一个子请求事件(ObMsSqlRpcEvent)。工作线程将
    , T/ J. P( |- E) P! m+ A5 Z, C& Y子请求发给相应的ChunkServer后开始等待(调用wait_single_event方法),0 x9 _6 L- R6 q! W
    ChunkServer执行完子请求后应答MergeServer。MergeServer收到应答包后回调signal* K3 }! g/ ?. J0 U( [% e) J
    函数,唤醒工作线程,工作线程接着调用process_result进行处理。; q$ K) H2 f( P/ G9 J! S
    ObMsSqlScanRequest和ObMsSql-GetRequest实现了process_result接口,将每个子请求1 w$ d# R9 s9 c3 G0 p
    返回的部分结果保存到结果合并器merge_operator_中。如果所有的子请求全部执行完
    0 t5 R: {( U9 E% ^" V成,process_result函数返回的finish变量将置为true,这时,merge_operator_中便保存. V9 l- N* W  t5 }$ Y
    了并发查询的最终结果。
      G8 c- A9 R6 G0 H. n细心的读者可能会发现,OceanBase这种查询模式虽然解决了绝大部分大查询请
    3 z# h1 [2 P5 T' T. F- P3 s求的延时问题,但是,如果查询的返回结果特别大,MergeServer将成为性能瓶颈。
    , p( c& N; y' o2 f' Q3 H0 S因此,新版的OceanBase系统将对OLAP查询执行逻辑进行升级,使其能够支持数据
    4 d$ `) z2 Q7 v6 {( n量更大且更加复杂的SQL查询。- I# P5 x/ }4 i0 s
    10.4.2 列式存储) i6 s% n3 [( n" p4 G
    列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全" A/ \+ o9 V. g2 d7 E
    部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一
    ' ~# ?( s9 _7 r% {起,能够极大地提高数据压缩率。
    6 A  Q( d9 I% q7 j' H列组(Column Group)
    . D! C5 S& I) o% pOceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
    $ y6 `' G" ]! Q2 P如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存2 ~, U6 T$ }' R) n
    储。分为几种情况:5 k& J# d! g& m. N# o8 b) M
    图 10-14 OceanBase列组设计
    $ n& B2 |) c2 r' e●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这3 I" B( A! ^1 L* ^
    种方式。5 f' _+ ^/ R2 @; M# G
    ●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较
    1 ?4 `0 t: H+ x. F少见。
    8 W6 Q$ l- S) P●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应: {3 @$ W2 V; |; ?! T5 m3 f
    用往往配置为这种方式。
    + J2 e& M( b6 k1 g+ c+ OOceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性' S7 K& R: j* z. Y
    能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3,
    2 O8 N$ R/ w1 I) ]* A2 P4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访
    6 B) f4 q3 |) }7 {  H7 E问只需要读取一个列组,避免了多个列组的合并操作。
      l4 _; W% \+ m) t3 ~列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初. M$ W% |, K% ?, H+ q
    的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨! `  l1 U: H, }8 c
    胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出4 X. @, i$ Y  h( N: \
    来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,9 w- @/ C1 v/ l9 I! M, M
    否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重
    % j  u9 l& p: ~新设计列式存储引擎。5 \' l) y" j9 T1 y

    $ d& u8 j% j8 ]# g; `: A1 u% `; I5 k/ v; P, X5 n' o. c
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2025-4-1 14:18 , Processed in 0.153191 second(s), 32 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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