大日志排序

crayonSin 2013-02-01 09:48:14
有一个日志文件,每行记录了一次调用信息,其中包括时间和来源IP。每天的记录数目大约10亿条左右。现在需要:
1)获取日访问次数最高的1000个来源IP,按照访问量从高到低排序。
2)获取连续一周内访问次数最高的1000个来源IP,按照访问量从高到低排序。
请给出能得到精确(非近似)结果,并且效率尽可能高的计算方法,并给出主要部分伪代码。
...全文
358 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
youyou1912 2013-04-15
  • 打赏
  • 举报
回复
时间效率最大化: 十亿条, 如果每天访问IP量重复度为1/10. 那么有1亿个IP.每个IP占用4bytes, 统计每个IP的数量用4bytes. 用哈希的空间利用率为0.5, 那么需要空间100M*8bytes/0.5=1600MB=1.6GB(2GB不到) 统计过后. 准备一个大小为1000的最小堆(空间占用几十KB), 遍历一遍哈希.获得最大1000的IP和相应访问量. 时间效率: 外部文件遍历1遍+内部内存1亿条数据遍历1遍*Log(1000) 空间上面有提: 2GB不到 对于一周的情况. 取决于IP重复度, 如果有2亿个IP左右. 还是可以一起放内存. 算法差不多. 否则需要先用4bytesIP取7的模, 拆分为7个文件分别处理后做败者树归并排序.
xjtufjj 2013-03-01
  • 打赏
  • 举报
回复
如果在一台服务器上做的话, 可能时间是个问题。 10亿条,每条IP + 时间信息可能加起来会有20字节左右, 10 * 20 = 200G左右的文件。 处理这么大的文件, 单台服务器有些吃力。 算法的话, 肯定还是hash,绝对不允许多次访问数据。如果内存够大 (> 20G),可以使用直接hash, key = IP, 然后对次数使用selection 算法(), 理论时间复杂度应该在n *lg1000, 工程中可以多取几个观测点(比如1000)这样可以将时间复杂度降低到An, A < 2, .另外当然可以去除一些内部地址,组播地址, 等等。此外也可以基于一些概率算法, 比如如果服务器在中国, 肯定中国的IP访问较多, 可以针对中国的IP做特殊的处理等等。 其实这么大的数据量,最后还是要走分布式, 使用hadoop,将数据分块, map到不同的n个服务器上去,每个服务器计算出前1000个, 然后再 在n个1000中找出前1000。 至于每周的前1000个, 类似于hadoop 的算法, 只要将每天的前1000个reduce一下就可以了。
amdgaming 2013-02-01
  • 打赏
  • 举报
回复
en ,希望高人给出其他 做法
蜡笔小新啦 2013-02-01
  • 打赏
  • 举报
回复
每次都1w行。 然后用hash记录出今天访问的ip的访问次数。 在写入到另一个文件中: 文件时由255*255*255*255个int组成。现叫做“ip次数文件” 写入hash中的一个ip的访问次数就先用fseek到这个ip的位置,然后读取,再加上现访问次数,再写入。 再来分析ip次数文件。不可能有255*255*255*255个ip地址的,哪里来这么多,又不是google。 所以再直接读取ip次数文件,还是用fseek来读不为零的。用堆排序来排序。 不知道这样可否???请高手解答。
paradin2 2013-02-01
  • 打赏
  • 举报
回复
3楼人家说了要精确,布隆过滤器省一点空间但有万分之几的误判。 像lz这样的访问量公司,显然有配套的hadoop之类的分布式平台来跑的。最后只要把每个结果拉下来做归并即可。
paradin2 2013-02-01
  • 打赏
  • 举报
回复
按2楼的方法,hash表全部存下来也就4G,楼主服务器不干别的就直接内存搞呗。 然后堆排序,大根堆,碰到一个比heap_ip_pv[1000]大的就替换掉,调整堆即可。 最坏时间:N*log(1000)
amdgaming 2013-02-01
  • 打赏
  • 举报
回复
是不是要使用 布隆过滤器

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