3

bucket表:数仓存算分离中CU与DN解绑的关键

 1 year ago
source link: https://www.cnblogs.com/huaweiyun/p/17192521.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
摘要:Bucket存储是数据共享中重要的一环,当前阶段,bucket存储可以将列存中的CU数据和DN节点解绑。

本文分享自华为云社区《存算分离之bucket表——【玩转PB级数仓GaussDB(DWS)】》,作者:yd_278301229 。

在云原生环境,用户可以自由配置cup型号、内存、磁盘、带宽等资源,需要在计算和IO之间做平衡;如果计算和存储耦合,扩缩容时数据要在节点之间移动,同时还要对外提供计算,性能会大受影响。如果存算分离,计算出和存储层可以独立增加节点互不干扰,这其中一个关键点是做到数据共享。Bucket存储是数据共享中重要的一环,当前阶段,bucket存储可以将列存中的CU数据和DN节点解绑。

一、bucket表在存算分离中的作用

通过存算分离,把DWS完全的shared nothing架构改造成计算层shared nothing + 存储层shared storage。使用OBS替换EVS,OBS对append only存储友好,与列存CU存储天然适配;由于存算分离数据共享,对写的并发性能不高,在OLAP场景下读多写少更有优势,这一点也是和列存相匹配的,目前主要实现的是列存的存算分。
在当前。bucket表在存储层共享中,为了将CU数据和DN节点解绑,主要做了两件关键的事,CUID和FILEID全局统一管理。我们来看看为什么这两件事能把CU和DN节点解绑以及带来的好处。
为了解释这个问题,先看看目前shared nothing架构中,建库和存储数据的过程。

二,当建立一张列存表并存储数据时,我们在做什么

建一张列存表时,主要要做以下两步:

1,系统表中建立表的数据。
2,为列存建立CUDesc表、Delta表等辅助表

当存储数据时,主要做以下几步:

1,根据数据分布方式,决定数据存储到哪个DN。
2,把列存存储时需要的辅助信息填入CUDesc表、Delta表等辅助表。
3,把存储用户数据的CU存储本地DN。

在上面的过程中,由于DN之间互不干扰,那就需要各自管理自己的存储的表的信息。

CUDesc表的一大功能是CU数据的“指路牌”,就像指针一样,指出CU数据存储的位置。靠的是CUID对应的CUPoint(偏移量),加上存储在DN的文件位置就能标注出具体的CU数据,而文件名就是系统表中的relfilenode。

v2-1741cec2aff7ed51e0de298573298a1b_720w.webp

由于在MPPDB的存算一体中,数据都存储在DN节点,DN节点之间互不干扰,CUID和relfilenode各个DN节点自己管理,只要自己不出问题就行了,也就是“各人自扫门前雪莫管他人瓦上霜”,例如下图,显示一张列存表在集群中的存储状态。

v2-42a31054af5a52af5ed6ecb44e6f8d09_720w.webp

CN把要存储的数据根据分布算法(例如对DN数量做除法取余数)把1,3,5存到DN1,把2,4,6存到DN2。DN1此时生成存储CU文件的relfilenode是12345,每插入一次CUID,就把该表的CUDesc表CUID自增,DN1只要把自己的数据管理好,与DN2无关。DN2同理。

三,数据共享和扩缩容时,遇到的困难

1,数据共享时遇到的困难

如上所述,当用户想查询数据1,2,4,6时,该怎么办。因为DN1和DN2都不可能单独完成任务,就需要共享数据了。问题就来了,DN间肯定是想以最小代价来完成数据共享,系统表最小,CUDesc表也很小(就像指针一样,同等规模下,只有CU数据的1/3000左右),CU数据最大。假如最后决定以DN2来汇聚所有结果,就算DN1把系统表和CUDesc表中的数据传给DN2,DN2也看不懂,因为在DN2上,relfilenode为12345可能是另外一张表,cudesc表为中CUID为1001的CUPoint也不知道是指向哪儿了(data1,data2),没办法,只能是DN1自己计算,最后把data1的CU数据通过stream算子发送给DN2。DN1迫不得已选了最难的那条路,CU的数据量太大,占用了网络带宽,还需要DN1来参与计算,并发上不去。

