V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yifeng
V2EX  ›  Linux

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

  •  
  •   yifeng · 2016-03-31 17:52:12 +08:00 · 4666 次点击
    这是一个创建于 2945 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用一行很长 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   ·   我们的愿景   ·   实用小工具   ·   1442 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 17:25 · PVG 01:25 · LAX 10:25 · JFK 13:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.