java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2182|回复: 0

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

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

    [LV.Master]出神入化

    2025

    主题

    3683

    帖子

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    66101

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

    发表于 2017-3-10 13:50:05 | 显示全部楼层 |阅读模式
    10.4 OLAP业务支持
    3 `* W; Q" }+ a& l# [7 W7 qOLAP业务的特点是SQL每次执行涉及的数据量很大,需要一次性分析几百万行
    ' ]3 t8 D$ ^  l: i甚至几千万行的数据。另外,SQL执行时往往只读取每行的部分列而不是整行数据。7 v& u. `; K5 R3 c5 Q+ o
    为了支持OLAP计算,OceanBase实现了两个主要功能:并发查询以及列式存
    " H" }" e) P6 w0 [- y9 b储。并行查询功能允许将SQL请求拆分为多个子请求同时发送给多台机器并发执行,
    8 H) A# }& J* J$ p2 S0 K$ _: Z& l列式存储能够提高压缩率,大大降低SQL执行时读取的数据量。本节首先介绍并发查
    - h: P: S7 c# W% Z( @6 W询功能,接着介绍OceanBase的列式存储引擎。
    0 \+ O) B3 C' h$ A7 Z( \1 R10.4.1 并发查询
    # @  H& i  |0 y+ z7 d- o如图10-13所示,MergeServer将大请求拆分为多个子请求,同时发往每个子请求+ k+ }/ k& S, b  C$ W( q  k0 G; |
    所在的ChunkServer并发执行,每个ChunkServer执行子请求并将部分结果返回给
    4 Q$ z' g, v" \6 g3 s% sMergeServer。MergeServer合并ChunkServer返回的部分结果并将最终结果返回给客户  q. |; C% E0 r2 J* d# R4 h( A( n" @
    端。
    + I2 B) t: l- r3 L. ~$ r图 10-13 OceanBase并发查询; v4 ]4 j: G  e2 d/ ~
    MergeServer并发查询执行步骤如下:6 p3 `8 A7 W9 m
    1)MergeServer解析SQL语句,根据本地缓存的子表位置信息获取需要请求的
    + |8 h) c% @2 |' N2 wChunkServer。  P7 ~2 M; U/ Q7 o& E4 D& u1 X
    2)如果请求只涉及一个子表,将请求发送给该子表所在的ChunkServer执行;如
    * u% }' u; t$ ~$ M果请求涉及多个子表,将请求按照子表拆分为多个子请求,每个子请求对应一个子3 `$ Y" z$ N; i* M) k% G
    表,并发送给该子表所在的ChunkServer并发执行。MergeServer等待每个子请求的返6 s# b3 ^3 s+ o" u. }
    回结果。4 U( A8 o3 G5 ?+ {* e! ^9 _
    3)ChunkServer执行子请求,计算子请求的部分结果。SQL执行遵从10.2.4节提1 Y7 \# K/ q1 e/ }/ f! U0 l
    到的本地化原则,即能让ChunkServer执行的尽量让ChunkServer执行,包括Filter、
    + \) x6 {" O. Q( t% ~2 _3 lProject、子请求部分结果的GroupBy、OrderBy、聚合运算等。. Y) S  u9 k% Z( ~$ T7 {. a7 ]" p4 T. y
    4)每个子请求执行完成后,ChunkServer将执行结果回复MergeServer,Merge-" m. l; L' t& t  H7 r
    Server首先将每个子请求的执行结果保存起来。如果某个子请求执行失败,( N" v) k3 Y6 w7 C; C
    MergeServer会将该子请求发往子表其他副本所在的ChunkServer执行。
    3 o/ h  K1 G" p# ?- I5)等到所有的子请求执行完成后,MergeServer会对全部数据排序、分组、聚合) |" K- I1 }' }  L& l
    并将最终结果返回给客户。OceanBase还支持批量读取(multiget)操作一次性读取多% Y! ?6 J' k$ }# Z
    行数据,且读取的数据可能在不同的ChunkServer上。对于这样的操作,MergeServer
    ' y* A% a6 A, }- z0 o会按照ChunkServer拆分子请求,每个子请求对应一个ChunkServer。假设客户端请求56 I" q2 p. W- `: J. n" V; ?
    行数据,其中第1、3、5行在ChunkServer A上,第2、4行在ChunkServer B上。那么,4 z4 t! |- g8 x2 n
    该请求将被拆分为(1、3、5)和(2、4)两个子请求,分别发往ChunkServer A和! ?3 F5 J- E4 ?7 A, [
    B。
    % Q7 y. I; H; v0 C3 }% t" YClass ObMsSqlRequest& V) {9 L1 C: b* k! j
    {
    ; Z. Q, @& j: [' o: \4 D0 E, H$ Ypublic:. Q3 e+ ]' v! h& s# K: \5 {8 Y5 d
    //唤醒正在等待的工作线程
    " l, b$ y/ i) n& y3 t2 uint signal(ObMsSqlRpcEvent&event);
    . i2 d4 ~7 r* L/ t5 d1 c//等待某个子请求返回
    - v3 f$ n. v  W1 l& tint wait_single_event(int64_t&timeout);
    . c; t9 p; B; u/ @$ k" x/ |//处理某个子请求的返回结果
    : n: d4 C$ H8 `4 Y4 r4 R8 }8 svirtual int process_result(const int64_t timeout,ObMsSqlRpcEvent*event,bool&
    5 B8 I9 k2 N2 y& T5 efinish)=0;% }( |5 ~4 @  B+ a  ]
    };, x  I3 K" w+ S' @. f$ r
    ObMsSqlRequest类用于实现并发查询,相应地,ObMsSqlScanRequest以及ObMs-
    ! M# t5 r! ^) X; S( D+ |SqlGetRequest类分别用于实现并发扫描和并发批量读取。MergeServer将大请求拆分* |5 _+ Q" f; U
    为多个子请求,每个子请求对应一个子请求事件(ObMsSqlRpcEvent)。工作线程将$ h' T: p$ K3 l- W1 G' q6 H8 S
    子请求发给相应的ChunkServer后开始等待(调用wait_single_event方法),% K  n$ |) v9 |
    ChunkServer执行完子请求后应答MergeServer。MergeServer收到应答包后回调signal
      V0 B* K5 _- H! U) R+ E: S' r3 K* H函数,唤醒工作线程,工作线程接着调用process_result进行处理。
    , w  c2 o# ~5 M# M! JObMsSqlScanRequest和ObMsSql-GetRequest实现了process_result接口,将每个子请求
    ) ^0 j  z: K9 o+ I( f+ D+ d返回的部分结果保存到结果合并器merge_operator_中。如果所有的子请求全部执行完
    - ~, i  _, x# J. y8 T3 ]成,process_result函数返回的finish变量将置为true,这时,merge_operator_中便保存& z" E$ |" _7 h7 M: z
    了并发查询的最终结果。
    6 w8 Y& F- x' v3 Z细心的读者可能会发现,OceanBase这种查询模式虽然解决了绝大部分大查询请
    ) l% w4 e! l% E6 V  s求的延时问题,但是,如果查询的返回结果特别大,MergeServer将成为性能瓶颈。7 [1 I6 ]+ m7 `% X
    因此,新版的OceanBase系统将对OLAP查询执行逻辑进行升级,使其能够支持数据, D: y: U* |' ~0 R/ V8 p
    量更大且更加复杂的SQL查询。0 T6 t1 G* ^' b
    10.4.2 列式存储9 P' _+ ^$ V* B, _* W! s8 c
    列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全- Z1 C* W: X) f2 e8 o; z/ s
    部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一
    % R; |; e- u! Z0 V起,能够极大地提高数据压缩率。
    8 u) V+ s7 O; y" h. j; t- \列组(Column Group)" J- u; o9 d0 P6 w. n
    OceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
    0 ]# q+ r8 V8 Z  y; H8 y% V如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存
    & ^! S8 p  A3 [) M& T4 F储。分为几种情况:
    3 |8 C; O5 X4 {/ X0 s0 Q0 X图 10-14 OceanBase列组设计$ T* X: J$ p8 U
    ●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这+ ?! L' C0 ]5 a/ r
    种方式。/ T7 ?& P6 W1 ~1 }9 O0 y% ^
    ●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较
    / j4 d& ?* m" X; `少见。
    5 n" K1 u& v; K# R●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应
    0 {+ o7 _  }0 |5 z! Q4 H8 J用往往配置为这种方式。3 p& X1 ]# t8 W8 m
    OceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性1 B1 }) Q- p! d
    能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3," c* O  P9 ~. i" b  T  W' N
    4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访
    1 s  P7 X) G% t1 o/ a& W3 z* _问只需要读取一个列组,避免了多个列组的合并操作。) S! Z8 R- u# B  c
    列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初' ?9 h3 d: w- k7 i: a3 ?
    的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨
    6 e" \# {* p) a9 t3 ~! c2 h; d胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出6 y, x8 L) q8 U# V
    来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,
    6 I/ {# d5 H+ k* G9 _否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重
    5 e6 `. q* M0 x) _5 X: R4 s新设计列式存储引擎。
    0 F$ _4 G, m0 V
    4 e' S7 C6 S4 R
    - c# L5 c! o% h+ j/ @5 h
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-29 04:21 , Processed in 0.096949 second(s), 29 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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