Hadoop + Python

2013-06-30 22:26:35 +08:00
 Livid
http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/
5877 次点击
所在节点    Hadoop
19 条回复
killpanda
2013-06-30 22:27:38 +08:00
hadoop streaming

貌似复杂的排序之类的支持的不好
likuku
2013-06-30 22:50:24 +08:00
嗯,最近一周正全力在搞这个,刚好昨天也拿 python 写 map/reduce 测试过。

13天的邮件日志文本,一天一个,总量62GB,存有5个数据节点的hdfs。
以 hadoop streaming 方式跑 很简单的 python,搜索发给 qq.com 的失败退信,取出退信代码,按退信代码分类求数量。

hadoop 跑了9分8秒,大部分都是map时间,reduce 瞬间完成。

然后在一台单机(与一台数据节点机器配置一样),用 一行指令完成同样事情:

time cat * | grep "@qq.com" | grep -v "success" | awk -F "," '{print $7 $8}' | sort | uniq -c

耗时28分25秒。
clowwindy
2013-06-30 23:01:17 +08:00
缺点是只能处理单行文本,否则要转义掉回车。
lookhi
2013-06-30 23:35:57 +08:00
可见我们的寻人帖 /t/70036
hadoop + python 解决上述烦恼.
ivanlw
2013-07-01 07:51:26 +08:00
昨天刚把这个跑了一遍……看到标题就猜到可能是这个了=.=
rrfeng
2013-07-01 08:50:24 +08:00
@likuku
sort 开销巨大……
你的任务完全可以只用 awk 一次搞定

awk -F ',' '/@qq\.com/&&!/success/{!a[$7,$8]++}'

唯一的缺点就是最后一步去重可能会吃掉大量内存,视你的数据情况而定
rrfeng
2013-07-01 08:57:35 +08:00
@likuku
修正刚才的awk,有错误
awk -F ',' '/@qq\.com/&&!/success/&&!a[$7,$8]++'
likuku
2013-07-01 13:49:47 +08:00
@rrfeng 这个 awk 用法太高级了...小白表示不明则厉... Orz

总量不是很大,结果最大的一个分类统计是97W。
rrfeng
2013-07-01 14:29:47 +08:00
@likuku
其实还是错了。。。uniq -c 是计数,我看成去重了哈哈

awk -F ',' '/@qq\.com/&&!/success/{a[$7" "$8]++}END{for(i in a)print i,a[i]}'

你跑跑试试多长时间呗

最后消耗的内存相当于 ... | sort | uniq 之后每行作为 key 存入一个数组,比文件大小略大。
cloudzhou
2013-07-01 15:14:02 +08:00
cat * | grep "@qq.com" 这个方式也会带来性能问题
直接 grep "@qq.com" * 就可以了
cshcool
2013-07-01 16:32:32 +08:00
@ivanlw 我就知道进来会看到你
likuku
2013-07-01 21:06:25 +08:00
@cloudzhou 用 cat 管道 到 后面其它,只是为了方便一系列的 过滤,修改起来方便,否则 测试时,有些在资源前面的条件来回改很头疼。


@rrfeng 我用我的 cat ... 一串作那一堆文本日志过滤求分类计数结果,实际跑的机器只有2G内存,运行过程中没去看top,swap分区也就4GB,机器貌似也一直响应正常。
rrfeng
2013-07-02 08:26:47 +08:00
@likuku
cat *|grep 问题倒不是很严重,反正是一次读取
你这句的关键是 sort ,而你的需求里完全没有排序的必要,计数而已
ysjdx
2013-07-02 08:41:46 +08:00
学习了~都是大神
lovejoy
2013-07-02 22:54:47 +08:00
@rrfeng 这个能解释一下吗
bengol
2013-07-02 22:57:26 +08:00
个人感觉就是n*n
rrfeng
2013-07-02 23:29:18 +08:00
@lovejoy
-F ',' 以逗号作分隔符
/pattern1/&&/pattern2/ 匹配两个条件的行
{a[$7" "$8]++} 满足上面条件的行 以 [$7" "$8] 作为键存入数组a,如果重复就是 ++ 递增

END{} 在所有文件读入结束之后执行的程序块,输出数组a的所有键以及值
likuku
2013-07-03 00:32:45 +08:00
@rrfeng 在 uniq -c 计数前,若不进行 sort 排序,则最后 uniq -c 计数的结果还是散布的,并不会完全分类聚合。
rrfeng
2013-07-03 09:13:08 +08:00
@likuku
问题是你根本不需要排序啊。
按照你的描述我觉得 28 min 至少有 27.5 min 被 sort 吃掉了~~

另外既然你都能排序……那么换成 awk 我所说的吃内存问题就根本不存在了 - -!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/74267

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX