Pig Latin分析报告_第1页
Pig Latin分析报告_第2页
Pig Latin分析报告_第3页
Pig Latin分析报告_第4页
Pig Latin分析报告_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、PIG LATIN 简简介介对海量数据的按需分析处理需求不断增加,尤其是对于因特网公司,它们的技术革新主要依赖于对每天收集的数据的分析处理能力。要提高如此巨大数据集的存储和分析效率,必须采用高度并行的系统,例如:shared-nothing cluster。并行数据库产品,如:Teradata 提供了一种解决方案,但是这种方案的 web 规模扩展开销太大,性价比不高,而且为程序员提供了一种不太自然的编程语言-SQL。事实上很多程序员更加偏爱过程式程序设计语言,因为这种语言的数据流更加清晰,便于分析和调试。这也是 map/reduce 编程模型流行的原因之一。另外 map/reduce 的运行于

2、普通商业硬件组成的集群,软件框架保证了可靠性和可用性,通过低端硬件实现了高性能计算,这也是 map/reduce 的优势所在。尽管如此,map/ reduce 也存在一些限制,它的单输入,两阶段数据流编程模式过于苛刻,对于超出该限制之外的数据分析任务,需要进行一些额外的数据转换。另外,它没有通用操作子,即使是对最通用的操作,如:projection 和filtering。这些限制导致 map/reduce 代码重用性和可维护性不高,任务的分析语义不够清晰,将对系统性能优化造成影响。基于以上问题,Yahoo!开发了一种新的基于数据流的大规模数据分析处理语言-Pig Latin,该语言借鉴了 SQ

3、L 和 map/reduce 两者的优点,既具有类似 SQL的灵活可变式性,又有过程式语言的数据流特点。首先以一个例子来直观感受 Pig Latin 的特点:假设我们有一个表 urls:(url,category,pagerank)下面是一个简单的 SQL 查询,对每个足够大的分类,找出其包含的高pagerank 的平均值。查询如下:SELECT category,AVG(pagerank)FROM urls WHERE pagerank0.2GROUP BY category HAVING COUNT(*)106与上述 SQL 等价的 Pig Latin 程序如下:good_urls=FIL

4、TER urls BY pagerank0.2;groups=GROUP good_urls BY category;big_groups=FILTER groups BY COUNT(good_urls)106;output=FOREACH big_groups GENERATEcategory, AVG(good_urls.pagerank);可见,Pig Latin 是一种一步一步顺序执行的编程语言,每一步都完成一次数据转换。这种风格为很多程序员所喜爱。同时每步的转换也都是高级抽象,例如:filtering,grouping,aggregation,抽象级别类似于 SQL。事实上,Pig

5、 Latin 程序更像是对查询执行计划的规范。因此更易于程序员理解和控制。Pig Latin 的实现系统叫 pig,Yahoo!的程序员使用 pig 对大规模数据进行分析处理。Pig Latin 程序被编译为 mapreduce 作业,在 hadoop 上执行。特特点点和和动动机机数数据据流流语语言言Pig Latin 语言在编程风格上与 SQL 有明显差别,前者凸显了程序的执行数据流,后者只关注最终结果。SQL 更适合于编程经验不丰富的程序员,适合小规模数据集;Pig Latin 更适合有经验的程序员和大规模数据集。尽管 Pig Latin 程序提供了显示的操作序列,但实际的执行计划不一定按

6、照该顺序执行,编译器会根据一定的规则对执行顺序进行一定的优化。举例如下:假设某人对类型为 spam 网页的 url 感兴趣,并且要求高 pagerank,则实现为:spam_urls=FILTER urls BY isSpam(url);highPR_spam_urls=FILTER spam_urls BY pagerank0.8按照上述给出的语句,程序会先找出所有的 spam url,然后按照 pagerank 对spam url 进行过滤。但是这种执行顺序可能是不高效的,尤其是当 isSpam(url)是一个用户定义的大开销函数时。显然,这种情况下更高效的方式是先对全部url 按照 pa

