100台机器上海量IP如何查找出现频率 Top 100?
场景题
有 100 机器,每个机器的磁盘特别大,磁盘大小为 1T,但是内存大小只有 4G,现在每台机器上都产生了很多 ip 日志文件,每个文件假设有50G,那么如果计算出这 100 太机器上访问量最多的 100 ip 呢?也就是Top 100。
思路
其实,一开始我有往布隆过滤器那边考虑,但是布隆过滤器只能大致的判断一个 ip 是否已经存在,而不能去统计数量,不符合该场景。
那么一般这种大数据的问题,都是因为一次不能完全加载到内存,因此需要拆分,那怎么拆呢?ip是32位的,也就是最多就 232 个, 常见的拆分方法都是 哈希:
- 把大文件通过哈希算法分配到不同的机器
- 把大文件通过哈希算法分配到不同的小文件
上面所说,一台机器的内存肯定不能把所有的 ip 全部加载进去,必须在不同机器上先 hash 区分,先看每台机器上,50G 文件,假设我们分成 100 个小文件,那么平均每个就500M,使用 Hash 函数将所有的 ip 分流到不同的文件中。
这个时候相同的 ip 一定在相同的文件中,当然不能排除数据全部倾斜于一个文件的情况,也就是虽然 hash了,但是由于个别ip或者hash值相同的ip太多了,都分到了个别文件上,那么这个时候分流后的文件依旧很大。这种情况我能想到的就是要是文件还是很大,需要再hash,如果基本属于同一个ip,那么这个时候就可以分批次读取,比如一次只读 1G 到内存。
在处理每个小文件时,使用 HashMap 来统计每个 ip 出现的频率,统计完成后,遍历,用最小根堆,获取出现频率最大的100个ip。这个时候,每个小文件都获取到了出现频率最大的100个 ip,然后每个文件的 Top 100 个ip 再进行排序即可(每个文件的top100 都是不一样的,因为前面进行 hash 之后保证相同的 ip 只会落到同一个文件里)。这样就可以得到每台机器上的 Top 100。
不同机器的 Top 100 再进行 加和 并 排序,就可以得到Top 100 的ip。
为什么加和? 因为不同机器上可能存在同样的ip,前面的hash操作只是确保同一个机器的不同文件里面的ip一定不一样。
但是上面的操作有什么瑕疵么?当然有!
假设我们又两台机器,有一台机器 C1 的top 100 的ip是 192.128.1.1,top 101 是 192.128.1.2,那么就可能存在另一台机器 C2 上 192.128.1.1 可能从来没有出现过,但是 192.128.1.2 却也排在 top 101,其实总数上 192.128.1.2 是超过192.128.1.1,但是很不幸的是,我们每台机器只保存了 top100,所以它在计算过程中被淘汰了,导致结果不准确。
解决方案:
先用 hash 算法,把 ip 按照 hash 值哈希到不同的机器上,保证相同的ip在相同的机器上,再对每个机器上的ip文件再hash成小文件,这个时候再分别统计小文件的出现频次,用最小根堆处理,不同文件的结果排序,就可以得到每台机器的top 100,再进行不同机器之间的结果排序,就可以得到真正的 top 100。

