java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2365|回复: 0

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

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

    [LV.Master]出神入化

    2025

    主题

    3683

    帖子

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    66345

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

    发表于 2017-3-10 13:50:05 | 显示全部楼层 |阅读模式
    10.4 OLAP业务支持/ A* }8 M0 j" L6 d9 o' a, i
    OLAP业务的特点是SQL每次执行涉及的数据量很大,需要一次性分析几百万行  _7 x# u/ e. h- |8 t+ S) u/ k
    甚至几千万行的数据。另外,SQL执行时往往只读取每行的部分列而不是整行数据。& v4 D' v. L! _
    为了支持OLAP计算,OceanBase实现了两个主要功能:并发查询以及列式存
    / N) W$ o$ @( \; o储。并行查询功能允许将SQL请求拆分为多个子请求同时发送给多台机器并发执行,
    : d- v/ K0 N' a: K列式存储能够提高压缩率,大大降低SQL执行时读取的数据量。本节首先介绍并发查
    8 J/ {# u; T" x& C  v询功能,接着介绍OceanBase的列式存储引擎。6 |& J( J& J% c
    10.4.1 并发查询5 e$ x/ D8 L+ V( p+ L
    如图10-13所示,MergeServer将大请求拆分为多个子请求,同时发往每个子请求8 Y% K7 ^2 I3 J7 i$ f
    所在的ChunkServer并发执行,每个ChunkServer执行子请求并将部分结果返回给
    - T: J* P# r. q0 j6 A6 X$ ]MergeServer。MergeServer合并ChunkServer返回的部分结果并将最终结果返回给客户
    8 O; t% z" k  i& a/ b端。) b9 E3 ?& F) ?
    图 10-13 OceanBase并发查询# p: o( I6 Z( H3 X3 S# X0 J5 S
    MergeServer并发查询执行步骤如下:$ {8 C8 n7 X5 u, \
    1)MergeServer解析SQL语句,根据本地缓存的子表位置信息获取需要请求的
    & T1 ?% C4 z  }  v: }. h% ]5 X  W6 iChunkServer。$ H; X' h. y! }
    2)如果请求只涉及一个子表,将请求发送给该子表所在的ChunkServer执行;如& h, M9 E8 `# m7 c+ r8 M
    果请求涉及多个子表,将请求按照子表拆分为多个子请求,每个子请求对应一个子
    3 u9 X4 q: ^) {1 E- o表,并发送给该子表所在的ChunkServer并发执行。MergeServer等待每个子请求的返2 S. A8 I/ d) b- k' h
    回结果。
    3 P# }0 P  V' w2 W8 [1 y$ ?9 {3)ChunkServer执行子请求,计算子请求的部分结果。SQL执行遵从10.2.4节提
      x# w3 E2 R3 Q& F& {( I; I2 {/ ?到的本地化原则,即能让ChunkServer执行的尽量让ChunkServer执行,包括Filter、
    4 l3 E4 N5 b3 vProject、子请求部分结果的GroupBy、OrderBy、聚合运算等。2 P. i! s: r8 H; D5 [3 M
    4)每个子请求执行完成后,ChunkServer将执行结果回复MergeServer,Merge-
    * `5 K* J( t8 {; K' ~$ {Server首先将每个子请求的执行结果保存起来。如果某个子请求执行失败,
    & S% N" z" Z2 G3 D6 j4 E+ QMergeServer会将该子请求发往子表其他副本所在的ChunkServer执行。# J5 B. X! i' j8 K; h
    5)等到所有的子请求执行完成后,MergeServer会对全部数据排序、分组、聚合1 E/ {! V$ ?6 z+ I" z" e4 r
    并将最终结果返回给客户。OceanBase还支持批量读取(multiget)操作一次性读取多1 m1 \+ \/ _1 \
    行数据,且读取的数据可能在不同的ChunkServer上。对于这样的操作,MergeServer
    ' i. C" A) l6 P5 E会按照ChunkServer拆分子请求,每个子请求对应一个ChunkServer。假设客户端请求5
    6 ^! ]- n4 {5 G* B7 h. P行数据,其中第1、3、5行在ChunkServer A上,第2、4行在ChunkServer B上。那么,
    $ y5 \1 ?7 S* _" G, o3 G  {, c该请求将被拆分为(1、3、5)和(2、4)两个子请求,分别发往ChunkServer A和
    & [6 [7 Y" a$ z3 u% F. ^4 p! iB。  \  H9 i; n9 _! w( U
    Class ObMsSqlRequest  F$ X4 `* Y2 ]3 t2 u
    {7 M0 y8 c* k4 d* \0 e
    public:+ x" U4 _& Y& }- V* ^
    //唤醒正在等待的工作线程
    6 T* V  j. T6 S2 n( M) Z: oint signal(ObMsSqlRpcEvent&event);
    6 ]! Z: i5 X6 H1 P//等待某个子请求返回
    8 K- E' f% D! ]int wait_single_event(int64_t&timeout);
    2 n  n# m8 \* U//处理某个子请求的返回结果
    " G- Z  z6 q2 m1 o0 ovirtual int process_result(const int64_t timeout,ObMsSqlRpcEvent*event,bool&
    ! Z2 {6 r. e+ B  f3 lfinish)=0;
    + I( O4 O0 ]' D# C% |};
    ' D3 c1 B: A1 y8 G- cObMsSqlRequest类用于实现并发查询,相应地,ObMsSqlScanRequest以及ObMs-" j  J5 z6 p7 @* g
    SqlGetRequest类分别用于实现并发扫描和并发批量读取。MergeServer将大请求拆分8 v% v& c+ }+ z
    为多个子请求,每个子请求对应一个子请求事件(ObMsSqlRpcEvent)。工作线程将
    ! M5 R. m2 b7 ^( J8 J; v& C3 o子请求发给相应的ChunkServer后开始等待(调用wait_single_event方法),
    & ?- R1 Y" X2 L! FChunkServer执行完子请求后应答MergeServer。MergeServer收到应答包后回调signal5 {4 Q1 Q) O: }: Z. G! m: J) j
    函数,唤醒工作线程,工作线程接着调用process_result进行处理。
    9 g8 A& W8 f; D; {+ Y# eObMsSqlScanRequest和ObMsSql-GetRequest实现了process_result接口,将每个子请求
    7 u2 S- J1 m4 a! H9 t  W- N: r返回的部分结果保存到结果合并器merge_operator_中。如果所有的子请求全部执行完
    0 V4 E' Y) Q: d- t成,process_result函数返回的finish变量将置为true,这时,merge_operator_中便保存& v* O# }) D& g
    了并发查询的最终结果。
    + B; k; p6 p+ \* k& y3 l$ l细心的读者可能会发现,OceanBase这种查询模式虽然解决了绝大部分大查询请% H  u2 U4 ~: W& w3 M5 M
    求的延时问题,但是,如果查询的返回结果特别大,MergeServer将成为性能瓶颈。/ l- y: a+ S+ l, H1 P( J- v! P
    因此,新版的OceanBase系统将对OLAP查询执行逻辑进行升级,使其能够支持数据$ Y" u  K& ], ?
    量更大且更加复杂的SQL查询。
    * [4 P" Z( {: G2 ?" Q10.4.2 列式存储
    . L; c' q  l- K; W; m5 c8 b- e0 L列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全
    / R& q' k2 `, T4 j. v7 X部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一9 ^- c6 \4 P% r# s* G, J4 A  X# X
    起,能够极大地提高数据压缩率。
    7 T; i' g% c( _/ @2 E, G- z列组(Column Group)
    3 ]( H" I1 j* {) jOceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
    & {/ }' J) l7 t; i* e如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存
    . }2 u$ a4 Q$ l; W储。分为几种情况:# L( m' S' v* |4 v' \! a
    图 10-14 OceanBase列组设计5 C( `, m# }. O4 ?$ |
    ●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这, T: P  [1 d. j
    种方式。& {: D# C9 ^6 M+ j# Z% K
    ●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较2 X+ V. e1 |  L, Q; f2 y; n
    少见。: K2 f/ b5 V. ?0 j
    ●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应
    8 n9 n9 T( n! r& H. [) }, A用往往配置为这种方式。  x1 n+ a& R  L3 S' |& @0 _
    OceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性
    % }; L5 s2 u; o6 n7 D% |能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3,
      R: P5 ^- F, [4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访
    ) \4 U' K8 k8 ?5 s# ?问只需要读取一个列组,避免了多个列组的合并操作。
    ' Y# B% M# |0 w( t% h3 e列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初
    % o3 z2 u1 j! k: `0 r. L的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨
    5 U4 x7 s1 n" @0 j胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出
    1 ]* T: I; q7 f来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,; n, I8 M1 `4 W( j
    否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重2 l! k, x3 u/ z. P
    新设计列式存储引擎。, z7 u* m; ~/ H/ p+ z

    $ X1 h9 u- V9 R$ z* g+ f, h& a6 {; i0 E# j3 k
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-11-21 20:33 , Processed in 0.186734 second(s), 30 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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