查看更多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 (type: int, desc: 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 (type: int, desc: 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
感谢关注我的微信公众号(微信扫一扫):
以及我的微信视频号: