Fork me on GitHub

海量数据处理

海量数据处理

存储(内存和外存)、计算资源(CPU)这是海量数据处理面对的两个问题:

  • 1.一台机器的内存存不下;
  • 2.一台机器处理起来太慢;

海量数据处理的核心思想:分治

  • 1.单机: 利用外存,分批加入内存处理; (先在内存中处理一部分,放入外存,再处理下一部分...依次类推把文件处理完...) 
  • 2.多机: 对数据分片,利用多机内存存储;  (分布到多台机器内存中,才能快速查找)
  • 3.多机: 并行计算,利用多线程、多机并行处理; (一小块一小块的在每台机器上排序处理,最后再merge ,MR的思想)

一些处理技巧:

  • 外部排序: 多路归并、 桶排序
  • 哈希分片
  • 位图

 

常见问题

  • 1.海量数据排序;
  • 2.海量数据查询;
  • 3.海量数据TOPK
  • 4.海量数据求频率TOPK;
  • 5.海量数据去重/找重;
  • 6.两海量问题找重

 


1.按照金额大小给10GB的订单文件进行排序;
2.有一个IP地址白名单文件,包含10亿个IP地址,判断某IP是否在白名单中?
3.10亿个整数,判断某个整数是否在其中?
4.10亿个整数,放在文件中,内存有限,如何求最大的TOP100个整数?
5.100GB的搜索关键词文件,统计出现频率TOP100关键词?
6.一个文件中包含10亿条URL,有可能会重复,将重复的去掉?
7.给你a、b两个文件,各自有50亿条URL,每条URL占用64字节,内存限制是4GB,找出a、b文件共同的URL

 

1.按照金额大小给10GB的订单文件进行排序;

离线处理海量数据排序

外 10GB
内 1.5GB

方法一:(单机、分批、多路归并排序)
从文件中读取1GB数据到内存, 进行排序(堆、快排,归并复杂度是O(n)), 存储到外存;  再读取1GB外存文件到内存, 排序后再存储到外存...
得到10个有序的小文件,  之后合并为整个大的有序文件,合并k个有序文件;   (类似于 合并两个有序数组、链表、 合并k个有序链表) ,利用归并merge函数的思想。
申请大小为10的数组, 每次从10个文件中读取一个数, 从这个数组的10个数据中找其中最小的写到另外一个文件中,  之后读取最小数的那个文件中再读取一个数补全10个数组... 
优化:每个文件前各加个100M的前置缓存,每次读取100M的数据到内存中, 减少IO操作;

方法二:(通排序) (适用于 每个文件的数据分布比较均匀,订单的金额区间不是很大;) 
10GB文件,扫描一遍这个订单文件,给它按金额划分文件:
第0个文件是0~99 
第1个文件是100~199
...
第9个文件是900~999
如果订单金额分布均匀的话每个文件大小1G左右,每个小文件放内存中排序再写到小文件中, 这样每个小文件内部是有序的、不同文件间也是有序的, 整个文件就是有序的了。 

 

2.有一个IP地址白名单文件,包含10亿个IP地址, 判断某IP是否在白名单中?

实时服务场景 - 海量数据查询问题
 10亿个 IP 地址 
 32位 int类型整数   
 4字节 

 10亿*4字节 = 1 * 10^3 * 10^3 * 10^3 * 4  = 1GB*4 = 4GB 

 ①如果内存有4G可以 构造哈希表、红黑树、位图

 ②如果内存限制是1GB, 可构造位图需要的空间:  

   需要的二进制位 0 ~ 2^32 - 1 bits

   2^32 / 8 字节 = 4G / 8 字节 = 500MB

   0~2^32 - 1个位图, 看是否存在, 存在就标记为1;

 ③如果每个机器内存200M, 那么4GB的数据就放不下了,利用哈希分片多机处理

   考虑多台机器 4个2.5GB 的机器,如果把IP地址划分到这4台机器上:

      MD5(IP) % 4 = 0~ 3 分到对应的机器中; 利用md5让数据分布 随机均匀些

   (0号机器) 2.5G 、(1号机器)2.5G、 (2号机器)2.5G、  (3号机器)2.5G

MD5(IP) % 4看是否落到哪台机器  

3.10亿个整数,判断某个整数是否在其中?

 

4.10亿个整数, 放在文件中, 内存有限, 如何求最大的TOP100个整数?

10亿个整数,
堆 - top100

内存 依次从文件中读取文件, 利用小顶堆, 堆顶元素个数不超过100就直接插入, 超过就和堆顶元素比大小,  比堆顶元素大就堆顶元素删除后插入, 小就不作处理;(跟内存中top排序一样) ;

        优化是每次读取100M数据到内存中,减少IO操作; 
----------------------------------------------------------------------------
外存 10亿个整数

5.100GB的搜索关键词文件, 统计出现频率TOP100关键词?

100GB 关键词 频率 

①统计每个关键词出现频率; 

    先排序、 借助哈希表  

②TOP100 堆  

单机: 先排序(多路归并)  类似上述题目场景 

顺序扫描这100GB的文件,  统计每个关键词出现的频率写到文档中; (word,count) 

利用哈希表统计出现的频率数 

假设内存有12GB,100G的文件分10个批次 依次放进10G的内存中, 

哈希分片 md5(word)%10 = 0 ~ 9, 把结果为0的拉到内存中用哈希表统计每个单次出现的频率,写到一个小文件中;
依次类推... 
10个1GB的小文件(每个小文件对应关键词对应出现的频率), 合并为一个大文件求TOP100 

 

6.一个文件中包含10亿条URL,有可能会重复,将重复的去掉

 10亿个URL
 64或者128字节/URL
   64*10^9 = 64GB
如果内存中放得下,可以基于排序、 或者 基于哈希表去重

基于排序:
内存: 一个个读取url, 看是否相同,  跟上一个不同就放入结果文件,依次类推,频率IO;

  优化: 开辟100M内存空间加个缓存,读取一批数据到内存,每次从内存中读取; 


基于哈希表 - 哈希分片:

64GB 每次8G到内存, 分8次;

md5(url)%8 = 0 ~ 7

结果为0的全放内存中去重, (排序or哈希表去重), 把去重后的写到一个小文件中;

依次类推;

最后把这8个小文件合并;

 

内存存不下了,分批哈希分片,哈希分片处理;

7.给你a、b两个文件,各自有50亿条URL,每条URL占用64字节,内存限制是4GB,找出a、b文件共同的URL

a:50亿

b:50亿

两个方法: 

  • 1.排序+双指针;  
  • 2.哈希表

排序 

对a、b排序之后顺序扫描, 从a、b中各取出一个数比较, 相同就放到一个文件中, 不同就看哪个指针往后移动; 

为了加速处理预支1GB缓存;

哈希表

没办法对一个文件构建哈希表,先哈希分片,分20次处理 md5(url)%20 = 0 ~ 19

两个文件中等于0的放内存中, 对这两个文件找相同的元素,写到一个小文件中

 

 
 
 
posted @   kris12  阅读(233)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
levels of contents
点击右上角即可分享
微信分享提示