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
学习一下!