Understanding Cubert Concepts(二)Co-Partitioned Blocks,partitioned
Understanding Cubert Concepts(二)Co-Partitioned Blocks,partitioned
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 from 0 to 1000 => block 0
memberIds from 1001 to 1500 => block 1
and so on until block 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来进行开发,那么我们必须遵从下面三个准则:
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 dataset
JOB "our first BLOCKGEN"
REDUCERS 10;
MAP {
data = LOAD "/path/to/data" USING AVRO();
}
//根据memberId来作为分区键,根据timestamp来进行sort
BLOCKGEN data BY ROW 1000 PARTITIONED ON memberId SORTED ON timestamp;
//注意,这里必须存储为RUBIX FILE FORMAT
STORE data INTO "/path/to/output" USING RUBIX();
END
JOB "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 data INTO "/path/to/other/output" USING RUBIX();
END
Idiom 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
重排序的键为pagekey
JOB "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 data INTO "/path/to/resorted-output" USING RUBIX();
END
注意:
- 我们要确保使用的还是原始数据集的index
- 并且一定要使用相同的
partition Keys
哦,否则block的数据分布就乱了。
同样,我们可以对数据集B,C都使用indexA进行重排序处理,因为他们都是co-partitioned blocks
参考
Cubert官方文档blocks
Ps:本文的写作是基于对Cubert官方文档的翻译和个人对Cubert的理解综合完成 :)
原创文章,转载请注明:
转载自:OopsOutOfMemory盛利的Blog,作者: OopsOutOfMemory
本文链接地址:http://blog.csdn.net/oopsoom/article/details/46707733
注:本文基于署名-非商业性使用-禁止演绎 2.5 中国大陆(CC BY-NC-ND 2.5 CN)协议,欢迎转载、转发和评论,但是请保留本文作者署名和文章链接。如若需要用于商业目的或者与授权方面的协商,请联系我。
评论暂时关闭