常见海量数据问题及解决方案

现有海量日志数据,要提取出某日访问百度次数最多的那个IP.内存空间有限只有512MB不能全部加载

对于大部分的数据量比较大的问题而言,分治都是一个可选的解决方案,解决方法基本划分为三步走:

 1. 如何有效的划分数据。一般是hash划分,这样能让相同的数据划分到同一个文件中   类似于map-reduce的map
 2. 如何在子集上解决问题。 类似于reduce阶段的处理
 3. 如何合并结果。 比如归并排序。
  1. 首先解决如何划分。由于IP地地址范围从000.000.000.000~255.255.255.255共有2^32个大约4GB,那么我们可以通过取模的方式进行划分,直接将四段数据相连就得到一个IP对应的数字A,再对A模1024(模数取多少可以自己指定,保证每个小文件能被放到内存就好),这样大文件被划分成小文件了,并且相同的IP一定被划分到相同的文件中。
  2. 其次解决每个小文件中TOP1的问题。可以构造自己的HashMap,key为IP,value为当前出现次数,通过最小堆找到value最大的Key即为当前文件中出现次数最多的IP。
  3. 最后要解决结果合并问题。这里直接将1024个子文件的统计结果进行归并排序比较,找到最大的数据。

有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词

这个和第一个问题没有太大区别,第一个问题是Top1,这个问题是TOP100。

第一步hash划分,拆成若干小文件,并且相同的词必然在同一个文件中。
第二步可以考虑用堆排序 ,即常用的TopN手段。
第三部就是更为常见的归并排序。

给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?

还是分治思想,对a,b进行分片,a,b文件大小都大约320G,那么每个文件都通过hash切分成1G的320个小文件,同样的url会划分到同一个文件中。

然后求两个小文件集合中,每个小文件共同的url。

lista->{a1,a2,a3...a320}

listb->{b1,b2,b3...b320}

resultlist = []
for tmpfile in lista:
    for infile in listb:
        for url in tmpfile:
            if url in infile:
                resultlist.add(url)

有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。

  1. 划分数据:顺序读取10个文件,按照hash(query)%10的结果将query写入到另外10个文件中。这样新生成的文件每个的大小大约也1G,并且相同的query在同一个文件中。
  2. 在子集上解决问题:用hash_map(query, query_count)来统计每个query出现的次数。利用快速/堆排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。
  3. 合并结果:对10个排好序的文件进行归并排序。

在2.5亿个整数中找出不重复的整数,注:内存不足以容纳这2.5亿个整数。

方案1:采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次)进行。然后扫描这2.5亿个整数,查看Bitmap中相对应位(00变01,01变10,10保持不变)。扫描完查看bitmap,把对应位是01的整数输出。
BitMap的原理和实现

方案2:也可采用与第1题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。

处理海量数据问题的四板斧

1.分治
基本上处理海量数据的问题,分治思想都是能够解决的,只不过一般情况下不会是最优方案,但可以作为一个baseline,可以逐渐优化子问题来达到一个较优解。传统的归并排序就是分治思想,涉及到大量无法加载到内存的文件、排序等问题都可以用这个方法解决。

2.哈希(Hash)
Hash对数据进行划分,让相同的数据划分到同一个文件中。

3.堆(Heap)
堆排序是一种比较通用的TopN问题解决方案,要求N不大,使得堆可以放入内存。

4.bit(位集或BitMap)
判断数字是否重复的问题,位图法是一种非常高效的方法。
BitMap的原理和实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值