我在根据参数输入加载日志文件时遇到问题,想知道是否有人能够提供一些指导。有问题的日志是 Omniture 日志,存储在基于年、月和日的子目录中(例如 /year=2013/month=02/day=14),并在文件名中带有日期戳。对于任何一天,都可能存在多个日志,每个日志有数百 MB。
我有一个 Pig 脚本,它当前处理整个月的日志,月份和年份指定为脚本参数(例如 /year=$year/month=$month/day=*)。它运行良好,我们对此非常满意。也就是说,我们希望切换到每周处理日志,这意味着以前的 LOAD 路径 glob 将不起作用(几周可以包含几个月甚至几年)。为了解决这个问题,我有一个 Python UDF,它需要一个开始日期并为一周的日志吐出必要的 glob,例如:
>>> log_path_regex(2013, 1, 28)
'{year=2013/month=01/day=28,year=2013/month=01/day=29,year=2013/month=01/day=30,year=2013/month=01/day=31,year=2013/month=02/day=01,year=2013/month=02/day=02,year=2013/month=02/day=03}'
然后将这个 glob 插入到适当的路径中:
> %declare omniture_log_path 's3://foo/bar/$week_path/*.tsv.gz';
> data = LOAD '$omniture_log_path' USING OmnitureTextLoader(); // See http://github.com/msukmanowsky/OmnitureTextLoader
不幸的是,我一生都无法弄清楚如何根据 $year、$month 和 $day 脚本参数填充 $week_path。我尝试使用 %declare 但 grunt 抱怨说它的日志记录但从不这样做:
> %declare week_path util.log_path_regex(year, month, day);
2013-02-14 16:54:02,648 [main] INFO org.apache.pig.Main - Apache Pig version 0.10.1 (r1426677) compiled Dec 28 2012, 16:46:13
2013-02-1416:54:02,648 [main] INFO org.apache.pig.Main - Logging error messages to: /tmp/pig_1360878842643.log % ls /tmp/pig_1360878842643.log
ls: cannot access /tmp/pig_1360878842643.log: No such file or directory
如果我在参数前加上美元符号或在前缀参数周围加上引号,也会产生同样的错误。
如果我尝试使用define(我相信它只适用于静态Java函数),我会得到以下信息:
> define week_path util.log_path_regex(year, month, day);
2013-02-14 17:00:42,392 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <file script.pig, line 11, column 37> mismatched input 'year' expecting RIGHT_PAREN
与 %declare 一样,如果我在参数前面加上美元符号或在前缀参数前面加上引号,我会得到同样的错误。
我已经四处寻找并没有提出解决方案。我可能正在寻找错误的东西。调用 shell 命令可能会起作用,但会很困难,因为这会使我们的脚本部署复杂化,并且可能不可行,因为我们正在从 S3 而不是挂载的目录中检索日志。同样,将生成的 glob 作为单个参数传递可能会使实例化 MapReduce 集群上的自动化作业复杂化。
除了使用 glob 之外,还可能有一种对 Pig 友好的方式来限制 LOAD。也就是说,我仍然必须使用我的 UDF,这似乎是问题的根源。
这真的归结为我想在我的 LOAD 语句中包含一个内置在 Pig 中的动态路径 glob。猪似乎没有那么容易。
我需要将我的 UDF 转换为静态 Java 方法吗?或者我会遇到同样的问题吗?(如果它会起作用,我会犹豫不决。它是一个 8 行 Python 函数,与等效的 Java 代码相比,它易于部署并且更容易被其他人维护。)
自定义 LoadFunc 是答案吗?有了这个,我大概必须指定 /year= /month= /day=* 并强制 Pig 测试每个文件名的日期戳,它位于两个日期之间。这似乎是一个巨大的黑客攻击和资源浪费。
有任何想法吗?