pig哲学之一——pigs eat anything。pig能够从不同数据源加载数据,能够处理不同式的数据。pig使用loader/store进行数据加载和存储,可选地使用schema指定数据列名称和类型。如果加载数据时不指定schema,数据列未命名,类型默认是字节数组(bytearray),在后
pig哲学之一——pigs eat anything。pig能够从不同数据源加载数据,能够处理不同格式的数据。pig使用loader/store进行数据加载和存储,可选地使用schema指定数据列名称和类型。如果加载数据时不指定schema,数据列未命名,类型默认是字节数组(bytearray),在后续操作中,pig可以通过位置参数引用数据列,会根据在数据列上进行的操作进行自动类型转化。从性能和可读性考虑,最好在加载数据时指定schema。
loader体系loader的基类是org.apache.pig.loadfunc,规定了loader需要实现的接口,并提供了一些默认实现。下图是loader的继承体系,针对不同数据源,pig实现了大量loader,包括hbasestorage和parquestloader等,能够处理列式存储。默认的loader是pigstorage。
org.apache.pig.loadfunc中的三个基本的方法决定了where/what/how:
public abstractvoidsetlocation(string location, job job) throws ioexceptionpublic abstractinputformat getinputformat() throws ioexceptionpublic loadcaster getloadcaster() throws ioexception { return new utf8storageconverter();}
指定加载位置。指定数据源类型,使用hdfs的inputformat处理不同数据源。如何处理数据从字节数组到实际类型的转化,默认使用utf8storageconverterpigstore分析1) 处理压缩格式,通过加载文件后缀加载不同的inputformat:
@overridepublic inputformat getinputformat() { if(loadlocation.endswith(.bz2) || loadlocation.endswith(.bz)) { return newbzip2textinputformat(); } else { return newpigtextinputformat(); }}
2) 读取数据:读取数据之前先代用preparetoread方法设置inputformat对应的recordreader,通过recordreader读取每行数据,根据用户指定的分隔符处理每行文本,最终转换成元组。public void preparetoread(recordreader reader,pigsplit split)@overridepublic tuple getnext() throws ioexception
3) schema处理,在getnext方法中,如果存在schema,会对元组应用applyschema方法,给元组中的数据项指定名称和类型。其他重要接口通过实现其他一些接口,loader能提供一些附加功能
loadmetadata通过getschema方法自动加载schema通过getpartitionkeys方法设置数据的分区键,把用户查询条件中的分区键通过setpartitionfilter直接传递给loader,减少数据加载。参见hcatloader中实现,注:org.apache.hcatalog.pig.hcatloaderloadpushdown在使用rcfile等基于列格式文件时,如果每次都加载所有列对性能影响较大。如果实现了loadpushdown接口,优化器会将所需要用到的字段传递给pushprojection方法。
loadcaster自定义字节数组到schema中数据类型的转换,通过一系列方法能够自定义字节数组到到pig的标量和复杂数据类型的转化。默认实现为utf8storageconverter,其中的复杂数据类型格式固定,比如元组格式为(),map格式为[],bag为{}。
store体系与org.apache.pig.loadfunc对应,pig中也存在org.apache.pig.storefunc抽象类。由于不少loader(比如默认的pigstorage)同样实现了store功能,受java单继承的限制,pig提供了storefuncinterface接口。
store的实现与loader对应,将实际输出操作委托给outputformat。值得注意的是,与loadmetadata对应,pig也提供了storemetadata接口用于处理元数据的存储。.
schema结构schema描述了一个数据集合每一行的列名称和数据类型,其中每一个列信息用fieldschema表示。fieldschema通常包括列名称、数据类型,如果列本身是bag的话,fieldschema还会拥有自己的schema。
参考价值目前pig针对逻辑执行计划的优化器都是基于规则的,如果要实现基于代价的优化,需要更多关于数据的统计信息,那么加载和存储数据应该是重要入口和出口。在loadmetadata/storemetadata接口中已经存在getstatistics/setstatistics方法,resourcestatistics包含行数、行大小、列直方图、区分度等统计信息,不过现在在pigstorage中是空实现。如果要实现pig on spark,loader体系中需要加入rdd层,演变为loader-rdd-hdfs三层结构。hdfs存储可以考虑orcfile等列式存储格式,基于成本的优化可以参考hive中的实现
