玩转大数据系列之Apache Pig高级技能之函数编程(六)

原创不易,转载请务必注明,原创地址,谢谢配合!
http://qindongliang.iteye.com/



Pig系列的学习文档,希望对大家有用,感谢关注散仙!

Apache
Pig的前世今生

Apache Pig如何自定义UDF函数?

Apache
Pig5行代码怎么实现Hadoop的WordCount?

Apache
Pig入门学习文档(一)

Apache Pig学习笔记(二)

Apache
Pig学习笔记之内置函数(三)

玩转大数据系列之Apache Pig如何与Apache Lucene集成(一)

玩转大数据系列之Apache
Pig如何与Apache Solr集成(二)

玩转大数据系列之Apache
Pig如何与MySQL集成(三)

玩转大数据系列之如何给Apache Pig自定义存储形式(四)

玩转大数据系列之Apache
Pig如何通过自定义UDF查询数据库(五)

如何使用Pig集成分词器来统计新闻词频?

在Hadoop的生态系统中,如果我们要离线的分析海量的数据,大多数人都会选择Apache
Hive或Apache Pig,在国内总体来说,Hive使用的人群占比比较高,
而Pig使用的人相对来说,则少的多,这并不是因为Pig不成熟,不稳定,而是因为Hive提供了类数据库SQL的查询语句,使得大多人上手Hive非常容易,相反而Pig则提供了类Linux
shell的脚本语法,这使得大多数人不喜欢使用。

如果在编程界,统计一下会SQL和会shell,那个人数占的比重大,散仙觉得,毫无疑问肯定是SQL语句了。因为有相当一部分编程人员是不使用Linux的,而是微软的的一套从C#,到ASP.NET,SQL
Server再到Windows的专用服务器 。

OK,扯远了,赶紧回来,使用shell的攻城师们,我觉得都会爱上它的,因为在linux系统中,没有比shell更简洁易用了,如果再配上awk和sed更是如虎添翼了。

我们都知道shell是支持函数调用的,这一点和JavaScript是非常类似的,通过定义函数我们可以重复使用某个功能,而不用再次大量编码,其中,把变的东西,分离成参数,不变的东西定义成语句,这样以来,就能够降低编码的冗余和复杂性,试想一下,如果Java里,没有方法,那将会是多么不可思议的一件事。

Pig作为类shell的语言,也支持了函数的方式,封装某个功能,以便于我们重用,这一点相比Hive来说,是一个很好的优势。

下面先看下定义Pig函数(也叫宏命令)定义的语法:

DEFINE (macros) :
支持的参数:

alias  pig的标量引用
整形(integer)
浮点型(float)
字符串(String)

下面看几个例子,让我们迅速对它熟悉并掌握,先看下我们的测试数据:

Java代码  

  1. 1,张三,男,23,中国
  2. 2,张三,女,32,法国
  3. 3,小花,男,20,英国
  4. 4,小红,男,16,中国
  5. 5,小红,女,25,洛阳
  6. 6,李静,女,25,中国河南安阳
  7. 7,王强,男,11,英国
  8. 8,张飞,男,20,美国
1,张三,男,23,中国
2,张三,女,32,法国
3,小花,男,20,英国
4,小红,男,16,中国
5,小红,女,25,洛阳
6,李静,女,25,中国河南安阳
7,王强,男,11,英国
8,张飞,男,20,美国

再看下pig脚本:

Java代码  

  1. --定义pig函数1 支持分组统计数量
  2. DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {
  3. d = group $A by $group_key parallel $number_reduces;
  4. $B = foreach d generate group, COUNT($1);
  5. };
  6. --定义pig函数2 支持排序
  7. --A 关系引用标量
  8. --order_field 排序的字段
  9. --order_type 排序方式 desc ? asc ?
  10. --storedir 存储的HDFS路径
  11. --空返回值
  12. define my_order(A,order_field,order_type,storedir) returns void {
  13. d = order $A by $order_field $order_type ;
  14. store  d into ‘$storedir‘ ;
  15. };
  16. --定义pig函数3,支持filter过滤,以及宏命令里面调用
  17. --定义过滤操作
  18. define  myfilter (A,field,count) returns B{
  19. b= filter $A by $field > $count ;
  20. $B = group_and_count(b,‘sex‘,1);
  21. };
  22. a = load  ‘/tmp/dongliang/318/person‘ using PigStorage(‘,‘) AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;
  23. --------pig函数1测试-----------------
  24. --定义按名字分组
  25. --bb = group_and_count(a,name,1);
  26. --定义按性别分组
  27. --cc = group_and_count(a,sex,1);
  28. --dump bb;
  29. --dump cc;
  30. -------pig函数2测试------------------
  31. --按年龄降序
  32. --my_order(a,age,‘desc‘,‘/tmp/dongliang/318/z‘);
  33. --dump a;
  34. -------pig函数3测试------------------
  35. --过滤年龄大于20的,并按性别,分组统计数量
  36. r =  myfilter(a,‘age‘,20);
  37. dump r;
--定义pig函数1 支持分组统计数量
DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {

 d = group $A by $group_key parallel $number_reduces;

 $B = foreach d generate group, COUNT($1);

};

--定义pig函数2 支持排序
--A 关系引用标量
--order_field 排序的字段
--order_type 排序方式 desc ? asc ?
--storedir 存储的HDFS路径
--空返回值
define my_order(A,order_field,order_type,storedir) returns void {

  d = order $A by $order_field $order_type ;
  store  d into ‘$storedir‘ ;  

}; 

--定义pig函数3,支持filter过滤,以及宏命令里面调用

--定义过滤操作
define  myfilter (A,field,count) returns B{

   b= filter $A by $field > $count ;

   $B = group_and_count(b,‘sex‘,1);

};

a = load  ‘/tmp/dongliang/318/person‘ using PigStorage(‘,‘) AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;

--------pig函数1测试-----------------

--定义按名字分组
--bb = group_and_count(a,name,1);
--定义按性别分组
--cc = group_and_count(a,sex,1);
--dump bb;
--dump cc;

-------pig函数2测试------------------

--按年龄降序
--my_order(a,age,‘desc‘,‘/tmp/dongliang/318/z‘);

--dump a;

-------pig函数3测试------------------

 --过滤年龄大于20的,并按性别,分组统计数量
 r =  myfilter(a,‘age‘,20);

dump r;

在上面的脚本中,散仙定义了三个函数,
(1)分组统计数量
(2)自定义输出存储

(3)自定义过滤并结合(1)统计数量

通过这3个例子,让大家对pig函数有一个初步的认识,上面的函数和代码都在一个脚本中,这样看起来不太友好,而且重用性,还没有得到最大发挥,实际上函数和主体脚本是可以分离的,再用的时候,我们只需要导入函数脚本,即可拥有所有的函数功能,这样一来,函数脚本被分离到主脚本外面,就大大增加了函数脚本的重用性,我们也可以再其他脚本中引用,而且函数脚本中也可以再次引用其他的函数脚本,但前提是不能够,递归引用,这样Pig语法在执行时,是会报错的,下面看下分离后的脚本文件:

一:函数脚本文件

Java代码  

  1. --定义pig函数1 支持分组统计数量
  2. --A 关系引用标量
  3. --group_key 分组字段
  4. --使用reduce的个数
  5. --返回最终的引用结果
  6. DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {
  7. d = group $A by $group_key parallel $number_reduces;
  8. $B = foreach d generate group, COUNT($1);
  9. };
  10. --定义pig函数2 支持排序
  11. --A 关系引用标量
  12. --order_field 排序的字段
  13. --order_type 排序方式 desc ? asc ?
  14. --storedir 存储的HDFS路径
  15. --空返回值
  16. define my_order(A,order_field,order_type,storedir) returns void {
  17. d = order $A by $order_field $order_type ;
  18. store  d into ‘$storedir‘ ;
  19. };
  20. --定义pig函数3,支持filter过滤,以及宏命令里面调用
  21. --A 关系引用标量
  22. --field 过滤的字段
  23. --count 阈值
  24. --返回最终的引用结果
  25. define  myfilter (A,field,count) returns B{
  26. b= filter $A by $field > $count ;
  27. $B = group_and_count(b,‘sex‘,1);
  28. };
  29. [search@dnode1 pigmacros]$
--定义pig函数1 支持分组统计数量
--A 关系引用标量
--group_key 分组字段
--使用reduce的个数
--返回最终的引用结果
DEFINE group_and_count (A,group_key,number_reduces) RETURNS B {

 d = group $A by $group_key parallel $number_reduces;

 $B = foreach d generate group, COUNT($1);

};

--定义pig函数2 支持排序
--A 关系引用标量
--order_field 排序的字段
--order_type 排序方式 desc ? asc ?
--storedir 存储的HDFS路径
--空返回值
define my_order(A,order_field,order_type,storedir) returns void {

  d = order $A by $order_field $order_type ;
  store  d into ‘$storedir‘ ;  

}; 

--定义pig函数3,支持filter过滤,以及宏命令里面调用
--A 关系引用标量
--field 过滤的字段
--count 阈值
--返回最终的引用结果

define  myfilter (A,field,count) returns B{

   b= filter $A by $field > $count ;

   $B = group_and_count(b,‘sex‘,1);

};

[[email protected] pigmacros]$ 


二,主体脚本文件

Java代码  

  1. --导入pig公用的函数库
  2. import ‘function.pig‘ ;
  3. a = load  ‘/tmp/dongliang/318/person‘ using PigStorage(‘,‘) AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;
  4. --------pig函数1测试-----------------
  5. --定义按名字分组
  6. --bb = group_and_count(a,name,1);
  7. --定义按性别分组
  8. --cc = group_and_count(a,sex,1);
  9. --dump bb;
  10. --dump cc;
  11. -------pig函数2测试------------------
  12. --按年龄降序
  13. --my_order(a,age,‘desc‘,‘/tmp/dongliang/318/z‘);
  14. --dump a;
  15. -------pig函数3测试------------------
  16. --过滤年龄大于20的,并按性别,分组统计数量
  17. r =  myfilter(a,‘age‘,20);
  18. dump r;
--导入pig公用的函数库

import ‘function.pig‘ ;

a = load  ‘/tmp/dongliang/318/person‘ using PigStorage(‘,‘) AS (id:int,name:chararray,sex:chararray,age:int,address:chararray) ;

--------pig函数1测试-----------------

--定义按名字分组
--bb = group_and_count(a,name,1);
--定义按性别分组
--cc = group_and_count(a,sex,1);
--dump bb;
--dump cc;

-------pig函数2测试------------------

--按年龄降序
--my_order(a,age,‘desc‘,‘/tmp/dongliang/318/z‘);
--dump a;

-------pig函数3测试------------------

 --过滤年龄大于20的,并按性别,分组统计数量
 r =  myfilter(a,‘age‘,20);
 dump r;

需要注意的是,导入的函数文件,需要用单引号引起来,这样我们就完成了pig函数的重用,是不是非常类似shell的语法呢?有兴趣的同学们,赶紧体验一把吧!  

时间: 2024-10-22 01:38:55

玩转大数据系列之Apache Pig高级技能之函数编程(六)的相关文章

玩转大数据系列之Apache Pig如何与Apache Solr集成(二)

散仙,在上篇文章中介绍了,如何使用Apache Pig与Lucene集成,还不知道的道友们,可以先看下上篇,熟悉下具体的流程. 在与Lucene集成过程中,我们发现最终还要把生成的Lucene索引,拷贝至本地磁盘,才能提供检索服务,这样以来,比较繁琐,而且有以下几个缺点: (一)在生成索引以及最终能提供正常的服务之前,索引经过多次落地操作,这无疑会给磁盘和网络IO,带来巨大影响 (二)Lucene的Field的配置与其UDF函数的代码耦合性过强,而且提供的配置也比较简单,不太容易满足,灵活多变的

玩转大数据系列之Apache Pig如何通过自定义UDF查询数据库(五)

GMV(一定时间内的成交总额)是一个衡量电商网站营业收入的一项重要指标,例如淘宝,京东都有这样的衡量标准,感兴趣的朋友可以自己科普下这方面的概念知识. 当然散仙今天,并不是来解释概念的,而是记录下最近工作的一些东西,原来我们平台的GMV只有一个总的成交金额,并没有细分到各个系统的GMV的比重,比如搜索端,推荐端,移动端等等. 通过细粒度的分析各个系统所占的比重,对于指导各个系统完善和发展有一定的重要意义,这里不就深说了,下面先来看下散仙分析的搜索gmv的数据布局方式. (1)Hadoop集群上,

玩转大数据系列之Apache Pig如何与MySQL集成(三)

上篇介绍了如何把Pig的结果存储到Solr中,那么可能就会有朋友问了,为什么不存到数据库呢? 不支持还是? 其实只要我们愿意,我们可以存储它的结果集到任何地方,只需要重写我们自己的StoreFunc类即可. 关于如何将Pig分析完的结果存储到数据库,在pig的piggy贡献组织里,已经有了对应的UDF了,piggybank是非apache官方提供的工具函数,里面的大部分的UDF都是,其他公司或着个人在后来使用时贡献的,这些工具类,虽然没有正式划入pig的源码包里,但是pig每次发行的时候,都会以

大数据系列(2)——Hadoop集群坏境CentOS安装

前言 前面我们主要分析了搭建Hadoop集群所需要准备的内容和一些提前规划好的项,本篇我们主要来分析如何安装CentOS操作系统,以及一些基础的设置,闲言少叙,我们进入本篇的正题. 技术准备 VMware虚拟机.CentOS 6.8 64 bit 安装流程 因为我的笔记本是Window7操作系统,然后内存配置,只有8G,内存配置太低了,当然为了演示,我会将Hadoop集群中的主节点分配2GB内存,然后剩余的三个节点都是1GB配置. 所有的节点存储我都设置为50GB. 在安装操作系统之前,我们需要

大数据系列之分布式数据库HBase-1.2.4+Zookeeper 安装及增删改查实践

之前介绍过关于HBase 0.9.8版本的部署及使用,本篇介绍下最新版本HBase1.2.4的部署及使用,有部分区别,详见如下: 1. 环境准备: 1.需要在Hadoop[hadoop-2.7.3] 启动正常情况下安装,hadoop安装可参考LZ的文章 大数据系列之Hadoop分布式集群部署 2. 资料包  zookeeper-3.4.9.tar.gz,hbase-1.2.4-bin.tar.gz 2. 安装步骤: 1.安装zookeeper 1.解压zookeeper-3.4.9.tar.gz

大数据系列之数据仓库Hive原理

Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用及JDBC连接 Hive的工作原理简单来说就是一个查询引擎 先来一张Hive的架构图: Hive的工作原理如下: 接收到一个sql,后面做的事情包括:1.词法分析/语法分析 使用antlr将SQL语句解析成抽象语法树-AST2.语义分析 从Megastore获取模式信息,验证SQL语句中队表名,列名

大数据系列之分布式计算批处理引擎MapReduce实践

关于MR的工作原理不做过多叙述,本文将对MapReduce的实例WordCount(单词计数程序)做实践,从而理解MapReduce的工作机制. WordCount: 1.应用场景,在大量文件中存储了单词,单词之间用空格分隔 2.类似场景:搜索引擎中,统计最流行的N个搜索词,统计搜索词频率,帮助优化搜索词提示. 3.采用MapReduce执行过程如图 3.1MapReduce将作业的整个运行过程分为两个阶段 3.1.1Map阶段和Reduce阶段 Map阶段由一定数量的Map Task组成 输入

大数据系列之分布式计算批处理引擎MapReduce实践-排序

清明刚过,该来学习点新的知识点了. 上次说到关于MapReduce对于文本中词频的统计使用WordCount.如果还有同学不熟悉的可以参考博文大数据系列之分布式计算批处理引擎MapReduce实践. 博文发表后很多同学私下反映对于MapReduce的处理原理没有了解到.在这篇博文中楼主与大家交流下MapReduce的数据处理原理及MR中各角色的职责. 文末还有示例代码讲解.. 1.MapReduce中的数据流动 最简单的过程: map - reduce 定制了partitioner以将map的结

大数据系列之三:大数据体系架构的重要里程碑

欧凯惯例:引子 世界上唯一不变的就是变化,大数据的架构也不例外. 这次变化的推动者,多是一些大的商业公司! 首发地址 --- Teradata 美国天睿 Teradata这家公司其实挺陌生的,但这并不能让我们忽视其在大数据方面做出的贡献.简单一句描述这家公司的贡献就是: 2008年之前,这家公司以关系型为基础,硬刚大数据,之后意识到数据实在太大大复杂了,终究实现了对非关系型数据的支持. 具体它拿关系型作为对大数据的解决方案硬刚到什么程度呢?拿一个数据说来说明白了,直到2017年,它可以基于其关系