来源:https://blog.csdn.net/lili0710432/article/details/48142791
所谓海量数据处理,就是数据量太大,无法在较短时间内迅速解决,无法一次性装入内存。本文在前人的基础上总结一下解决此类问题的办法。那么有什么解决办法呢?
时间复杂度方面,我们可以采用巧妙的算法搭配合适的数据结构,如Bloom filter/Hash/bit-map/堆/数据库或倒排索引/trie树。空间复杂度方面,分而治之/hash映射。
海量数据处理的基本方法总结起来分为以下几种:
- 分而治之/hash映射 + hash统计 + 堆/快速/归并排序;
- 双层桶划分;
- Bloom filter/Bitmap;
- Trie树/数据库/倒排索引;
- 外排序;
- 分布式处理之Hadoop/Mapreduce。
前提基础知识:
1 byte= 8 bit。
int整形一般为4 bytes 共32位bit。
2^32=4G。
1G=2^30=10.7亿。
1 分而治之+hash映射+快速/归并/堆排序
问题1
给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
分析:50亿*64=320G大小空间。
算法思想1:hash 分解+ 分而治之 + 归并
- 遍历文件a,对每个url根据某种hash规则求取hash(url)/1024,然后根据所取得的值将url分别存储到1024个小文件(a0~a1023)中。这样每个小文件的大约为300M。如果hash结果很集中使得某个文件ai过大,可以在对ai进行二级hash(ai0~ai1024)。
- 这样url就被hash到1024个不同级别的目录中。然后可以分别比较文件,a0VSb0……a1023VSb1023。求每对小文件中相同的url时,可以把其中一个小文件的url存储到hash_map中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_map中,如果是,那么就是共同的url,存到文件里面就可以了。
- 把1024个级别目录下相同的url合并起来。
问题2
有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。
解决思想1:hash分解+ 分而治之 +归并
- 顺序读取10个文件a0~a9,按照hash(query)%10的结果将query写入到另外10个文件(记为 b0~b9)中。这样新生成的文件每个的大小大约也1G(假设hash函数是随机的)。
- 找一台内存2G左右的机器,依次对用hash_map(query, query_count)来统计每个query出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样得到了10个排好序的文件c0~c9。
- 对这10个文件c0~c9进行归并排序(内排序与外排序相结合)。每次取c0~c9文件的m个数据放到内存中,进行10m个数据的归并,即使把归并好的数据存到d结果文件中。如果ci对应的m个数据全归并完了,再从ci余下的数据中取m个数据重新加载到内存中。直到所有ci文件的所有数据全部归并完成。
解决思想2: Trie树
如果query的总量是有限的,只是重复的次数比较多而已,可能对于所有的query,一次性就可以加入到内存了。在这种假设前提下,我们就可以采用trie树/hash_map等直接来统计每个query出现的次数,然后按出现次数做快速/堆/归并排序就可以了。
问题3:
有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。
类似问题:怎么在海量数据中找出重复次数最多的一个?
解决思想: hash分解+ 分而治之+归并
- 顺序读文件中,对于每个词x,按照hash(x)/(1024*4)存到4096个小文件中。这样每个文件大概是250k左右。如果其中的有的文件超过了1M大小,还可以按照hash继续往下分,直到分解得到的小文件的大小都不超过1M。
- 对每个小文件,统计每个文件中出现的词以及相应的频率(可以采用trie树/hash_map等),并取出出现频率最大的100个词(可以用含100个结点的最小堆),并把100词及相应的频率存入文件。这样又得到了4096个文件。
- 下一步就是把这4096个文件进行归并的过程了。(类似与归并排序)
问题4
海量日志数据,提取出某日访问百度次数最多的那个IP
解决思想: hash分解+ 分而治之 + 归并
- 把这一天访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有2^32个IP。同样可以采用hash映射的方法,比如模1024,把整个大文件映射为1024个小文件。
- 再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。
- 然后再在这1024组最大的IP中,找出那个频率最大的IP,即为所求。
问题5
海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。
解决思想: 分而治之 + 归并。
注意TOP10是取最大值或最小值。如果取频率TOP10,就应该先hash分解。
- 在每台电脑上求出TOP10,采用包含10个元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。比如求TOP10大,我们首先取前10个元素调整成最小堆,如果发现,然后扫描后面的数据,并与堆顶元素比较,如果比堆顶元素大,那么用该元素替换堆顶,然后再调整为最小堆。最后堆中的元素就是TOP10大。
- 求出每台电脑上的TOP10后,然后把这100台电脑上的TOP10组合起来,共1000个数据,再利用上面类似的方法求出TOP10就可以了。
问题6
在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数。
解决思路1 : hash 分解+ 分而治之 + 归并
2.5亿个int数据hash到1024个小文件中a0~a1023,如果某个小文件大小还大于内存,进行多级hash。每个小文件读进内存,找出只出现一次的数据,输出到b0~b1023。最后数据合并即可。
解决思路2 : 2-Bitmap
如果内存够1GB的话,采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^32*2bit=1GB内存。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。
注意,如果是找出重复的数据,可以用1-bitmap。第一次bit位由0变1,第二次查询到相应bit位为1说明是重复数据,输出即可。
问题7
一共有N个机器,每个机器上有N个数。每个机器最多存O(N)个数并对它们操作。如何找到N^2个数中的中数?
解决思想1 : hash分解 + 排序
- 按照升序顺序把这些数字,hash划分为N个范围段。假设数据范围是2^32 的unsigned int 类型。理论上第一台机器应该存的范围为0~(2^32)/N,第i台机器存的范围是(2^32)*(i-1)/N~(2^32)*i/N。hash过程可以扫描每个机器上的N个数,把属于第一个区段的数放到第一个机器上,属于第二个区段的数放到第二个机器上,…,属于第N个区段的数放到第N个机器上。注意这个过程每个机器上存储的数应该是O(N)的。
- 然后我们依次统计每个机器上数的个数,一次累加,直到找到第k个机器,在该机器上累加的数大于或等于(N^2)/2,而在第k-1个机器上的累加数小于(N^2)/2,并把这个数记为x。那么我们要找的中位数在第k个机器中,排在第(N^2)/2-x位。然后我们对第k个机器的数排序,并找出第(N^2)/2-x个数,即为所求的中位数的复杂度是O(N^2)的。
解决思想2: 分而治之 + 归并
先对每台机器上的数进行排序。排好序后,我们采用归并排序的思想,将这N个机器上的数归并起来得到最终的排序。找到第(N^2)/2个便是所求。复杂度是O(N^2 * lgN^2)的。
2 Trie树+红黑树+hash_map
这里Trie树木、红黑树或者hash_map可以认为是第一部分中分而治之算法的具体实现方法之一。
问题1
上千万或上亿数据(有重复),统计其中出现次数最多的钱N个数据。
解决思路: 红黑树 + 堆排序
- 如果是上千万或上亿的int数据,现在的机器4G内存可以能存下。所以考虑采用hash_map/搜索二叉树/红黑树等来进行统计重复次数。
- 然后取出前N个出现次数最多的数据,可以用包含N个元素的最小堆找出频率最大的N个数据。
问题2
1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。请怎么设计和实现?
解决思路:trie树。
这题用trie树比较合适,hash_map也应该能行。
问题3
一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
解决思路: trie树 + 堆排序
这题是考虑时间效率。
1. 用trie树统计每个词出现的次数,时间复杂度是O(n*len)(len表示单词的平准长度)。
2. 然后找出出现最频繁的前10个词,可以用堆来实现,前面的题中已经讲到了,时间复杂度是O(n*lg10)。
总的时间复杂度,是O(n*le)与O(n*lg10)中较大的哪一个。
问题4
搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录,这些查询串的重复读比较高,虽然总数是1千万,但是如果去除重复和,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就越热门。请你统计最热门的10个查询串,要求使用的内存不能超过1G。
解决思想 : trie树 + 堆排序
采用trie树,关键字域存该查询串出现的次数,没有出现为0。最后用10个元素的最小推来对出现频率进行排序。
3 BitMap或者Bloom Filter
3.1 BitMap
BitMap说白了很easy,就是通过bit位为1或0来标识某个状态存不存在。可进行数据的快速查找,判重,删除,一般来说适合的处理数据范围小于8*2^32。否则内存超过4G,内存资源消耗有点多。
问题1
已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数。
解决思路: bitmap
8位最多99 999 999,需要100M个bit位,不到12M的内存空间。我们把0-99 999 999的每个数字映射到一个Bit位上,所以只需要99M个Bit==12MBytes,这样,就用了小小的12M左右的内存表示了所有的8位数的电话
问题2
2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。
解决思路:2bit map 或者两个bitmap。
将bit-map扩展一下,用2bit表示一个数即可,00表示未出现,01表示出现一次,10表示出现2次及以上,11可以暂时不用。
在遍历这些数的时候,如果对应位置的值是00,则将其置为01;如果是01,将其置为10;如果是10,则保持不变。需要内存大小是2^32/8*2=1G内存。
或者我们不用2bit来进行表示,我们用两个bit-map即可模拟实现这个2bit-map,都是一样的道理。
3.2 Bloom filter
Bloom filter可以看做是对bit-map的扩展。
参考july大神csdn文章 Bloom Filter 详解
4 Hadoop+MapReduce
参考引用july大神 csdn文章
MapReduce的初步理解
Hadoop框架与MapReduce模式
相关推荐
1. "海量数据带答案.docx":这份文档可能包含了海量数据处理的实例或者练习题,并提供了相应的解答,有助于读者通过实践来学习和验证理论知识。 2. "2的32次方.docx":在计算机科学中,2的32次方(4,294,967,296)...
在IT行业中,面对中等规模的海量数据处理是一项常见的挑战。在这个实例分析中,我们将探讨如何利用一台普通服务器高效地处理近60亿PV(页面浏览量)的数据。这一问题的核心在于优化数据处理策略,充分利用有限的计算...
海量数据处理方法总结 本文总结了常用的海量数据处理方法,包括 Bloom filter、Hashing 和 bit-map 等。这些方法可以用来解决大数据量的问题,例如数据字典、判重、集合求交集等问题。 Bloom Filter Bloom filter...
大数据量,海量数据 处理方法总结 包括Bloom filter 哈希 bit-map 堆 双层桶划分 数据库索引 倒排索引 外排序 trie树等。细分为适用范围、要点、实例等。
### 大数据量、海量数据处理方法总结 #### 一、引言 随着互联网技术的发展,数据量呈现出爆炸性增长的趋势。如何高效地处理这些大数据成为了一项挑战性的任务。在IT行业,尤其是在搜索引擎、社交媒体等领域,处理...
这些技术是大数据量和海量数据处理的基石,在数据科学、网络分析、搜索引擎优化等众多领域有着广泛的应用。在实际使用过程中,可以根据数据的特性和处理需求灵活选择合适的处理方法,并结合问题实例进一步理解和掌握...
### 海量数据处理的方法详解 #### 一、Bloom Filter **定义**: Bloom Filter是一种高效的数据结构,用于快速判断一个元素是否在一个集合中。它使用位数组和多个哈希函数来实现。虽然Bloom Filter可能会产生误报...
总之,海量数据处理与高可用性方案的核心在于通过数据库优化、分区策略和智能负载均衡技术的综合运用,以提升系统性能和稳定性。这不仅涉及到单个技术的运用,还包括了对整个系统架构的全面考量。采用这些方法,可以...
本文是关于海量数据快速批量处理的研究与实现的论文,重点研究了在数据库应用中如何快速大批量抽取和处理数据,并针对特定需求提出了基于共性特征的数据集...通过这些方法和工具,可以实现高效、准确的海量数据处理。
随着物联网(IoT)的快速发展,其应用项目已逐步进入推广应用阶段,随之而来的是物联网系统中海量数据处理的新需求。物联网传感器分布于工业、农业、能源、交通、环保、医疗等多个领域,持续产生大量数据,这些数据...
然而,传统的单机数据处理方法在处理如此大规模数据时,面临明显的存储和计算瓶颈。 为了解决这些问题,文章提出了一种基于开源框架Hadoop的海量日志数据处理方法。Hadoop是一个由Apache软件基金会支持的开源分布式...
随着信息技术的发展,数据挖掘已成为从海量数据中提取有价值信息的关键技术。Weka是一款由新西兰怀卡托大学开发的开源软件,它包含了丰富的数据挖掘工具,能够支持数据预处理、分类、回归、聚类、关联规则挖掘等多种...
Hadoop是目前最受关注的大数据处理平台和解决方案,并且已经广泛应用于生产环境。本书主要介绍Hadoop技术的相关知识,不但详细介绍了Hadoop、MapReduce、HDFS、Hive和Sqoop,还深入探讨了Hadoop的运维和调优,并包含...
在技术研究领域,本文的作者王彩玲,来自西安石油大学计算机学院,其主要研究方向为遥感影像数据处理技术,其工作展示了她和她的团队在海量数据处理方面的专长,以及在构建高性能计算机群架构方面的深厚技术积累。...
《Hadoop海量数据处理 技术详解与项目实战 大数据云计算IP 第2版》这本书是深入理解Hadoop技术及其实战应用的重要参考资料。Hadoop作为大数据处理领域的一个核心框架,因其分布式计算的能力,被广泛应用于各类大数据...
本文所探讨的“基于Hadoop的海量日志数据处理”正是在这样的背景下,针对传统单机处理方法在海量数据处理方面所面临的局限性,提出了一种新的解决方案。 在处理海量数据时,传统的单机方法存在明显的存储和计算瓶颈...
在大数据处理领域,面对日增的海量数据,有效的存储和计算策略至关重要。本文将探讨如何利用Google的LevelDB库处理亿级数据的离线计算,尤其是对于每天接近10GB,涉及2亿用户的大型数据集。LevelDB是一个轻量级、高...
本文所涉及的知识点围绕“基于大规模集群的海量数据处理技术”这一新型课程的教学探索。课程旨在将工业界最新的技术整合到教学实践中,以提升学生的创新与实践能力。该课程由清华大学计算机科学与技术系与Google公司...