`
winnerbao
  • 浏览: 10012 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

统计海量数据中访问最多的IP (略有扩展)

 
阅读更多

[介绍]

这是一道经典的题目,而且也是比较贴近实际的一个问题。 在网上,已经有人给出了非常好的解决方式, 如 CSDN July http://www.cnblogs.com/v-July-v/archive/2012/03/22/2413055.html
 
我这里罗列出来,出于两方面考虑
1. 重复、加深记忆。我会把重点思路加以重复
2. 扩展。扩展到更多的场景,拓宽思路。
 
 
[解决]
 
重复一下题目
一个数据文件,非常大(如 100G),每行都是一条IP访问记录。计算器中重复最多的IP,即访问最多的IP。
分析
由于数据源太大,无法直接brute force的进行内存处理,那么从几个方面考虑
 
首先,贼心不死,看看能不能直接内存处理? IPv4的话,一共2^32个ip,即4G个,每个IP占用4个字节,加上每个计数所占用8个字节(long型),则需要至少 4G * (4+8)= 48G内存。IPv4中一些IP保留给内网以及广播网络(IGMP?), 所以总数小于4G,实际为 3,706,452,992, 参考:http://stackoverflow.com/questions/2437169/what-is-the-total-amount-of-public-ipv4-addresses
显然,使用64位的OS,64G内存的机器的话,还是有可能的哦。但是如果是IPv6呢?歇菜了吧!
不过,这种把数据源的数据属性认真分析的方法,还是非常非常值得推荐的!!!!
 
然后,还是老实的把大文件分拆了吧。
大文件划分成若干小文件,如1024个小文件。划分时,把相同IP的条目分配到相同的文件中。这样分别统计小文件的IP,然后汇总即可。
注意:保证相同ip分配到相同小文件中。简单的hash就能达到这个效果。如果分配到不同文件中,则没有意义了。
注意:这里的思路是,分拆大数据量的时候,要注意,此时你可能可以做一些预处理的工作。预处理工作一方面保证你的工作可以完成,另一方面,可能可以加快处理过程。此预处理,要考虑当前数据的属性。
 
[扩展]
有些场景下,需要实时统计最大IP数。HOW?
重复一下场景:数据源是没有截止的,它源源不断的提供更多的IP访问记录。要求,得到当前时刻,访问最多的那个IP,以及它的数量。进一步要求,获得当前时刻,访问最多的Top K (e.g. K =100)个IP。
 
与上面的拆分思路一致,将数据源的条目分别送到N个服务器上分别处理。相同IP,会到达相同的服务器。
这些服务器在处理的时候,内部保存当前所有uniq IP的访问数量与一个Tree(TODO:何种Tree比较好?RB tree looks good)中.每次到达新的IP,则调整这个树。此树要求,1) 快速定位节点,以更新其value 2)更新某个节点值后,能够快速调整 3)方便获取Top K记录  注: priority Q怎么样?取最大值很方便,TopK则不行。快速定位也不太行。
 
继续思考:由于调整频繁(数据源更新过快),如200,000条数据/秒钟,会导致该树一直抖动 200,000次抖动每秒钟,如何处理? 此场景非常常见!
1)有没有别的更好的数据结构? 
OR
2)缓存新入数据,譬如1秒钟,然后再更新树,这样,最多抖动60*uniq IP数量次/每分钟。注意:缓存的1秒钟数据,要进行uniq IP计数累加,这样1秒钟到达时,uniq IP只引起一次抖动。
OR
3) 还有什么别的办法么?Spark之类的能帮忙做点什么么?
 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics