java自学网VIP

Java自学网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2366|回复: 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业务支持9 X: h; q1 W/ j% @6 N+ v8 O6 H
    OLAP业务的特点是SQL每次执行涉及的数据量很大,需要一次性分析几百万行" g2 R2 s. w1 w5 t1 f, Z
    甚至几千万行的数据。另外,SQL执行时往往只读取每行的部分列而不是整行数据。  \& y  W+ |: n7 [: r- i+ A6 {
    为了支持OLAP计算,OceanBase实现了两个主要功能:并发查询以及列式存
    8 ?' ?# [) p$ K. x" @1 X, m4 f储。并行查询功能允许将SQL请求拆分为多个子请求同时发送给多台机器并发执行,
    # c9 w1 }) K4 ?/ b7 X7 Y列式存储能够提高压缩率,大大降低SQL执行时读取的数据量。本节首先介绍并发查
    - `4 D5 ~( Q; K1 X询功能,接着介绍OceanBase的列式存储引擎。
    " ?$ O3 o: n( ]8 G- ~* e10.4.1 并发查询
    0 s! H/ s9 u- w/ H+ P如图10-13所示,MergeServer将大请求拆分为多个子请求,同时发往每个子请求
    2 t& T3 [6 U' F1 W; k1 D1 n8 Q所在的ChunkServer并发执行,每个ChunkServer执行子请求并将部分结果返回给
    * }0 {) K8 F  |+ e$ Z6 P9 TMergeServer。MergeServer合并ChunkServer返回的部分结果并将最终结果返回给客户
    1 J" _9 w. d4 B. s! M5 ?端。
    / w4 q5 h9 ?' j) e* z( R1 D/ L图 10-13 OceanBase并发查询. P+ X1 S+ r$ R& N; c! D
    MergeServer并发查询执行步骤如下:
    " W4 L/ U  c  T4 [1)MergeServer解析SQL语句,根据本地缓存的子表位置信息获取需要请求的* O; e6 m. f6 q; q' h4 [0 o7 G
    ChunkServer。
    1 W; G5 x& n# ^1 \* n2)如果请求只涉及一个子表,将请求发送给该子表所在的ChunkServer执行;如  A, ?$ D3 p: G+ B- r
    果请求涉及多个子表,将请求按照子表拆分为多个子请求,每个子请求对应一个子1 C1 ^: l0 A8 h; B8 R/ \2 D3 b" L$ r
    表,并发送给该子表所在的ChunkServer并发执行。MergeServer等待每个子请求的返
    - K: t( G- v6 q; c# ^回结果。% q* a0 [6 y$ A- p% G/ ~* R
    3)ChunkServer执行子请求,计算子请求的部分结果。SQL执行遵从10.2.4节提
    - |# J% w/ Y; V4 V6 R到的本地化原则,即能让ChunkServer执行的尽量让ChunkServer执行,包括Filter、  }4 a1 }% r1 h
    Project、子请求部分结果的GroupBy、OrderBy、聚合运算等。
    1 c, _9 ^6 R0 o0 D4)每个子请求执行完成后,ChunkServer将执行结果回复MergeServer,Merge-
    , g7 d* ~" b) }6 p5 Y3 t& b6 KServer首先将每个子请求的执行结果保存起来。如果某个子请求执行失败,
    : g# s& @# e+ d! A. X6 IMergeServer会将该子请求发往子表其他副本所在的ChunkServer执行。; N' X/ ?9 s' W( x
    5)等到所有的子请求执行完成后,MergeServer会对全部数据排序、分组、聚合$ t. s* _* v6 p6 c9 G  S/ C  K+ M
    并将最终结果返回给客户。OceanBase还支持批量读取(multiget)操作一次性读取多
    8 _7 j/ W9 Y8 N; g2 O行数据,且读取的数据可能在不同的ChunkServer上。对于这样的操作,MergeServer
    + T$ b  @0 V. V* d; g4 F会按照ChunkServer拆分子请求,每个子请求对应一个ChunkServer。假设客户端请求5
    0 }/ {; t- w% D行数据,其中第1、3、5行在ChunkServer A上,第2、4行在ChunkServer B上。那么,$ u* F, r* ]0 I3 p( i, u
    该请求将被拆分为(1、3、5)和(2、4)两个子请求,分别发往ChunkServer A和
    3 M  N$ s) ?& G+ v; E' [) D' IB。
    3 Y  U+ _/ n: c; n8 Y4 VClass ObMsSqlRequest
    % I' p. a: ?2 {/ G6 @- @: Z( p{+ g) p$ k) {9 g7 N  S
    public:
    : K  H1 ~- p" \  f6 d//唤醒正在等待的工作线程2 L$ L1 _- i* w8 e% D# |& l) o
    int signal(ObMsSqlRpcEvent&event);- j- O$ |4 t  W/ ^# L
    //等待某个子请求返回4 |* h/ l+ V' ~# Z
    int wait_single_event(int64_t&timeout);" R1 Y+ @" v# d6 V& n
    //处理某个子请求的返回结果; w- q/ A* _7 c) A3 z$ }
    virtual int process_result(const int64_t timeout,ObMsSqlRpcEvent*event,bool&. f; J3 G0 a' m9 I
    finish)=0;
    " z7 N' q5 U, p7 v3 @0 N) I};
      L6 t7 i: I; ?4 v* [% \7 xObMsSqlRequest类用于实现并发查询,相应地,ObMsSqlScanRequest以及ObMs-
    % F' p, V6 W* J: m' N' y" ASqlGetRequest类分别用于实现并发扫描和并发批量读取。MergeServer将大请求拆分
    - ]' ]8 |- f9 `- s为多个子请求,每个子请求对应一个子请求事件(ObMsSqlRpcEvent)。工作线程将
    5 x: {5 m9 }0 z* N; S* Z1 p3 k子请求发给相应的ChunkServer后开始等待(调用wait_single_event方法),# }0 S" H" f7 r6 `+ n6 W1 m$ l
    ChunkServer执行完子请求后应答MergeServer。MergeServer收到应答包后回调signal% V/ I, D7 W7 H( T! P1 C; z5 [
    函数,唤醒工作线程,工作线程接着调用process_result进行处理。9 e1 C1 v) m: g, }- ^
    ObMsSqlScanRequest和ObMsSql-GetRequest实现了process_result接口,将每个子请求
      H4 ^- n6 l. w/ F返回的部分结果保存到结果合并器merge_operator_中。如果所有的子请求全部执行完9 Z8 H5 n- Q" \3 ~. Y. U/ Q) k
    成,process_result函数返回的finish变量将置为true,这时,merge_operator_中便保存
    " G( v2 r5 i, a$ u. ?$ Z了并发查询的最终结果。
    7 N& A9 Z3 u! {5 B细心的读者可能会发现,OceanBase这种查询模式虽然解决了绝大部分大查询请
    8 A$ c( ]8 c/ h4 [求的延时问题,但是,如果查询的返回结果特别大,MergeServer将成为性能瓶颈。
      f) a" a  S) T5 f  Y因此,新版的OceanBase系统将对OLAP查询执行逻辑进行升级,使其能够支持数据& @8 J, ?' X: U' T+ P7 g+ d
    量更大且更加复杂的SQL查询。
    $ [' P8 k+ L! e0 a5 u6 t, i10.4.2 列式存储7 e- Z  _" H0 e, w- f
    列式存储主要的目的有两个:1)大部分OLAP查询只需要读取部分列而不是全( Z7 u/ [# @  P! t& \
    部列数据,列式存储可以避免读取无用数据;2)将同一列的数据在物理上存放在一
    ! Z) o$ q- E5 u: @9 B4 I. t起,能够极大地提高数据压缩率。* n( U0 k1 r; `, w: `
    列组(Column Group)- x' G. j$ ?8 ]5 y3 M4 d( K- L
    OceanBase通过列组支持行列混合存储,每个列组存储多个经常一起访问的列。
    2 M+ K9 V: Y% M5 E, ^4 @; K如图10-14所示,OceanBase SSTable首先按照列组存储,每个列组内部再按行存, ]( Q5 m. E6 v/ B1 m( G* m
    储。分为几种情况:
    ' K. ?0 u: i4 Y9 u' z图 10-14 OceanBase列组设计
    6 X" v& G" Z; o5 T) J5 b3 m●所有列属于同一个列组。数据在SSTable中按行存储,OLTP应用往往配置为这
    , w( H$ x! Y1 }2 X种方式。: ^, J; k8 F$ }# ?
    ●每列对应一个列组。数据在SSTable中按列存储,这种方式在实际应用中比较  y% Y% R# n: J# G6 d1 N8 S) N
    少见。! m' i7 m& U! F4 M2 K( R0 J
    ●每个列组对应一行数据的部分列。数据在SSTable中按行列混合存储,OLAP应
    4 z; d& |. E) j* h) j( t. [! T. E用往往配置为这种方式。& E" o! f6 T4 o3 j1 U2 E/ L' k
    OceanBase还允许一个列属于多个列组,通过冗余存储这些列,能够提高访问性3 Z0 J+ I! @0 W- o7 ]
    能。例如,某表格总共包含5列,用户经常一起访问(1,3,5)或者(1,2,3,* p' Q( Q' I  i* z! e
    4)列。如果将(1,3,5)和(1,2,3,4)存储到两个列组中,那么,大部分访
    ! t% O+ x7 n; ^, {问只需要读取一个列组,避免了多个列组的合并操作。, T+ R5 w* W# Q6 X
    列式存储提高了数据压缩比,然而,实践过程中我们发现,由于OceanBase最初
    5 m; F% a9 }* }" e3 X! u的几个版本内存操作实现得不够精细,例如数据结构设计不合理,数据在内存中膨1 z, }* O$ h; M' j( r. N
    胀很多倍,导致大查询的性能瓶颈集中在CPU,列式存储的优势完全没有发挥出
    - j7 A2 m) G8 v2 F来。这就告诉我们,列式存储的前提是设计好内存数据结构,把CPU操作优化好,
    ! O; y" z6 G  }( T( O否则,后续的工作都是无用功。为了更好地支持OLAP应用,新版的OceanBase将重$ R, }+ k6 }- w4 ^* N5 E/ B
    新设计列式存储引擎。" ?. f' ]1 |3 y" Q7 }- E# `. O
    & U7 _) ^! y1 Q! z/ _) y; ~

    - b# b# W* z6 M2 H4 }7 V, T) }
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-11-21 21:15 , Processed in 0.245243 second(s), 28 queries .

    Powered by Javazx

    Copyright © 2012-2022, Javazx Cloud.

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