一. 海量数据处理的困难
海量数据处理的困难用一句话概括就是:时空(时间,空间)资源不够。
- 时间受限:无法在有限的时间内,完成针对海量数据的某项特定工作的处理;
- 空间受限:无法将海量数据一次性读入内存;
对于时间受限的问题,我们一般的解决办法是高效的算法配合恰当的数据结构,比如哈希表,堆,二叉树等;而对于空间受限的问题,一般的解决办法就是 “大而化小,分而治之” 的策略,既然一次行不通,那就一部分一部分的读取,每读入一部分可以生成一个小文件,小文件是可以直接读放入内存中去的,然后就这样分割大数据之后,再依次处理各个的小文件的数据,最后归并即可。
二.常用方法
1.哈希映射
- 解决问题:海量数据不能一次性读入内存,而我们需要对海量数据进行相应的操作(计数、排序等操作)
- 使用工具:hash函数(hash表);堆
这种方法是典型的== “分而治之”== 的策略,也是解决空间限制最常用的方法,基本思路可以用下图表示。先借助哈希算法,计算每一条数据的 hash 值,按照 hash 值将海量数据分布存储到多个桶中(所谓桶,一般可以用小文件实现)。根据 hash 函数的唯一性,相同的数据一定在同一个桶中。如此,我们再依次处理这些小文件,最后做合并运算即可。
注:一般用 hash 函数将数据映射到桶的方法是:
- bucket_ID = H(mi) % n
其中 H(mi) 为第 i 条数据,bucket_ID 为桶标号,n 为要设置的桶的数量。关于桶数量(即小文件数量)设置的基本的原则是:每个小文件的大小比内存限制要小。
比如处理 1G 的大文件,内存限制为 1M,那就可以把大文件分成 2000 个小文件(甚至更多),这样每个小文件的大小约 500K (甚至更小),我们就可以轻松读入内存进行处理了。
2.分文件+哈希统计+内存处理(堆/快速/归并排序)
对于固定大小的海量数据,通常可以采用 分文件+哈希统计+内存处理(堆/快速/归并排序) 的方法。
- 对于字符串数据,可以对字符串进行哈希(字符串.hashCode() ),哈希值%n ( n为分成的小文件的数量 ),这样来说同一个字符串必然分配到同一个小文件当中,然后如果哈希均匀的话(每个小文件的数量差不多一样多