7、gerank 进行过滤,再对过滤后的 url 集合判别是否是 spam_url,得出最终想要的结果集合。快快速速开开始始和和协协同同工工作作能能力力Pig 支持对各种存储格式的查询处理,前提是用户要给出特定的处理函数,该函数能够分析文件内容,提取需要的元组,因此 Pig 不需要像传统数据库管理系统那样在查询数据之前要花费大量时间导入数据。类似地,Pig 程序的输出也会按照用户自定义函数将元组类型转换为特定格式的字节序列。这就简化了后续应用程序对 Pig 输出结果的使用,例如可视化应用程序或者类 Exel 的电子表格应用程序。在像 Yahoo!这样的大公司里,数据生态系统中包含大量的应用,而 P

8、ig只是其中的一个,因此使 Pig 具有操作外部文件中的数据,又具有一定的操作权限是非常重要的,目前 Pig 可以容易地与生态系统中其他应用进行交互。传统数据库管理系统需要将数据导入到系统管理表主要是出于一下三点考虑:1) 保证事务一致性2) 通过元组标识符实现高效的点式查询3) 为用户管理数据,记录模式信息以方便其他用户理解但是,Pig 只支持只读式数据分析,对数据的读取是顺序的,因此不需要事务一致性保证和基于索引的查询。Pig 通常被用于分析每天或者每两天产生的临时数据集,不需要长期保留,因此数据托管和模式管理也是多余的。Pig 对模式的支持是可有可无的,用户可以在任何时候提供模式信息,也

9、可以不提供。以我们在第一部分给出的例子为例,如果用户知道存储 url 表文件的第三个域是 pagerank 而不想在程序中提供模式,则第一行可以等价表示为:good_urls=FILTER urls BY $20.2嵌嵌套套式式数数据据模模型型很多时候,程序员想使用嵌套数据结构,例如:为获取术语在一组文件中出现的位置信息,程序员就一定希望为每个术语创建一个类似于MapdocumentId,Set的结构。对于数据库而言,只允许扁平式表的存在,即只有原子字段可以作为列,否则会违反第一范式(1NF)。在满足第一范式的条件下抓取术语位置信息就要求创建两个表,对数据进行标准化处理:term_info:(

10、termId,termString,)position_info: (termId,documentId,positon)然后按照 termId 进行表连接,再按照 termId 和 documentId 进行分组。Pig Latin 具有灵活的,完全嵌套的数据模型,允许复杂的非原子数据类型(set,map,tuple)作为一个表的字段。嵌套数据类型比 1NF 更适合 Pig 的执行环境,主要是出于一下几点考虑:嵌套式数据模型更符合程序员在编程过程中的需求,对他们来讲这种数据模型比标准化数据格式更加自然。存储在磁盘上的数据本身往往具有嵌套的特点。比如,web 爬虫程序为每个 url 和来自该

11、url 的外部连接集合产生输出。Pig 是直接对文件进行操作,将这种 web 规模的数据进行标准化,然后再通过多次表连接进行数据重组显然是不现实的。嵌套数据模型有助于完成前边介绍的代数式语言目标,即一步一步执行,每步只完成一次数据转换。例如,GROUP 原语产生的每个输出元组都会有一个非原子字段(来自于 GROUP 输入中属于每个组的所有元组的嵌套集合)。嵌套数据模型有助于用户写出各式各样的用户定义函数(UDF),关于 UDF将在下一节给出介绍。用用户户自自定定义义函函数数( UDF)对搜索日志,爬虫数据,点击流等数据分析的关键就是定制化处理。例如,一个用户对搜索词的自然语言填充感兴趣,或者判

12、断一个特殊的网页是否是spam 等都需要定制化处理。为完成这种特殊的数据处理任务,Pig Latin 提供 UDF 实现扩展支持。事实上,Pig Latin 的所有处理(包括 grouping,filtering,joining 和 per-tuple processing)都可以通过 UDF 定制。UDF 的输入和输出都可以使用嵌套数据模型,即可以使用非原子参数作为输入,输出也可以表示为非原子参数。考虑下面一个例子。继续以第一个例子的设置为例,假设我们想为每个 category,根据 url 的pagerank 找出 top10 urls。可以使用 Pig Latin 表示为:groups=

13、 GROUP urls BY category;output= FOREACH groups GENERATE category, top10(urls)其中 top10 就是一个 UDF,接收一组 url 作为输入(每次针对一个组),为每个组输出一个按 pagerank 排序前 10 位的 urls,该输出包含了一个非原子字段。目前,Pig 的 UDF 需要用 java 实现,正在开发对其他语言的支持。并并行行化化需需求求Pig Latin 的目标是处理 web 规模的数据,因此它在实现时屏蔽了所有非并行的计算,即它只实现了一些容易并行处理的原语,不容易并行处理的原语(如:非等价表连接以及相

14、关子查询)都没有被实现。但是,这些操作可以通过 UDF 来实现,Pig Latin 不显式提供非并行原语,用户就可以很容易发现程序中瓶颈。调调试试环环境境任何一种语言实现的应用程序,都要经历一个运行-调试-运行的循环迭代过程。这就需要一个调试环境,而对于 Pig 处理的数据规模而言,每次运行往往花费几十分钟甚至数小时,因此需要定制一种高效的调试环境。Pig 开发了一种特定的交互式调试环境,对程序运行的每个步骤都以一个简单测试数据表来测试每步产生的输出结果。测试数据尽可能模拟真实数据,也基本可以完全表达程序的语义,并且,测试数据会随着程序的进化而自动调整,而不是固定不变的。一步一步执行的测试数据

15、有助于尽早发现错误(甚至可能在全数据集上第一次迭代执行之前),可以准确定位错误位置。PIG LATIN数数据据模模型型Pig 的数据模型主要有以下四种类型构成:Atom:一个原子类型包括一个简单的原子值(字符串、数等),如:alice。Tuple:一个元组类型由一些列字段组成,每个字段可以是任意类型,例如:(alice,lakers)。Bag:一组 tuples 构成一个 bag,组成 bag 的每个元组是很灵活的,即 bag中的每个 tuple 不需要具有相同的字段数和字段类型。Tuple 可以嵌套,看一个bag 实例:Map:一个 map 由一组数据项和它们关联的索引键组成。和 bag 类

16、型一样,map 中每个数据项的模式也是很灵活的,即所有数据项不需要具有相同类型。但是,索引键必须是原子类型的数据,主要是为了高效查询。下面是一个 map的例子:上例的 map 中,索引键fan of被映射为一个包含两个 tuple 类型的 bag类型,而索引键age被映射为原子类型 20。Map 类型对建模模式随时间变化的数据集非常有用,例如:web 服务器可能需要新添加一个新字段来存储日志信息,新字段可以通过在 map 中添加一个索引键来完成,不需改变现有程序,又可以通过新的程序完成对新字段的访问。再来看看 Pig Latin 的各种表达式类型以及对它们的操作。如下表所示:由上表可见 Pig

17、 Latin 语言的数据模型的灵活性,它可以任意嵌套,这种灵活性有助于完成”嵌套数据类型”一节给出的设计动机。规规范范数数据据输输入入 :LOAD规范数据输入是 Pig Latin 程序的第一步,这一步规范了输入数据的路径,以及数据解序列化方式,即采用什么方法将输入数据转化为 Pig Latin 的数据模型。下面是一个 LOAD 示例:上面的命令规范了三个方面的内容: 输入文件名为:query_log.txt 定制的文件解序列化方法为 myLoad() 加载的元祖由三个字段组成,分别为 userId,queryString 和 timestamp。LOAD 返回一个 bag 句柄,在上例中该句

18、柄指向 queries,可以直接作为后续命令的输入。实际上,该操作的实际效果并没有像数据库那样将数据载入表中,bag 句柄在 Pig Latin 中只是一个逻辑上的概念,即 LOAD 命令仅仅规范了输入文件名以其读取方式,而并没有将数据读取出来,除非用户显式给出命令,如 STORE 命令,该命令将在后面具体介绍。每每元元组组处处理理: FOREACH数据通过 LOAD 命令载入后,就要指定对数据处理的方法。其中一个基本的操作是对数据集中每个元组的处理操作,通过 FOREACH 命令完成。举例如下:上述命令对 queries 中每个元组(tuple)分别处理,每次处理产生一个输出元组。输出元组中

19、第一个字段是输入元组的 userId 字段,第二个字段由用户自定义函数 expandQuery 产生,expandQuery 的输入是输入元组的 queryString 字段。假设 expandQuery 会产生一个 bag 类型,作为输入查询串的扩展。则上述命令完成的数据转换功能可以用图 1 表示:图 1 在 FOREACH+FLATTEN 实例在 FOREACH 命令中,对每个元组的处理是相互独立的,可以完全并行处理,这符合 Pig Latin 语言的完全并行化目标。图 1 中最后一步数据转换涉及一个 flattening 处理,它的作用是对嵌套数据类型的消解,每个 FLATTEN 消除一

20、层嵌套。命令如下:数数据据过过滤滤命命令令: FILTER该命令 Pig Latin 中又一个非常常用的命令,功能是保留一些想要的子数据集,丢弃其余,下面是一个具体的例子:该例子完成的功能是过滤掉用户bot的信息,采用的操作子为 neq,是一种字符串比较操作子,与其对应的还有 eq,另外还有其他类型的过滤操作子,如:数字比较操作子(=,!=)和逻辑连接子(AND,OR,NOT)。FILTER 命令的比较标准可以采用任意的表达式实现,因此,我们也可以采用 UDFs 的方式实现上述功能,考虑,上述命令在实际中可能不会很好地实现我们想要达到的效果,因为用户bot可能不唯一,因此一种更好的实现方式如下

21、:分分组组聚聚集集: COGROUP数据处理过程中经常需要将一个或多个数据集中的元组按照它们的相关性进行分组聚集,以便于对它们进行联合处理。在 Pig Latin 中这种功能通过COGROUP 命令完成。假设我们通过 LOAD 命令得到两个数据集,分别为:其中 results 包含了不同的搜索串,用 url 表示的搜索结果以及它们在搜索结果列表中出现的位置。而 revenue 包含不同的搜索串,广告位置以及搜索串关联的广告在指定位置获取的广告费收入。下面按照 queryString 字段对两个数据集进行分组聚集,命令如下:该命令产生的结果如图 2 所示:图 2 COGROUP 与 JOIN一般

22、,COGROUP 命令的输出包含一些列元组,每个组对应一个元组。每个元组的第一个字段是组标识符,唯一标识了一个组。后续每个字段都是一个bag,每个来自于一个输入数据集。第 i 个 bag 包含第 i 个输入中对应每个组的所有输入元组。有人可能会质疑 COGROUP 原语的必要性,因为它的功能和 JOIN 操作很类似,图 2 对两者做出了比较。显然,JOIN 等价于对 COGROUP 结果中每个bag 字段进行叉积。其实 JOIN 只是 COGROUP 的目标之一,在叉积之前,通过对 COGROUP 结果进行定制化操作可以得到多种结果,而不单单是 JOIN 的效果。这一点可以通过下面一个例子做进

23、一步解释说明:该例子的目标是找出搜索产生的每个 url 对搜索产生的广告收入的贡献,从而判断每个 url 价值,可以采用如下命令完成:DistributeRevenue 是一个用户定制的处理函数,它以某次查询串搜索产生的 results 和 revenue 信息作为输入参数。输出一个由一些列(url,revenue)元组构成的 bag。假设该函数的处理逻辑是搜索串产生的 top 位置广告收入全部来自于 url 列表中的第一个,slide 位置的广告收入平均分配到每个 url。这种处理逻辑下产生的输出结果如图 2 所示。要使用 SQL 来完成同样的功能,首先 JOIN BY queryStrin

24、g,然后 GROUP BY queryString,最后应用一个定制化的 aggregation。但是在执行连接操作时系统会计算两个表的叉积,而执行 aggregation 是又要去掉叉积的效果,整个处理过程会相当低效,查询也会变得难以理解。其实,COGROUP 语句是 Pig Latin 与 SQL 之间的关键区别,COGROUP遵循前边阐述的 Pig Latin 代数式语言的设计目标,即分布执行,每步只处理一个数据转换。COGROUP 只完成将对所有输入数据集的元组聚集,对于之后的处理,用户可以选择在这些元组上应用一个 aggregation,或者对它们进行叉积以实现 JOIN 的效果,还

25、可以定制其他处理逻辑。而在 SQL 中,分组操作不能独立存在,要么与 aggregation 联合(group-by-aggregate 查询),要么根叉积操作联合(JOIN 操作)。需要注意的是,Pig Latin 的嵌套式数据模型是 COGROUP 能独立存在的根本原因。它将所有输入的元组按照一定的规则进行分组,然后存入嵌套 bags 中。这类原语不可能在 SQL 中出现,原因是它的数据模型是扁平化的,不允许嵌套。当然,嵌套数据可能会引起执行效率的问题,对这一点,在后面进行详细说明。单数据集 COGROUP:GROUPGROUP 是 COGROUP 在单一输入数据集上的特例。这种情况就直接

26、使用关键字 GROUP,继续上边的例子,假如我们想统计每个查询串带来的总体广告收入(一个典型的 group-by-aggregate 查询),可以通过下列语句完成:PIG LATIN 中的 JOIN上边通过 COGROUP 与 JOIN 的对比,体现了 COGROUP 的灵活性,但是,并不是所有的用户都需要这种灵活性,很多情况下,只需要一个简单的等价连接就可以满足用户要求。因此,Pig Latin 通过关键字 JOIN 为用户提供了等价连接命令,举例如下:事实上,JOIN 在语义上与 COGROUP 后接 flattening 是等价的,因此上边 JOIN命令可以改写为如下等价命令:PIG L

27、ATIN 中的 MAP-REDUCE在 Pig Latin 中 map-reduce 不再作为一个编程模型而存在,它们实际上以及成为了 Pig Latin 的 UDFs。map 函数每次对一个输入元组进行操作,输出一个bag,该 bag 包含一组 key-value,而 reduce 函数每次对一个 key 关联的一组values 进行操作,产生最后的结果。举例如下:第一行语句对输入数据集的每个元组应用 map 操作(这里的*号与 SQL 中意义相同,表示输入元组的每个字段都传入 map),然后对 map 输出扁平化处理,产生一组 key-value 对。存存储储命命令令 :STORE用户可以

28、通过该命令将 Pig Latin 表达式序列结果序列化到一个具体的文件,具体命令如下:该例采用了一个定制化函数 myStore()完成具体的序列化功能。也可以省略USING 短语,这是系统会默认使用一个基于空格分隔的纯文本文件序列化函数,系统还提供了内置的序列化和去序列化函数,支持 LOAD/STORE 任意嵌套数据。类类 SQL 命命令令Pig Latin 有很多类似于 SQL 的命令,分别为: UNION:返回两个或者多个 bags 的联合体。 CROSS:返回两个或者多个 bags 的叉积。 ORDER:按照某些字段对一个 bag 进行排序。 DISTINCT:实现一个 bag 中的元组

29、去重,实际上,该命令是首先按照一个 bag 的所有字段进行分组聚集,然后进行投影的简化表示。PIG LATIN 实实现现Pig Latin 的实现系统叫做 Pig,它的架构目标是高扩展性,允许不同系统以插件的方式作为 Pig Latin 的执行平台。目前的实现,使用 Hadoop 作为执行平台,Hadoop 是一个开源可扩展的 map-reduce 实现,Pig Latin 程序被编译为map-reduce 作业,然后在 hadoop 执行。下面具体介绍设计上的三个关键技术。构构建建逻逻辑辑执执行行计计划划客户端提交 Pig Latin 命令后,首先由 Pig 解释器对命令进行分析,检验输入文

30、件和语句中出现的 bags 的有效性。例如,c=COGROUP a BY .,b BY .命令,Pig 会检验 a 和 b 两个 bags 已经被定义,逻辑计划的构建过程具有递归性和依赖性,以上例进行说明,c 的逻辑计划要依赖于 a 和 b 的逻辑计划,因此只有当 a 的逻辑计划和 b 的逻辑计划构建完毕才能构建 c 的逻辑计划。所有逻辑计划,只是一个处理流程,而没有任何处理过程发生,处理过程是在调用 STORE 之后发生的。调用 STORE 之后,逻辑计划就被编译成具体的执行计划并被调度执行。这种懒惰执行方式有很多好处,比如允许内存管道,再比如跨多个 Pig Latin 命令的重定序。Pig

31、 系统采用预处理与处理分离的架构,即程序的分析,逻辑计划的生成独立于执行平台。只有逻辑计划被编译为具体的执行计划时才依赖于具体的执行平台。目前,Pig 采用比较成熟的开源 map-reduce 实现 hadoop 作为执行平台。这种分离体系结构,有助于系统的发展。MAP-REDUCE 计计划划的的生生成成图 3 MAP-REDUCE 计划Pig Latin 逻辑计划到具体的 MAP-REDUCE 执行计划的编译过程遵循 MAP-REDUCE 处理模式的本质特点,MAP-REDUCE 处理模式本质上具有大规模分组聚集的能力,即 map 任务通过指派 keys 对数据进行分组,reduce 任务每

32、次处理一个组的数据。Pig 编译器遵循这种特点将逻辑计划中每个 COGROUP 命令转化为一个不同的 map-reduce 作业。如图 3 所示。与 COGROUP 命令 C 相关联的 map 函数首先根据 C 中的 BY 短语将 keys 指派为相应的元组,而 reduce 最初不进行任何操作。这样每个 COGROUP 命令就成为两个不同的 map-reduce 任务的界限。第一个 COGROUP 命令 C1的命令都由C1对应的 map 函数处理,如图 3 所示。记第 i 个 COGROUP 命令为 Ci,则在 Ci与 Ci+1之间的命令序列要么(a)由 Ci的 reduce 函数处理,要么

33、(b)由 Ci+1的 map 函数处理。考虑 grouping 后常跟 aggregation,Pig 选择方案(a),认为这种方案有利于减少不同 map-reduce 作业之间序列化的数据量。当 COGROUP 操作的输入为多数据集时,map 函数会为每个元组附加一个字段以标识元组是源于哪个数据集。相应的 reduce 函数对该信息进行解码,利用该信息将元组插入到适当的位置。LOAD 的并行性通过 HDFS 实现(文件存储在 HDFS 上)。对于一个 map-reduce 作业,多个 map 和 reduce 运行实例是并行的,从而可以实现 FILTER 和FOREACH 操作的自动并行化。多个 map 实例产生的输出按照一定的划分规则划分为不同部分,每个对应一个 reduce 实例,它们以并行化方式执行,从而实现了(CO)GROUP 的并行性。ORDER 命令被编译为两个 map-reduce 作业。第一个作业通过对输入进行取样来确定排序

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论