Greenplum 数据分布黄金法则 - 论分布列与分区的选择

背景

阿里云ApsaraDB for Greenplum公测以来,已经收到好多用户的公测申请。

要使用Greenplum,登陆到数据库后第一件事当然是建表,然后倒入数据开测。

大部分用户以前是使用MySQL的,并没有接触过Greenplum,语法需要适应一下。

例如MySQL中的建表语句

DROP TABLE IF EXISTS  `ab01`;
CREATE TABLE `ab01` (
  `aab001` bigint(10) NOT NULL ,
  `aab007` varchar(50) DEFAULT NULL ,
  `aab008` decimal(14,0) DEFAULT NULL ,
  `create_time` datetime NOT NULL ,
  `deleteedflag` bit(1) DEFAULT b'0' ,
  PRIMARY KEY (`aab001`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

在Greenplum中可以写成

DROP TABLE IF EXISTS  ab01;
CREATE TABLE ab01 (
  aab001 int8 NOT NULL ,
  aab007 varchar(50) DEFAULT NULL ,
  aab008 decimal(14,0) DEFAULT NULL ,  -- 长度 <=15 的decimal建议替换成float8, 运算效率比decimal高
  create_time timestamp(0) NOT NULL ,
  deleteedflag bit(1) DEFAULT b'0' ,
  PRIMARY KEY (aab001)
) ; 

Greenplum完整的建表语法参考本文末尾。

分布列选择黄金法则

由于Greenplum是一个分布式的数据库,数据是分散存储在各个数据节点的,所以需要告诉Greenplum数据应该如何分布。

短板效应

当用户请求QUERY时,Greenplum会在所有的节点并行执行,所以最慢的节点会成为整个系统的瓶颈。

Greenplum 支持的分布算法 :

用户可以指定 分布列(允许指定多个列) ,或者使用 随机分布 算法。

那么用户应该如何选择分布列,或者是否要使用随机分布算法呢?

总结起来,需要考虑以下几点

  • JOIN
    当JOIN的列都是分布列时,不需要重分布或广播小表,可以在segment内完成JOIN。


两个表在JOIN时,如果JOIN列不是表的分布列,那么其中一个更小的表会发生数据重分布,或者broadcast,以继续完成JOIN的动作。
例如a和b都是随机分布的,在JOIN时,要么广播小表,要么两个表都根据JOIN 列重分布。

例如a和b,其中a是JOIN列分布,b不是,那么b可以选择广播,或者重分布。

重分布或广播的动作都是自动完成的,但是这样一定会带来额外的网络开销。

想象一下,如果你的QUERY并发很高,而且大量的QUERY中涉及到JOIN的数据重分布或broadcast的话,网络很快就会成为瓶颈。

法则1,分布列尽量选择需要经常JOIN的列,这类查询的并发越高,越应该考虑。

  • 防止数据倾斜
    Greenplum依据指定的分布列,hash取模存放到对应的segment中。

如果选择的分布列值分布不均匀,就可能导致数据倾斜,某些segment可能非常大,而某些segment非常小。

数据倾斜的显著危害,1. 空间不均匀,不好规划存储。2. 数据分布过多的节点,容易成为整个系统的短板。

法则2,尽量选择分布均匀的列,或者多列

  • 高并发查询,选择性好
    如果数据经常被高并发的键值或离散查询,建议将查询条件的列作为分布列,这样不需要连接到所有的segment去查,可以大大提高并发能力。

例子

aa01 的分布列是aaz499

查询分布列时,定位到一个segment查询

postgres=# explain analyze select * from aa01 where aaz499=1;
                                    QUERY PLAN
----------------------------------------------------------------------------------
 Gather Motion 1:1  (slice1; segments: 1)  (cost=0.00..120.00 rows=1 width=1973)
   Rows out:  0 rows at destination with 1.352 ms to end, start offset by 144 ms.
   ->  Seq Scan on aa01  (cost=0.00..120.00 rows=1 width=1973)
         Filter: aaz499 = 1
         Rows out:  0 rows with 0.031 ms to end, start offset by 145 ms.
 Slice statistics:
   (slice0)    Executor memory: 330K bytes.
   (slice1)    Executor memory: 176K bytes (seg10).
 Statement statistics:
   Memory used: 128000K bytes
 Optimizer status: legacy query optimizer
 Total runtime: 145.822 ms
(12 rows)

查询非分布列,需要所有的segment参与查询

postgres=# explain analyze select * from aa01 where cae007='t';
                                     QUERY PLAN
------------------------------------------------------------------------------------
 Gather Motion 16:1  (slice1; segments: 16)  (cost=0.00..120.00 rows=2 width=1973)
   Rows out:  0 rows at destination with 2.001 ms to end, start offset by 146 ms.
   ->  Seq Scan on aa01  (cost=0.00..120.00 rows=1 width=1973)
         Filter: cae007::text = 't'::text
         Rows out:  0 rows (seg0) with 0.047 ms to end, start offset by 147 ms.
 Slice statistics:
   (slice0)    Executor memory: 330K bytes.
   (slice1)    Executor memory: 176K bytes avg x 16 workers, 176K bytes max (seg0).
 Statement statistics:
   Memory used: 128000K bytes
 Optimizer status: legacy query optimizer
 Total runtime: 147.813 ms
(12 rows)

法则3,尽量选择高并发查询的条件列(指该查询条件产生的中间结果集小的,如果中间结果集很大,那就让所有节点都来参与运算更好,因此不选),如果有多个条件,请先权衡前面的法则

法则4,不要轻易使用随机分布

分区黄金法则

目前Greenplum支持LIST和RANGE两种分区类型。

分区的目的是尽可能的缩小QUERY需要扫描的数据量,因此必须和查询条件相关联。

法则1,尽量选择和查询条件相关的字段,缩小QUERY需要扫描的数据

法则2,当有多个查询条件时,可以使用子分区,进一步缩小需要扫描的数据

例子,一个用户发起了带两个查询条件col1=xx and col2 between ?1 and ?2 的请求,通过分区,如果表已经根据col1进行了LIST分区,同时根据col2进行了range的分区,那么查询范围可以大大的缩小。

小结

  • 分布列选择法则
    原则,避免短板效应。

法则1,分布列尽量选择需要经常JOIN的列,这类查询的并发越高,越应该考虑。

法则2,尽量选择分布均匀的列,或者多列

法则3,尽量选择高并发查询的条件列(指该查询条件产生的中间结果集小的,如果中间结果集很大,那就让所有节点都来参与运算更好,因此不选),如果有多个条件,请先权衡前面的法则

法则4,不要轻易使用随机分布

  • 分区法则
    原则,缩小查询范围。

法则1,尽量选择和查询条件相关的字段,缩小QUERY需要扫描的数据

法则2,当有多个查询条件时,可以使用子分区,进一步缩小需要扫描的数据

参考

《阿里云ApsaraDB RDS用户 - OLAP最佳实践》

《Greenplum资源隔离指南》

《三张图读懂Greenplum在企业的正确使用姿势》

《Greenplum 公测申请页面》
https://www.aliyun.com/product/gpdb?spm=5176.7960203.237031.39.3xWeRa

Greenplum完整的建表语法如下 :

Command:     CREATE TABLE
Description: define a new table
Syntax:
CREATE [[GLOBAL | LOCAL] {TEMPORARY | TEMP}] TABLE table_name (
[ { column_name data_type [ DEFAULT default_expr ]     [column_constraint [ ... ]
[ ENCODING ( storage_directive [,...] ) ]
]
   | table_constraint
   | LIKE other_table [{INCLUDING | EXCLUDING}
                      {DEFAULTS | CONSTRAINTS}] ...}
   [, ... ] ]
   [column_reference_storage_directive [, ... ]
   )
   [ INHERITS ( parent_table [, ... ] ) ]
   [ WITH ( storage_parameter=value [, ... ] )
   [ ON COMMIT {PRESERVE ROWS | DELETE ROWS | DROP} ]
   [ TABLESPACE tablespace ]
   [ DISTRIBUTED BY (column, [ ... ] ) | DISTRIBUTED RANDOMLY ]  -- 分布算法的选择
   [ PARTITION BY partition_type (column)
       [ SUBPARTITION BY partition_type (column) ]
          [ SUBPARTITION TEMPLATE ( template_spec ) ]
       [...]
    ( partition_spec )
        | [ SUBPARTITION BY partition_type (column) ]
          [...]
    ( partition_spec
      [ ( subpartition_spec
           [(...)]
         ) ]
    )
where storage_parameter is:
   APPENDONLY={TRUE|FALSE}
   BLOCKSIZE={8192-2097152}
   ORIENTATION={COLUMN|ROW}
   COMPRESSTYPE={ZLIB|QUICKLZ|RLE_TYPE|NONE}
   COMPRESSLEVEL={0-9}
   CHECKSUM={TRUE|FALSE}
   FILLFACTOR={10-100}
   OIDS[=TRUE|FALSE]
where column_constraint is:
   [CONSTRAINT constraint_name]
   NOT NULL | NULL
   | UNIQUE [USING INDEX TABLESPACE tablespace]
            [WITH ( FILLFACTOR = value )]
   | PRIMARY KEY [USING INDEX TABLESPACE tablespace]
                 [WITH ( FILLFACTOR = value )]
   | CHECK ( expression )
and table_constraint is:
   [CONSTRAINT constraint_name]
   UNIQUE ( column_name [, ... ] )
          [USING INDEX TABLESPACE tablespace]
          [WITH ( FILLFACTOR=value )]
   | PRIMARY KEY ( column_name [, ... ] )
                 [USING INDEX TABLESPACE tablespace]
                 [WITH ( FILLFACTOR=value )]
   | CHECK ( expression )
where partition_type is:
    LIST
  | RANGE
where partition_specification is:
partition_element [, ...]
and partition_element is:
   DEFAULT PARTITION name
  | [PARTITION name] VALUES (list_value [,...] )
  | [PARTITION name]
     START ([datatype] 'start_value') [INCLUSIVE | EXCLUSIVE]
     [ END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE] ]
     [ EVERY ([datatype] [number | INTERVAL] 'interval_value') ]
  | [PARTITION name]
     END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE]
     [ EVERY ([datatype] [number | INTERVAL] 'interval_value') ]
[ WITH ( partition_storage_parameter=value [, ... ] ) ]
[column_reference_storage_directive [, ...] ]
[ TABLESPACE tablespace ]
where subpartition_spec or template_spec is:
subpartition_element [, ...]
and subpartition_element is:
   DEFAULT SUBPARTITION name
  | [SUBPARTITION name] VALUES (list_value [,...] )
  | [SUBPARTITION name]
     START ([datatype] 'start_value') [INCLUSIVE | EXCLUSIVE]
     [ END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE] ]
     [ EVERY ([datatype] [number | INTERVAL] 'interval_value') ]
  | [SUBPARTITION name]
     END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE]
     [ EVERY ([datatype] [number | INTERVAL] 'interval_value') ]
[ WITH ( partition_storage_parameter=value [, ... ] ) ]
[column_reference_storage_directive [, ...] ]
[ TABLESPACE tablespace ]
where storage_directive is:
   COMPRESSTYPE={ZLIB | QUICKLZ | RLE_TYPE | NONE}
 | COMPRESSLEVEL={0-9}
 | BLOCKSIZE={8192-2097152}
Where column_reference_storage_directive is:
   COLUMN column_name ENCODING ( storage_directive [, ... ] ), ...
 | DEFAULT COLUMN ENCODING ( storage_directive [, ... ] )

祝大家玩得开心,欢迎随时来 阿里云促膝长谈 业务需求 ,恭候光临。

阿里云的小伙伴们加油,努力做 最贴地气的云数据库

时间: 2024-11-02 22:04:48

Greenplum 数据分布黄金法则 - 论分布列与分区的选择的相关文章

【动手实践】Oracle 12.2新特性:多列列表分区和外部表分区

Oracle 12.2版本中,增加了大量的分区新特性,这其中包括: 自动的列表分区创建 在线的普通表转换分区表 支持只读分区和读写分区混合 以下介绍的三个特性同样是12.2新增的: 多列列表分区.外部表分区.维护过滤 而对于多列列表分区的支持,也是大家关注已久的特性,先看一下脚本(在 livesql.oracle.com 测试执行,推荐动手实践): CREATE TABLE dba_by_db_in_yhem  (dbalic           NUMBER,    username    

为PostgreSQL讨说法 - 浅析《UBER ENGINEERING SWITCHED FROM POSTGRES TO MYSQL》

背景 最近有一篇文档,在国外闹得沸沸扬扬,是关于UBER使用mysql替换postgres原因的文章. 英文原文https://eng.uber.com/mysql-migration/ 来自高可用架构的 中文翻译 文章涉及到 PG数据库的部分,背后的原理并没有深入的剖析,导致读者对PostgreSQL的误解 . uber在文章阐述的遇到的PG问题 We encountered many Postgres limitations: Inefficient architecture for wri

德哥的PostgreSQL私房菜 - 史上最屌PG资料合集

看完并理解这些文章,相信你会和我一样爱上PostgreSQL,并成为一名PostgreSQL的布道者. 资料不断更新中... ... 沉稳的外表无法掩饰PG炙热的内心 . 扩展阅读,用心感受PostgreSQL 内核扩展 <找对业务G点, 体验酸爽 - PostgreSQL内核扩展指南>https://yq.aliyun.com/articles/55981 <当物流调度遇见PostgreSQL - GIS, 路由, 机器学习 (狮子,女巫,魔衣橱)>https://yq.aliy

旋转门数据压缩算法在PostgreSQL中的实现 - 流式压缩在物联网、监控、传感器等场景的应用

背景 在物联网.监控.传感器.金融等应用领域,数据在时间维度上流式的产生,而且数据量非常庞大. 例如我们经常看到的性能监控视图,就是很多点在时间维度上描绘的曲线. 又比如金融行业的走势数据等等. 我们想象一下,如果每个传感器或指标每100毫秒产生1个点,一天就是864000个点. 而传感器或指标是非常多的,例如有100万个传感器或指标,一天的量就接近一亿的量. 假设我们要描绘一个时间段的图形,这么多的点,渲染估计都要很久. 那么有没有好的压缩算法,即能保证失真度,又能很好的对数据进行压缩呢? 旋

mongoDB BI 分析利器 - PostgreSQL FDW (MongoDB Connector for BI)

背景 mongoDB是近几年迅速崛起的一种文档型数据库,广泛应用于对事务无要求,但是要求较好的开发灵活性,扩展弹性的领域,. 随着企业对数据挖掘需求的增加,用户可能会对存储在mongo中的数据有挖掘需求,但是mongoDB的语法较为单一,不能满足挖掘的需求. PostgreSQL是起源于伯克利大小的一个开源数据库,已经有20多年的历史,以稳定性,功能强大著称,号称"开源界的Oracle". 在国内外各个行业都有非常多的用户,如平安银行,邮储银行,中移动,去哪儿,高德,菜鸟,美国宇航局,

【干货合集】大流量与高并发:数据库、架构与实践技巧

峰会专题:https://yq.aliyun.com/activity/112 报名入口:http://yq.aliyun.com/webinar/join/49?spm=5176.8155509.437644.12.F2Xi5N 从2009年第一届双十一购物节到2015年双十一全天912.17亿元的交易额,"双十一"当天订单创建峰值增长了350倍(每秒14万笔),支付峰值 (每秒8.59万笔)增长了430倍.为了保证越来越多购物者的用户体验,在IT基础设施上,阿里一次又一次地遭遇并超

Greenplum 清理垃圾、修改存储模式(行列变换) 平滑方法 - 交换数据、交互分区

标签 PostgreSQL , Greenplum , 交换分区 , 清理垃圾 , 存储格式变更 背景 1.在使用Greenplum的过程中,如果业务会经常对数据进行更新,删除,插入,可能导致数据出现膨胀. <如何检测.清理Greenplum膨胀.垃圾 - 阿里云HybridDB for PG最佳实践> <Greenplum 列存表(AO表)的膨胀.垃圾检查与空间收缩> 2.用户在建表的时候,存储模式选择不当,但是业务已经运行了一段时间,表里面已经写入了大量的数据. 3.用户在建表

数据库案例集锦 - 开发者的《如来神掌》

背景 「剑魔独孤求败,纵横江湖三十馀载,杀尽仇寇,败尽英雄,天下更无抗手,无可柰何,惟隐居深谷,以雕为友.呜呼,生平求一敌手而不可得,诚寂寥难堪也.」 剑冢中,埋的是剑魔独孤求败毕生几个阶段中用过的几柄剑: 利剑无意:第一柄是青光闪闪的利剑,凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋. 软剑无常:第二柄是紫薇软剑,三十岁前所用,误伤义士不祥,悔恨不已,乃弃之深谷. 重剑无锋:第三柄是玄铁重剑,重剑无锋,大巧不工,四十岁之前恃之横行天下. 木剑无俦:第四柄是已腐朽的木剑. 无剑无招:四十岁后,不

RDS PostgreSQL\HDB PG 毫秒级海量时空数据透视 典型案例分享

标签 PostgreSQL , GIS , 时空数据 , 数据透视 , bitmapAnd , bitmapOr , multi-index , 分区 , brin , geohash cluster 背景 随着移动终端的普及,现在有越来越多的业务数据会包含空间数据,例如手机用户的FEED信息.物联网.车联网.气象传感器的数据.动物的溯源数据,一系列跟踪数据. 这些数据具备这几个维度的属性: 1.空间 2.时间 3.业务属性,例如温度.湿度.消费额.油耗.等. 数据透视是企业BI.分析师.运营非