Understanding Cubert Concepts(二)Co

Understanding Cubert Concepts(二):Cubert Co-Partitioned Blocks

话接上文Cubert PartitionedBlocks,我们介绍了Cubert的核心Block概念之一的分区块,它是一种根据partitionKeys和cost function来对原始数据进行Redistribution和Transformation来结构化数据,这种结构化的数据是对后续join和cube计算是非常有利的。

好了,本文将着重讲Cubert Block中的另一种Block,Co-PartitionedBlock.

Co-partitioned Blocks

让我们来看下另一种创建blocks的方式: 这种方式就是,依靠一个dataset的index来创建“另一个dataset的blocks. 比如: 有一个dataset P 是通过上文Cubert PartitionedBlocks的BLOCKGEN方式生成的。这个dataset P 的内部会将partitionKeys的全局的range划分为sub-ranges,使得每个sub-range的key范围对应了一个block.(Ps:就是定范围的rangeKeys的数据在一个block内)

举个例子:

BLOCKGEN For DataSet P (PartitionedBlocks)

比如我们对dataset P的parititionKey指定为memberId,那么BLOCKGEN过程后,会生成类似如下的索引:

memberIds => block 0memberIds => so N

至此,我们做的都是PartitionedBlocks,如果dataset **S** 要生成Co-paritionedBlocks怎么办呢? 那么索引就是dataset **P**.

BLOCKGEN For DataSet S (Co-partitionedBlocks)

我们要生成与DataSet P 同样number的blocks。(分区都是一致的)

具体来说,就是block i of S会和block i in P有着相同的memberIds,换句话说,如果memberId=1234在block 2 of P中,那么我们能确定能在block 2 of S中找到这个相同的memberId.

对于Map-Side Join来说,这种一致性的分区方法是必要的。

这种根据其它已经partitionedBlock来进行创建一致性分区Block的过程叫做BLOCKGEN BY INDEX

BLOCKGEN BY INDEX Checklist

如果想要使用cubert来进行开发,那么我们必须遵从下面三个准则:

定义primary relation:也就是上面我们创建的DataSet P,指定我们要使用的index,这样我们可以根据这个index来创建BLOCKS。(Ps:这里的说的index,就是primary relation)

Note: BLOCKGEN BY INDEX是一个可传递性的操作,比如,我们有三个数据集A,B,C。我们通过BLOKGEN操作数据集A,然后我们可以将A作为primary relation (可以看做indexA),这样我们就可以根据indexA创建co-partitioned Blocks。现在如果C也要做BLOCKGEN操作怎么办呢,选用A还是B呢?其实这种BLOCKGEN BY INDEX是传递性的,indexA -> Blocks of B (co-partitioned), 那么indexA -> Blocks of C 后, Blocks of B == Blocks of C(这里==的意思是co-partitioned). 所以说BLOCKGEN BY INDEX是一个可传递性的操作。

定义SortKeys(可选) 这个排序也是在每个生成后的block内进行的(根据sortKeys排序),不是全局排序的。

存储为RUBIX FILE FORMAT 原始数据集转化为blocks的操作,存储的格式必须为RUBIX FILE FOMRAT。Creating Co-Partitioned Blocks

要创建Co-PartitionedBlocks,还是需要BLOCKGEN这个shuffle command,通过使用BY INDEX来生成。

首先第一个JOB生成primary dataset(包含index,存储的路径就是下面要生成co-partitionedBlocks的索引路径)第二个BlockGen是通过BY INDEX 指定第primary dataset BLOCKGEN的target path为其索引的。

eg:

// the primary datasetJOB “our first BLOCKGEN”REDUCERS 10;MAP {data = LOAD “/path/to/data” USING AVRO();}//根据memberId来作为分区键,根据timestamp来进行sortBLOCKGEN data BY ROW 1000 PARTITIONED ON memberId SORTED ON timestamp;//注意,这里必须存储为RUBIX FILE FORMATSTORE USING RUBIX();ENDJOB “our first blockgen by index”REDUCERS 20;MAP {data = LOAD “/path/to/other/data” USING AVRO();}//注意 INDEX的 Path 为 上一个JOB的存储目录BLOCKGEN data BY INDEX “/path/to/output” PARTITIONED ON memberId SORTED ON some_column;STORE USING RUBIX();ENDIdiom of Resorting Blocks

BLOCKGEN BY INDE命令还有另一种用途,对于已创建过的Blocks进行重新排序

在上一个例子里的our first BLOCKGEN JOB里,我们是对blocks内部根据timestamp键来进行排序的。如果我想重新指定排序键,怎么做呢?

将生成Blocks后的数据集重新从存储路径(/path/to/output)使用RUBIX FILE FORMAT加载进来使用相同的路径自引用索引/path/to/output来BLOCKGEN BY INDEX,并且指定sorted on pagekey 重排序的键为pagekeyJOB “resorting blocks”REDUCERS 10;MAP {data = LOAD “/path/to/output” USING RUBIX();}BLOCKGEN data BY INDEX “/path/to/output” PARTITIONED ON memberId SORTED ON pagekey;STORE USING RUBIX();END

注意:

我们要确保使用的还是原始数据集的index并且一定要使用相同的partition Keys哦,否则block的数据分布就乱了。

同样,我们可以对数据集B,C都使用indexA进行重排序处理,因为他们都是co-partitioned blocks

参考

Cubert官方文档blocks

Ps:本文的写作是基于对Cubert官方文档的翻译和个人对Cubert的理解综合完成 :)

原创文章,转载请注明:

转载自:OopsOutOfMemory盛利的Blog,,作者: OopsOutOfMemory

本文链接地址:

注:本文基于署名-非商业性使用-禁止演绎 2.5 中国大陆(CC BY-NC-ND 2.5 CN)协议,欢迎转载、转发和评论,但是请保留本文作者署名和文章链接。如若需要用于商业目的或者与授权方面的协商,请联系我。

不知道来年,会不会开出一地的记忆和忧愁。

Understanding Cubert Concepts(二)Co

相关文章:

你感兴趣的文章:

标签云: