V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
V2EX  ›  Hadoop

Hadoop + Python

  •  
  •   Livid · 2013-06-30 22:26:35 +08:00 via iPhone · 6004 次点击
    这是一个创建于 4160 天前的主题,其中的信息可能已经有所发展或是发生改变。
    19 条回复    1970-01-01 08:00:00 +08:00
    killpanda
        1
    killpanda  
       2013-06-30 22:27:38 +08:00
    hadoop streaming

    貌似复杂的排序之类的支持的不好
    likuku
        2
    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
        3
    clowwindy  
       2013-06-30 23:01:17 +08:00
    缺点是只能处理单行文本,否则要转义掉回车。
    lookhi
        4
    lookhi  
       2013-06-30 23:35:57 +08:00
    可见我们的寻人帖 /t/70036
    hadoop + python 解决上述烦恼.
    ivanlw
        5
    ivanlw  
       2013-07-01 07:51:26 +08:00
    昨天刚把这个跑了一遍……看到标题就猜到可能是这个了=.=
    rrfeng
        6
    rrfeng  
       2013-07-01 08:50:24 +08:00
    @likuku
    sort 开销巨大……
    你的任务完全可以只用 awk 一次搞定

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

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

    总量不是很大,结果最大的一个分类统计是97W。
    rrfeng
        9
    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
        10
    cloudzhou  
       2013-07-01 15:14:02 +08:00
    cat * | grep "@qq.com" 这个方式也会带来性能问题
    直接 grep "@qq.com" * 就可以了
    cshcool
        11
    cshcool  
       2013-07-01 16:32:32 +08:00
    @ivanlw 我就知道进来会看到你
    likuku
        12
    likuku  
       2013-07-01 21:06:25 +08:00
    @cloudzhou 用 cat 管道 到 后面其它,只是为了方便一系列的 过滤,修改起来方便,否则 测试时,有些在资源前面的条件来回改很头疼。


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

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

    另外既然你都能排序……那么换成 awk 我所说的吃内存问题就根本不存在了 - -!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3036 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:29 · PVG 22:29 · LAX 06:29 · JFK 09:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.