Hive使用TRANSFORM运行Python脚本总结

1、Python环境设置

可以使用add cachearchive的方法把tar.gz添加到分布式缓存,Hive会自动解压压缩包,但是目录名是和压缩包名称一样的;

add cachearchive ${env:my_workbench}/share/python2.7.tar.gz;

–这样使用

using 'python2.7.tar.gz/bin/python my.py' 

2、一定使用distribute by或者cluster by

如果不加上这两个关键词,那么数据会被分发到1个机器,如果数据量大执行会很慢;

但是Hive 0.8的一个问题是,distribute by和cluster by后面只能跟1列,如果多列就会报错;

如果数据量大,并且数据不能被拆分,那只能设置mapred.reduce.tasks=1;

如果数据可以满足结合律,那么使用子查询,在外面聚合一下,就可以解决只能跟1列的问题;

3、每个python脚本并不是执行了reduce上的所有数据;

每个reducer机器会从很多maper机器上取数据,取过来之后会合并,但不一定合并成1个文件,而会是S个;

因此即使设置mapred.reduce.tasks数值为1,Python程序会被启动S个进程来执行每个分片,执行完毕后再汇总成1个数据;

也就是说1个reducer上,每个python脚本也会被启动N个进程处理不同的数据分片的。

–这个问题查了好久,仔细分析了结果数据才发现的,多么痛的领悟;

4、self join非常耗时间,尤其关联规则有运算的时候;

最开始我启动的一个self join是这样的

tablea a join tablea b on a.id=b.id+1 join tablea c on a.id=c.id+2

这个程序在很小的数据量上运行了1个多小时,表示极度郁闷;

然后我对其改进,在tablea数据表中直接增加id+1和id+2数值的两个冗余字段,然后改写为:

tablea a join tablea b on a.id_1=b.id join tablea c on a.id_2=c.id

运行时间有所减少,但是还是非常慢,运行了好几十分钟被我Kill掉了;

真不知道Hive怎么实现这个语句的;

实在没办法只好Hive中调用Transform的Python脚本,使用distribute by id进行分发,然后每个节点的每个python中运行两边扫描:

第一步:以id为key,把数据全部存入词典,内存幸好没爆;

第二步:扫描第一步的词典,取出每个id,直接从词典中取id-1和id-2的数据,输出;

这样改进后非常快。杀鸡用牛刀,真是浪费资源,Hive为什么self join如此耗时真是不理解;

本文链接:http://crazyant.net/1437.html

相关推荐

1 thought on “Hive使用TRANSFORM运行Python脚本总结”

Leave a Comment