[原创] Apache Pig如何按数据分组保存到不同的子目录中(MultiStorage)

查看更多Apache Pig的教程请点击这里

用Apache Pig进行数据处理的时候,我们通常会在最后把处理结果保存到一个HDFS目录下:

STORE result INTO '/my_output_dir';

这是最常见的情况。
但是,如果我们想根据某个字段,把数据分成多组,分别存储在多个目录下呢?举个可能不恰当的例子,就有点像我们先把数据按某个字段分组:

GROUP data BY field;

再把各个group的数据分别存储在不同的目录下一样。

现在来看一个实例。
假设有如下数据(用 tab 分隔的四列分别为:人员类型的id,人员类型的描述,姓名,爱好):

type desc name hobby
2 学生 陈玉 篮球
3 老师 王强 足球
1 保安 许勤 下棋
2 学生 范雨 跑步
2 学生 李林 游泳
1 保安 涂欣 看书

文章来源:https://www.codelast.com/
现在我们想按第1列 type,把这份数据处理之后分别存储到不同的目录下,即 type 2(学生)的数据保存到目录"2"里,type 3(老师)的数据保存到目录"3"里,依此类推。
一个最简单也最笨的方法是: 在Pig中把数据 SPLIT(拆分) 成多份,再分别 STORE(存储) 到指定的目录下:

A = LOAD '1.txt' AS (typeintdesc: chararray, name: chararray, hobby: chararray);
SPLIT A INTO A1 IF (type == 1), A2 IF (type == 2), A3 IF (type == 3);

STORE A1 INTO '/my_output_dir/1';
STORE A2 INTO '/my_output_dir/2';
STORE A3 INTO '/my_output_dir/3';

代码很直观,但当 type 有太多种数值的时候,比如说type有100种数值,难道你打算写100个 STORE 语句吗?会疯。
文章来源:https://www.codelast.com/
更好的办法是利用piggybank里的一个UDF MultiStorage来实现同样的功能:

A = LOAD '1.txt' AS (typeintdesc: chararray, name: chararray, hobby: chararray);
STORE A INTO '/my_output_dir' USING org.apache.pig.piggybank.storage.MultiStorage('/my_output_dir', '0', 'none', '\t', 'true');

看,只要一行代码就代替了无数的 SPLIT INTO 以及 STORE INTO 语句,多么优雅。
MultiStorage的参数含义分别是:

public MultiStorage(String parentPathStr, String splitFieldIndex, String compression, String fieldDel, String isRemoveKeys)

parentPathStr:输出文件的父目录。事实上这个参数不起作用,真正起作用的输出路径是在 "INTO" 关键字后面的那个路径里指定的,但开发团队为了向前兼容,保留了这个参数,因此,把这个参数里的路径,设置成和 "INTO" 后面的路径一样即可。
splitFieldIndex:使用数据里的第几个字段来拆分数据存储到不同的子目录下(从0开始)。我这里设置成0,是表示我使用数据里的 type 字段来拆分数据。
compression:输出数据的压缩方式,可以是 'bz2','bz','gz','none'这几种取值,其中 none 表示无压缩。
fieldDel:输出数据多个字段的分隔符。
isRemoveKeys:输出数据是否移除掉用于拆分数据的字段。我这里设置成 true 表示在输出数据中不会包含 type,因为我只想拿 type 用作输出子目录名,不想让它出现在输出数据中。
文章来源:https://www.codelast.com/
最后我们看一下执行结果。生成了3个目录,每个 type 一个目录:

/my_output_dir/1
/my_output_dir/2
/my_output_dir/3
/my_output_dir/_SUCCESS

再来看一下子目录"1"里的文件:

/my_output_dir/1/1-0,000

其文件内容是:

保安    许勤    下棋
保安    涂欣    看书

这里面全是 type 1 的数据。可见 MultiStorage 确实把数据按照 type 拆分并存储在了不同的子目录下。

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):
wechat qrcode of codelast
以及我的微信视频号:

发表评论