Greenplum分布键及配置规则

Greenplum分布键及配置规则

基本概念

Greenplum是分布式系统,创建表时需要指定分布键(创建表需要CREATEDBA权限),目的在于将数据平均分布到各个segment。选择分布键非常重要,选择错了会导致数据不唯一,更严重的是会造成SQL性能急剧下降。

Greenplum有两种分布策略:

1、hash分布

Greenplum默认使用hash分布策略。该策略可选一个或者多个列作为分布键(distribution key,简称DK)。分布键做hash算法来确认数据存放到对应的segment上。相同分布键值会hash到相同的segment上。表上最好有唯一键或者主键,这样能保证数据均衡分不到各个segment上。语法,distributed by。
如果没有主键或者唯一键,默认选择第一列作为分布键。增加主键

一、hash分布键
1、创建表的时候如果不指定分布键,那么会默认将表的第一个字段作为分布键,
2、如果分布键不是主键或者唯一键,比如我们将test表中的name作为分布键,那么我们还可以将这个分布键指定为唯一键或者主键。
(一般主键会自动的被分成分布键)
3、hash分布表可实现主键或者唯一键值的唯一性(当分布键是主键或者唯一键的时候)
也就是说hash分布键相当于主键或者唯一键,不允许有重复的值插入到同一个列中

4、删除主键后,原hash分布键依然不变。

2、随机(randomly)分布

数据会被随机分不到segment上,相同记录可能会存放在不同的segment上。随机分布可以保证数据平均,但是Greenplum没有跨节点的唯一键约束数据,所以无法保证数据唯一。基于唯一性和性能考虑,推荐使用hash分布,性能部分会另开一篇文档详细介绍。语法,distributed randomly。

二、随机分布键
创建随机分布表需加distributed randomly关键字,具体使用哪列作为分布键不得而知。
验证主键/唯一键的唯一性,可以看到随机分布表不能创建主键和唯一键

分布键设置原则

建议

1.不建议为了设置分布键而添加一个主键(和业务无关的主键)
2.如果没有关联查询,建议以where条件相关的唯一性强的字段作为分布键
3.如果有大表关联,建议将关联字段作为分布键

由于greenplum是一种分布式的并行执行数据库,负载均衡其实是通过数据的均匀分布来实现的,如果表的数据不均衡,
则数据多的节点会比其他节点的压力大,那么时间消耗会卡在数据多的节点上,
所以使用greenplum数据库时要时刻保持数据均匀分布。

与其它数据库相比,GP的表最大的不同是它一定是分区的,也就是表中的所有记录都会依据相关算法打散,分布到所有的segment当中,
从而在充分利用硬件资源的同时,最大化访问数据的IO,这种特性对于数据仓库应用是非常有帮助的

greenplum的均匀分布式设置分布键来实现的,因此设置合理的分布键也就十分重要。
原则:

(1)一般使用数据比较均匀、空值很少的字段作为主键(主键是最适合做分布键的)) 如果在指定了分布键之后,主键不是分布键,那么系统会自动的修改主键为分布键。

(2)根据执行计划中的介绍,两个表关联时可能会造成数据广播或者重分布,所以选择分布键的时候要适当的考虑这个表和其他表常用的关联键,除此之外,group by、window function都会造成数据重分布。

(3)关联键于唯一键不一样的时候要有所取舍。

(4)如果表上定义了主键或者唯一键,则这些键值列必须作前导列出现在分布键当中。并且放在第一位

(5)如果定义表的时候,没有指定distributed子句,系统使用第一个列作为HASH键使用。

(6)另一种数据打散的算法是平均分配法(ROUND-ROBIN):
数据会被随机分不到segment上,相同记录可能会存放在不同的segment上。随机分布可以保证数据平均,但是Greenplum没有跨节点的唯一键约束数据,
所以无法保证数据唯一。基于唯一性和性能考虑,推荐使用hash分布,性能部分会另开一篇文档详细介绍。语法,distributed randomly。

(7)唯一性:hash分布键可以保证数据的唯一性,而随机分布键不能保证,(不能保证的原因是有多个实例的存在)。

考虑因数:

  • 1.对任何表,明确指定分布键,或者使用随机分布,而不是依赖缺省的行为。
  • 2.只要有可能,应该只使用一个字段作为分布键,而不是使用组合字段作为分布键。
  • 3.如果不是为了特定的目的设计,不要为分析型用途的表,选择WHERE条件包含的字段作为分布键。比如,查询是主键查询,使用主键作为分布键,并不会有任何不妥,反而是最合适的设计,这一条主要表达的意思是,不要让个别Instance来承担个大的查询任务。
  • 4.应该尽可能的避免使用日期或者时间字段来作为分布键。因为,一般不会使用这种字段来与其他的表进行关联查询。
  • 5.不要用分区字段作为分布键。因为,一般不会使用这种字段来与其他的表进行关联查询。
  • 6.为了改善大表之间的关联性能,应该考虑将大表之间关联的字段作为分布键。注意,这里说的是大表之间的关联,但凡涉及与小表关联的场景,完全不应该作为选择分布键的考虑因素。
  • 7.分布键字段应该使用唯一性较高的字段。虽然,主键往往是唯一性最好的字段,但是,不建议为了选择一个分布键而去增加一个主键,这是一种逻辑颠倒的做法,通常,应该选择一个常用于大表之间关联的某个唯一性较高的字段作为分布键,一般这个字段可能在其他某个表中具有主键特征,例如,客户ID,例如会员卡号,例如手机号码,例如身份证号码,等等。
  • 8.如果没有某个字段适合单独作为分布键,就需要考虑组合分布键是否对关联查询有帮助,如果有帮助,应该选择字段数量最少的可能性,一般建议永远不要超过两个字段。
  • 9.只有当关联条件包含全部的分布键字段时,分布键才能对关联有帮助,否则,必须进行数据的重分布,所以,如果实在没有合适的单个字段或者两个字段用作分布键,也许RANDOMLY分布会是一个不错的选择。过多的字段用作分布键,除了带来计算分布键HASH值时更多的资源消耗,一般并不会带来其他好处。
  • 10.要定期或者不定期的检查数据分布的倾斜情况。可以参考"数据的分布与倾斜"章节获得更多关于数据倾斜的信息。

随机分布并不能绝对的保证每个Instance上的数据数量完全相同,或者误差在数条以内,但可以绝对的保证数据的相对均衡。官方文档说,差异会小于10%,编者不清楚这个数字是怎么来的,根据编者的经验,对于数据量较大的表来说,RANDOMLY分布Instance之间的记录数差异极小,远小于10%,编者认为10号可能是最坏的情况。

优秀的分布策略,对于大表与大表的关联,至关重要,对于GP来说,要执行表与表的关联,相关的记录必须在同一个Instance上,如果相关的记录不在同一个Instance上,则,在执行查询的过程中,必须在Instance之间进行动态的数据重分布,当然,有些时候还可能会是广播操作。重分布,是将所有的数据根据关联字段重新计算HASH值并确定数据重新分发到其他Instance,而广播,是将表中的所有数据在每个Instance上分发一份完整的拷贝。

posted @ 2024-12-25 15:19  数据库小白(专注)  阅读(25)  评论(0编辑  收藏  举报