searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

GreenPlum 数据相容性介绍

2024-09-11 09:53:25
25
0

数据源

数据源节点有很多种,比如数据表,系统表,函数,外表(foreign data wrapper)。这些数据源节点产生的数据有各自的分布特性。而对于中间节点,比如连接,聚合,集合操作,为了能够实现特定的处理逻辑,对数据的分布特性同样有特定的要求。数据的分布特性在Greenplum中称为Locus。下表列举了Locus的类型和其分布特性的说明
CdbLocusType_Entry
数据分布在 Master 上
CdbLocusType_SingleQE
数据集中分布在单个执行节点上
CdbLocusType_General
自包含的数据类型,与任何数据类型兼容
CdbLocusType_SegmentGeneral
与 CdbLocusType_General 相同,但是不能应用在 QD 上
CdbLocusType_Replicated
数据在每个 QE 节点上有一份复制
CdbLocusType_Hashed
数据哈希分片,NULL 值被分布到一个 QE
CdbLocusType_HashedOJ
数据哈希分片,但是 NULL 随机分布在多个 QE 上,一般是外连接的结果
CdbLocusType_Strewn
数据以未知的方式分片,通常是随机分布
数据表是数据库中最常见的数据源。Greenplum目前支持两种类型的数据表,普通表和复制表。普通表的数据分布在所有的Segment上,如果用户在创建表的时候,指定了分布键,数据会按照分布键的哈希值分布在各个Segment上,那么这个表的Locus为CdbLocusType_Hashed。如果用户在建表时没有指定分布键,数据会随机分布到各个Segment,那么这个表的分布类型则CdbLocusType_Strewn。复制表中,每个Segment都有一份完整的数据,所以它的数据分布类型为CdbPathLocus_IsSegmentGenera。
系统表也能够作为查询语句的数据源。在Greenplum中,为了能够在所有的Master和Segment节点上方便的访问系统表信息,几乎所有的系统表在Master和Segment上都存在一份完整的备份,但是当查询语句显式的用到系统表时,优化器认为系统表存在于Master上,所以系统表的Locus为Entry。
FDW是一种数据库对外部数据源的抽象。由于数据库通常并不知道外部数据源的分布情况,或者外部数据源并没有数据分布的概念,又或者外部数据源对于数据分布的抽象与Greenplum不相容。在GreenPlum中默认外部数据是未知分布,所以它的Locus为Strewn。
General是一种跟任何Locus都能相容的数据分布类型。General被称为自包含的类型,这意味着General类型的数据集在任何执行节点上(包括QD和QE),都有完整的数据。所以General可以与任何一种Locus相容。最典型的General数据集是generate_series(1,100)函数,这个函数在任何节点上执行都会按顺序产生1到100的整数。
函数是Greenplum上的一种常见的数据源。在Greenplum中,创建函数时可以指定函数的运行方式,分别为:
  • EXECUTE ON ANY,函数可以运行在任何一个或几个Master或者Segment上,每个函数都能够返回全量的数据,所以函数的Locus为General
  • EXECUTE ON MASTER,函数只能运行在Master上,所以函数的Locus为Entry
  • EXECUTE ON ALL SEGMENTS,函数运行在所有Segment上,所以函数的locus为Strewn
因此大家可能会发现,以上4种数据源并没有涵盖所有的8种Locus。这是因为Join和Motion节点会产生新的Locus。下面的部分将要讨论Locus在Join中的相容性和不同Locus之间的转换。

数据分布的相容性

上文提到,其中一个可能需要添加Motion节点的位置是表连接。表连接的定义是将两个关系中符合连接条件的元组连接在一起,生成一个新的关系。那么在分布式环境中正确的进行Join的前提就是,两个表中符合条件的元组分布在相同的Segment上。那么怎样的数据分布才能保证参加Join的两个输入数据源符合连接条件的元组分布在相同的Segment节点上呢
上图反映了不同的LocusJoin中能否保证符合条件的元组分布在同一个Segment上,通常满足条件的Locus被称为Join相容。上图中黄色的椭圆代表连接运算输入源数据的Locus,浅蓝色的椭圆代表Join生成结果的Locus。两个不同的黄色椭圆通过箭头指向浅蓝色椭圆,代表两个黄色椭圆中的LocusJoin的结果是浅蓝色椭圆中的Locus。黄色椭圆指向自己的箭头表示输入的两个数据源都是黄色椭圆中的Locus,并且连接生成的结果跟输入数据源的Locus相同。
以一个选课系统的例子来验证上图中的Join相容性。在这个选课系统中一共有4张数据表。student是参与选课的学生信息。teacher是课程教师的信息。course是课程信息。enrolled是选课信息
CREATE TABLE student(sid int, sname text, sage int) DISTRIBUTED BY (sid);
CREATE TABLE teacher (tid int, tname text, tage int) DISTRIBUTED BY (tid);
CREATE TABLE enrolled (sid int, cid int, score int) DISTRIBUTED RANDOMLY;
CREATE TABLE course (cid int, cname text, tid int) DISTRIBUTED REPLICATED;
student和teacher的创建语句指定了分布键,所以他们的Locus为CdbLocusType_Hashed。course的创建语句指定为复制表,所以它的Locus为CdbLocusType_SegmentGeneral。enrolled的创建语句指定分布方式为randomly,所以它的Locus为Strewn
以下面的sql为例:
SELECT sid, cid, tid, cname FROM course c, enrolled e WHERE c.cid = e.cid;

表course的Locus为SegmentGeneral,表enrolled的Locus为Strewn。两表在cid字段进行内连接。可以看出Join结果的Locus仍然为Strewn。同理可以推断出Strewn与General/Replicated的连接结果的Locus同样是Strewn。
SELECT tid, tname, cname FROM course c, teacher t WHERE t.tid = c.tid;

表course的Locus为SegmentGeneral,表teacher的Locus为Hashed。两表在tid字段进行内连接。可以看出连接结果的Locus仍然为Hashed。同理可以推断出Hashed与General/Replicated的连接结果的Locus同样是Hashed。
将General/SegmentGeneral/Replicated作为一类进行考虑,统一认为数据是在所有的Segment节点上复制的。那么这类数据Locus就可以与任何其他种类的Locus相兼容,Join的输出结果则为对方的Locus。
Strewn是一种分片的数据分布,但是分片的方法未知。所以数据库只能认为数据是随机分片分布在所有的Segment上。如果对表为General/SegmentGeneral/Replicated,由于对表在任何一个Segment上都含有全量的元组,任何一个符合条件的元组都能在本地找到,所以系统认为两者是Join兼容的。Join输出的Locus为Strewn。
select sid, sname, cid from student s, enrolled e where s.sid = e.sid;

反之,Hashed和Strewn则是不相容的两种Locus。由于Strewn的分布是不确定的分布,所以如果与Strewn进行Join的数据分布类型在每个Segment上没有全量的元组,那么Join的结果就会缺失很多数据。
Hashed/HashedOJ也是一种分片的数据分布,分片方式为按照分布键上的哈希值进行分布。Hashed与HashedOJ的区别在于对空值的处理。HashedOJ是Hashed Outer Join的简写,顾名思义,外连接的结果的分布是HashedOJ。Hashed空值会被分布到同一个Segment,而HashOJ空值会分布在所有的Segment上。同Strewn一样,与General/SegmentGeneral/Replicated是Join兼容的。Join的输出的Locus为Hash。与SingleQE不兼容,因为在除了SingleQE所在的Segment上,任何一个Segment对表都没有数据。与Strewn不兼容,原因是“不能保证在JoinKey上相等的元组分布在相同的Segment上”。与Hash/HashOJ在双方HashKey相同并且是JoinKey的子集时,双方是Join相容的。因为“HashKey相等的元组会被分布到相同的Segment上”。相反,如果不能满足条件,则不相容。

数据重分布

如果参与Join操作的两个表Locus不相容,系统如何才能顺利的完成Join呢?答案对数据进行重新分布。下图描述了Locus之间通过Motion的转化关系

 

在上图中,Locus按照数据分布的大体特征分成三组:
  • SINGLETON:数据分布在单一的节点上,包含SingleQE,Entry两种Locus
  • REPLICATED:数据是复制的,每个节点上都有一份完整的数据复制,包含Replicated,General,SegmentGeneral三种Locus
  • PARTITIONED:数据是分片的,每个节点包含一部分数据,包含Hashed,Strewn,HashedOJ三种Locus
图中的箭头表示Locus之间互相转换使用的Motion:
  • BroadCastMotion:将输入的元组复制发送到所有的Segment节点
  • GatherMotion:将元组发送到一个节点
  • HashedMotion:将元组按照分布键发送到一组Segment节点
以上三组Locus通过Motion互相转化,每组的任意一个Locus通过对应箭头所代表的的Motion转化为另一组的第一个Locus。比如PARTITIONED组Hashed,HashedOJ,Strewn三个Locus中的任意一个,在通过BroadCastMotion都转化为Replicated
0条评论
作者已关闭评论
张****强
2文章数
0粉丝数
张****强
2 文章 | 0 粉丝
张****强
2文章数
0粉丝数
张****强
2 文章 | 0 粉丝
原创

GreenPlum 数据相容性介绍

2024-09-11 09:53:25
25
0

数据源

数据源节点有很多种,比如数据表,系统表,函数,外表(foreign data wrapper)。这些数据源节点产生的数据有各自的分布特性。而对于中间节点,比如连接,聚合,集合操作,为了能够实现特定的处理逻辑,对数据的分布特性同样有特定的要求。数据的分布特性在Greenplum中称为Locus。下表列举了Locus的类型和其分布特性的说明
CdbLocusType_Entry
数据分布在 Master 上
CdbLocusType_SingleQE
数据集中分布在单个执行节点上
CdbLocusType_General
自包含的数据类型,与任何数据类型兼容
CdbLocusType_SegmentGeneral
与 CdbLocusType_General 相同,但是不能应用在 QD 上
CdbLocusType_Replicated
数据在每个 QE 节点上有一份复制
CdbLocusType_Hashed
数据哈希分片,NULL 值被分布到一个 QE
CdbLocusType_HashedOJ
数据哈希分片,但是 NULL 随机分布在多个 QE 上,一般是外连接的结果
CdbLocusType_Strewn
数据以未知的方式分片,通常是随机分布
数据表是数据库中最常见的数据源。Greenplum目前支持两种类型的数据表,普通表和复制表。普通表的数据分布在所有的Segment上,如果用户在创建表的时候,指定了分布键,数据会按照分布键的哈希值分布在各个Segment上,那么这个表的Locus为CdbLocusType_Hashed。如果用户在建表时没有指定分布键,数据会随机分布到各个Segment,那么这个表的分布类型则CdbLocusType_Strewn。复制表中,每个Segment都有一份完整的数据,所以它的数据分布类型为CdbPathLocus_IsSegmentGenera。
系统表也能够作为查询语句的数据源。在Greenplum中,为了能够在所有的Master和Segment节点上方便的访问系统表信息,几乎所有的系统表在Master和Segment上都存在一份完整的备份,但是当查询语句显式的用到系统表时,优化器认为系统表存在于Master上,所以系统表的Locus为Entry。
FDW是一种数据库对外部数据源的抽象。由于数据库通常并不知道外部数据源的分布情况,或者外部数据源并没有数据分布的概念,又或者外部数据源对于数据分布的抽象与Greenplum不相容。在GreenPlum中默认外部数据是未知分布,所以它的Locus为Strewn。
General是一种跟任何Locus都能相容的数据分布类型。General被称为自包含的类型,这意味着General类型的数据集在任何执行节点上(包括QD和QE),都有完整的数据。所以General可以与任何一种Locus相容。最典型的General数据集是generate_series(1,100)函数,这个函数在任何节点上执行都会按顺序产生1到100的整数。
函数是Greenplum上的一种常见的数据源。在Greenplum中,创建函数时可以指定函数的运行方式,分别为:
  • EXECUTE ON ANY,函数可以运行在任何一个或几个Master或者Segment上,每个函数都能够返回全量的数据,所以函数的Locus为General
  • EXECUTE ON MASTER,函数只能运行在Master上,所以函数的Locus为Entry
  • EXECUTE ON ALL SEGMENTS,函数运行在所有Segment上,所以函数的locus为Strewn
因此大家可能会发现,以上4种数据源并没有涵盖所有的8种Locus。这是因为Join和Motion节点会产生新的Locus。下面的部分将要讨论Locus在Join中的相容性和不同Locus之间的转换。

数据分布的相容性

上文提到,其中一个可能需要添加Motion节点的位置是表连接。表连接的定义是将两个关系中符合连接条件的元组连接在一起,生成一个新的关系。那么在分布式环境中正确的进行Join的前提就是,两个表中符合条件的元组分布在相同的Segment上。那么怎样的数据分布才能保证参加Join的两个输入数据源符合连接条件的元组分布在相同的Segment节点上呢
上图反映了不同的LocusJoin中能否保证符合条件的元组分布在同一个Segment上,通常满足条件的Locus被称为Join相容。上图中黄色的椭圆代表连接运算输入源数据的Locus,浅蓝色的椭圆代表Join生成结果的Locus。两个不同的黄色椭圆通过箭头指向浅蓝色椭圆,代表两个黄色椭圆中的LocusJoin的结果是浅蓝色椭圆中的Locus。黄色椭圆指向自己的箭头表示输入的两个数据源都是黄色椭圆中的Locus,并且连接生成的结果跟输入数据源的Locus相同。
以一个选课系统的例子来验证上图中的Join相容性。在这个选课系统中一共有4张数据表。student是参与选课的学生信息。teacher是课程教师的信息。course是课程信息。enrolled是选课信息
CREATE TABLE student(sid int, sname text, sage int) DISTRIBUTED BY (sid);
CREATE TABLE teacher (tid int, tname text, tage int) DISTRIBUTED BY (tid);
CREATE TABLE enrolled (sid int, cid int, score int) DISTRIBUTED RANDOMLY;
CREATE TABLE course (cid int, cname text, tid int) DISTRIBUTED REPLICATED;
student和teacher的创建语句指定了分布键,所以他们的Locus为CdbLocusType_Hashed。course的创建语句指定为复制表,所以它的Locus为CdbLocusType_SegmentGeneral。enrolled的创建语句指定分布方式为randomly,所以它的Locus为Strewn
以下面的sql为例:
SELECT sid, cid, tid, cname FROM course c, enrolled e WHERE c.cid = e.cid;

表course的Locus为SegmentGeneral,表enrolled的Locus为Strewn。两表在cid字段进行内连接。可以看出Join结果的Locus仍然为Strewn。同理可以推断出Strewn与General/Replicated的连接结果的Locus同样是Strewn。
SELECT tid, tname, cname FROM course c, teacher t WHERE t.tid = c.tid;

表course的Locus为SegmentGeneral,表teacher的Locus为Hashed。两表在tid字段进行内连接。可以看出连接结果的Locus仍然为Hashed。同理可以推断出Hashed与General/Replicated的连接结果的Locus同样是Hashed。
将General/SegmentGeneral/Replicated作为一类进行考虑,统一认为数据是在所有的Segment节点上复制的。那么这类数据Locus就可以与任何其他种类的Locus相兼容,Join的输出结果则为对方的Locus。
Strewn是一种分片的数据分布,但是分片的方法未知。所以数据库只能认为数据是随机分片分布在所有的Segment上。如果对表为General/SegmentGeneral/Replicated,由于对表在任何一个Segment上都含有全量的元组,任何一个符合条件的元组都能在本地找到,所以系统认为两者是Join兼容的。Join输出的Locus为Strewn。
select sid, sname, cid from student s, enrolled e where s.sid = e.sid;

反之,Hashed和Strewn则是不相容的两种Locus。由于Strewn的分布是不确定的分布,所以如果与Strewn进行Join的数据分布类型在每个Segment上没有全量的元组,那么Join的结果就会缺失很多数据。
Hashed/HashedOJ也是一种分片的数据分布,分片方式为按照分布键上的哈希值进行分布。Hashed与HashedOJ的区别在于对空值的处理。HashedOJ是Hashed Outer Join的简写,顾名思义,外连接的结果的分布是HashedOJ。Hashed空值会被分布到同一个Segment,而HashOJ空值会分布在所有的Segment上。同Strewn一样,与General/SegmentGeneral/Replicated是Join兼容的。Join的输出的Locus为Hash。与SingleQE不兼容,因为在除了SingleQE所在的Segment上,任何一个Segment对表都没有数据。与Strewn不兼容,原因是“不能保证在JoinKey上相等的元组分布在相同的Segment上”。与Hash/HashOJ在双方HashKey相同并且是JoinKey的子集时,双方是Join相容的。因为“HashKey相等的元组会被分布到相同的Segment上”。相反,如果不能满足条件,则不相容。

数据重分布

如果参与Join操作的两个表Locus不相容,系统如何才能顺利的完成Join呢?答案对数据进行重新分布。下图描述了Locus之间通过Motion的转化关系

 

在上图中,Locus按照数据分布的大体特征分成三组:
  • SINGLETON:数据分布在单一的节点上,包含SingleQE,Entry两种Locus
  • REPLICATED:数据是复制的,每个节点上都有一份完整的数据复制,包含Replicated,General,SegmentGeneral三种Locus
  • PARTITIONED:数据是分片的,每个节点包含一部分数据,包含Hashed,Strewn,HashedOJ三种Locus
图中的箭头表示Locus之间互相转换使用的Motion:
  • BroadCastMotion:将输入的元组复制发送到所有的Segment节点
  • GatherMotion:将元组发送到一个节点
  • HashedMotion:将元组按照分布键发送到一组Segment节点
以上三组Locus通过Motion互相转化,每组的任意一个Locus通过对应箭头所代表的的Motion转化为另一组的第一个Locus。比如PARTITIONED组Hashed,HashedOJ,Strewn三个Locus中的任意一个,在通过BroadCastMotion都转化为Replicated
文章来自个人专栏
学习大数据
2 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0