一般而言,像这种海量数据,比如 有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL. ,内存一次性读不下,只能通过 分而治之。
hash 到不同的小文件,一直这样划分,直到满足资源的限制:
- hash分流
- hash表统计
- 最小堆/外部排序
如果允许一定的误差存在,其实还可以考虑使用布隆过滤器(Bloom filter),将URL挨个映射到每一个Bit,在此之前判断该位置是否映射过,来证明它是否已经存在。(有一定的概率出现误判,因为其他的URL也可能会映射到同一位置)
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:Java源码解析,JDBC,Mybatis,Spring,redis,分布式,剑指Offer,LeetCode等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。
100台机器上海量IP如何查找出现频率 Top 100?的更多相关文章
- 大数据学习day17------第三阶段-----scala05------1.Akka RPC通信案例改造和部署在多台机器上 2. 柯里化方法 3. 隐式转换 4 scala的泛型
1.Akka RPC通信案例改造和部署在多台机器上 1.1 Akka RPC通信案例的改造(主要是把一些参数不写是) Master package com._51doit.akka.rpc impo ...
- shell远程操作另外一台机器上数据
shell远程操作另外一台机器上的数据,有两种方式: 1 .配置免密登陆,2.使用sshpass 当前存在两台虚拟机,ip地址分别为:192.168.3.32 192.168.3.33 一.免密登陆操 ...
- window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法
window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法 本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装 ...
- 不要将缓存服务器与Tomcat放在单台机器上,否则出现竞争内存问题
缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况. 1.不要将缓存服务器与Tomcat放在单台机器上,否则出现竞争内存问题 2.不要将缓存服务器 ...
- 通过Mouse Without Borders在多台机器上共享键盘鼠标
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:通过Mouse Without Borders在多台机器上共享键盘鼠标.
- 在同一台机器上让Microsoft SQL Server 2000/ SQL2005/ SQL2008共存
可能很多朋友都遇到想同时在自己的机器上运行Microsoft SQL Server 2000以及Microsoft SQL Server 2005和Microsoft SQL Server 2008. ...
- 一台机器上运行多个ActiveMq
由于业务需要一台机器上运行多个ActiveMq,这里主要说一下有什么地方不重复: 1.brokerName名称不能重复 2.端口号不能重复uri = tcp://localhost:50509 3.k ...
- 如何在同一台机器上安装多个MySQL的实例
转自:'http://www.cnblogs.com/shangzekai/p/4375271.html 最近由于工作的需要,需要在同一台机器上搭建两个MySQL的实例,(注:已经存在了一个3306的 ...
- Nginx一台机器上负载均衡多个Tomcat
默认你的机器上安装了Java环境,解压了Tomcat,安装了Nginx.默认这几个tomcat都部署在一台机器上. 对于Tomcat需要改三个地方[你部署的所有tomcat这三个地方都不能一样,如果你 ...
随机推荐
- 【转】TCP的三次握手与四次挥手理解及面试题
转自:https://blog.csdn.net/qq_38950316/article/details/81087809 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据 ...
- hdfs中数据迁移
1.hdfs集群间数据迁移 hadoop distcp hdfs://192.128.112.66:8020/user/hive/warehouse/data.db/dwi_xxxx_d /user ...
- SprngCloud微服务框架搭建(一)
参照来源 :https://blog.csdn.net/forezp/article/details/70148833 1.简介 目前来说,SpringCloud是比较完整的微服务解决方案框架.不像其 ...
- 刷题-力扣-63. 不同路径 II
63. 不同路径 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii/ 著作权归领扣网络所有.商业转 ...
- Windows搭建mac黑苹果系统
最近看到一个开源工具tidevice,是可以脱离mac来做ios自动化测试的.看到这么方便,就想着来尝尝鲜.但由于使用该工具,是需要基于WebDriverAgent的,该工具又需要使用Xcode重签名 ...
- RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列
系列文章: RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解 RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列 ...
- docker容器 如何精简镜像减小体积
写在前面 我们在上篇<Docker容器 关于镜像构建的安全问题>一起学习了如何构建一个基于安全的镜像,这篇小作文我们会学习镜像构建的另一个关键性问题,为何别人打造的镜像只有10MB而我的有 ...
- ES6两种静态属性的书写方法
1.这种可以不用实例化对象就能输出. class Car{ constructor(){ } } Car.tool=4 console.log(Car.tool);//4 2.必须实例化后才能输出.但 ...
- 自己封装一个Object.freeze()方法
1.遍历所有属性和方法 2.修改遍历到的属性的描述 3.Object.seal() Object.defineProperty(Object,'freezePolyfill',{ value:func ...
- x和y为正整数变量,求满足 x+y | xy 的通解。
x和y为正整数变量,求满足 x+y | xy 的通解. 解:由题设可知存在正整数t满足t(x+y)=xy. 设m=(x,y),则存在正整数u和v满足: x=mu, y=mv, (u,v)=1. 于是有 ...