linux 下超级大日志文件统计问题,求 V 牛挤点儿奶来解渴! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yifeng
V2EX    Linux

linux 下超级大日志文件统计问题,求 V 牛挤点儿奶来解渴!

  •  
  •   yifeng 2016-03-31 17:52:12 +08:00 5274 次点击
    这是一个创建于 3481 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用一行很长 linux shell 脚本,从格式为“ uid,timestamp ”的 10G 大小的日志中抽取前天 4 点到 5 点间,访问用户最多的前 5 名的 uid 的列表。

    求 V 友们给指引方向,谢谢,谢谢,谢谢!
    26 条回复    2016-04-04 15:57:49 +08:00
    justfly
        1
    justfly  
       2016-03-31 17:58:13 +08:00   1
    方向是 cat | grep | awk

    awk 具体统计用法自己查下 我记不清了
    visaxin
        2
    visaxin  
       2016-03-31 17:59:12 +08:00 via Android   1
    spark 应该就可以把
    yifeng
        3
    yifeng  
    OP
       2016-03-31 18:01:07 +08:00
    @justfly 非常感谢,谢谢。
    skydiver
        4
    skydiver  
       2016-03-31 18:02:23 +08:00
    这不是常见面试题么……
    JamesRuan
        5
    JamesRuan  
       2016-03-31 18:16:18 +08:00
    10G 不算大吧……
    shsfoolish
        6
    shsfoolish  
       2016-03-31 18:43:28 +08:00   1
    先用`split`切成多个小文件,每个小文件用`awk`统计前天 4-5 点内的访问量,将每个文件的中间结果输出到临时文件,最后将临时文件求合计算出 top5 ((基本上是 MR 过程..
    chairuosen
        7
    chairuosen  
       2016-03-31 19:05:41 +08:00   1
    cat a.txt | awk -F, '$2 < 1433001600500 && $2> 1433001600000 {print $1}' | uniq -c | sort -k1,1nr | head -5
    不知道大文件有没有问题
    chairuosen
        8
    chairuosen  
       2016-03-31 19:06:09 +08:00
    @chairuosen 啊,两个时间戳替换掉。。。
    hadoop
        9
    hadoop  
       2016-03-31 19:11:49 +08:00
    @chairuosen 少一步 cat 岂不是更好?
    yifeng
        10
    yifeng  
    OP
       2016-03-31 19:16:21 +08:00 via iPhone
    @shsfoolish 非常感谢,我试试看
    yifeng
        11
    yifeng  
    OP
       2016-03-31 19:18:07 +08:00 via iPhone
    @chairuosen 非常感谢, cat 的话效率是个问题,内存负载压力很大吧,还是非常感谢
    SlipStupig
        12
    SlipStupig  
       2016-03-31 20:54:55 +08:00   1
    10G 一点也不多,给出一些方法
    1.这里倒着读取日志,每次读取 10 万行,先搜索符合最后一天的日志(具体搜索算法可以用 bm 或者 kmp 反正数据量不大)记录一下尾部行号,然后接着往上读直到符合要求为止
    2.bash 法,用 cat | xarg | unique | grep ""或 awk 这类
    3.mysql 直接 loadfile ,建好索引,用 where 语句查询
    4.mmap 读取大文件用 re2 写个 regex 匹配一下就好(内存可能会不够)
    5.bozo 读取法(最神奇的算法),随机进行读取,然后记录一下,总有一天会完全读取完成的

    觉得最省事的就是载入到 mysql 里面,如果你是嵌入式环境当我没说
    @visaxin spark 是处理实时流量,这个场景犯不上用那么大的家伙
    SlipStupig
        13
    SlipStupig  
       2016-03-31 20:56:29 +08:00   1
    v 站不能编辑真头疼,针对第一类可以采用半解析法,这样能更快速定位到行号
    wsy2220
        14
    wsy2220  
       2016-03-31 21:22:49 +08:00
    导入数据库吧
    rrfeng
        15
    rrfeng  
       2016-03-31 21:37:11 +08:00   2
    10G awk 毫无压力吧……

    关键是 2 点:估计离文件头近还是尾近,当时间段过完之后(时间肯定是有序的啊)立刻退出,不要继续读文件了。

    更高级的写法请用 seek ,跳跃式定位时间点(开始点),然后一直读到结束点。来个 awk 版本的:


    awk -F, '$2>TIME_END{exit}$2>TIME_START{s[$1]++}END{for(i in a)print a[i],i}' FILE | sort -k1nr | head -5

    这个只要你时间段内 uid 数量不过百万肯定没问题,主要是排序的开销

    如果更接近文件末尾,用 tac FILE | awk 然后把 > < 条件改一下就好……
    fishg
        16
    fishg  
       2016-03-31 21:38:25 +08:00
    真不大。。
    yifeng
        17
    yifeng  
    OP
       2016-03-31 22:10:00 +08:00
    @SlipStupig 非常非常感谢,谢谢你给的思路,感谢!
    yifeng
        18
    yifeng  
    OP
       2016-03-31 22:12:20 +08:00
    @rrfeng 谢谢,非常感谢,我看大家都提到了 awk,我好好研究一下,谢谢。
    ToughGuy
        19
    ToughGuy  
       2016-04-01 01:52:57 +08:00   1
    awk -F, '$NF>=1459281600&&$NF<=1459285200{a[$1]++}END{for(i in a){printf("%s\t%s\n",a[i],i)}}' abcd.txt | sort -rn | head -n 5
    ToughGuy
        20
    ToughGuy  
       2016-04-01 01:54:33 +08:00   1
    @ToughGuy

    补充下, 如果字段不止个的话你需要把$NF 替换成$2
    xuboying
        21
    xuboying  
       2016-04-01 08:51:23 +08:00 via Android
    perl flip flop 运算符轻松搞定
    dreammes
        22
    dreammes  
       2016-04-01 09:41:44 +08:00
    楼上正解
    ryd994
        23
    ryd994  
       2016-04-01 11:24:09 +08:00 via Android
    @SlipStupig mmap 不存在内存不够啊………
    除非地址空间不够,相信大家服务器都是 64 位了吧
    yifeng
        24
    yifeng  
    OP
       2016-04-01 13:10:00 +08:00
    @ToughGuy 谢谢,谢谢,受教了。
    SlipStupig
        25
    SlipStupig  
       2016-04-01 14:15:45 +08:00
    @ryd994 我理解可能有点问题,感谢指正
    interdev
        26
    interdev  
       2016-04-04 15:57:49 +08:00
    @hadoop 收一下 gmail ,有事找。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2639 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 06:36 PVG 14:36 LAX 23:36 JFK 02:36
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86