v2-8f547f72ec2999b758a50bae9a21c8d6_720w.webp

2,扩缩容时遇到的困难

当用户发现DN1,DN2节点不够用时,想要一个DN3,该怎么办。根据分布假设的算法(对DN数量做除法取余数),data3和data6应该要搬去DN3才对。系统表还比较好搬,无非是在DN3上新建一份数据,CUDesc表也好搬,因为数据量小,再把CUID和CUPoint按照DN3的逻辑写上数据就好了,CU数据也要搬,但是因为CU数据量大,会占用过多的计算资源和带宽,同时还要对外提供计算。真是打了几份工,就赚一份工资。

v2-1796fbce4dada16973231d9ed54ad4f6_720w.webp

总结起来,困难主要是

1)系统表元数据(计算元数据)

每个节点有自己的系统表元数据,新增dn必须创建“自己方言”的系统表,而实际上这些系统表内容是“相同的”,但是dn之间互相不理解;

2)CUDesc元数据(存储元数据)

每个节点的CUID自己分配,同一个CUID在不同节点指向不同的数据,CU无法在dn之间迁移,因为迁移后会混乱,必须通过数据重分布生成dn “自己方言的CUID”
CU的可见性信息(clog/csnlog)各自独立管理,dn1读取dn2的cudesc行记录之后,不知道记录是否可见

3)CU用户数据

filepath(relfilenode) dn节点各自独立管理,dn1不知道到哪里读取dn2的数据

四、揭秘CU与DN解绑的关键——bucket表

1,存储映射

bucket表的存储方式如图,CU的管理粒度不再是DN,而是bucket,bucket是抽象出来的一个概念,DN存储的,是系统元数据和bucket对应的CUDesc元数据,由于在bucket作为存储粒度下,CUID和FILEID是全局统一管理的,DN只需要懂全局的规则,并且拿到别的bucket对应的CUDesc元数据,那就可以很方便的去OBS上拿到CU数据了。通过这种方式,把本该存储在DN上的CU数据,映射到OBS上,可以保证DN间共享数据时相互独立,换句话说,每个DN都读的懂其他DN的CUDesc数据,不再需要把CU数据喂到嘴边了。

v2-1551163b831824681581bda611dcfa2d_720w.webp

2,全局CUID和FILEID表生成

CUID不再是各节点自己管理生成,而是全局唯一的。其原因是CUID与bucket号绑定,特定的bucket号只能生成特定的globalCUID,与此同时,relfilenode不再作为存储的文件名,而是作为存储路径。CU存放的文件名为relfilenode/C1_fileId.0,fileId的计算只与bukcet号和seqno有关。

这样V3表就建立起了一套映射关系(以V2表示存算一体表,V3表示为bucket表):

step 1,数据插入哪一个bucket由分布方式来确定,例如是RR分布,那么就是轮巡插入bucket。
step 2,CUID是多少,由bucket粒度级别的CUID来确定,比如+1自增作为下一个CUID。
step 3,在bucket上存储bucket粒度级别的fileId。
step 4,生成全局唯一fileId,由bucketid和bucket粒度级别的fileId来生成,对应生成的CU插入该fileId文件名的文件。
setp 5,生成全局唯一globalCUID。由bucketid和bucket粒度级别的CUID计算得到全局唯一的globalCUID。

CUDesc表中,也为bucket表新建了一个属性fileId,用来让DN查找到OBS上的CU数据所在的文件。

v2-d5da37c0c0cafc10c0f013543e20f86e_720w.webp

3,共享数据和扩缩容的便利

如上所述,DN可以通过全局CUID和FILEID来找到CU数据,在数据共享时,不再需要其他DN参与大量的计算和搬迁CU,扩缩容时,也不需要搬迁CU了,只需要正确生成系统表中的信息和搬迁CUDesc即可。

最后,来看一看bucket表在OBS上存储的CU数据:

v2-ea00659bd91cdc8cb169ba1a5fa231a7_720w.webp

点击关注,第一时间了解华为云新鲜技术~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK