1、需求
有一个大小为1TB的文件,里面有许多行,其中只有两行一样,这两行的位置未知,需要找出这两行。
2、单机处理思路
假设如下:
- 单机可用内存500M
- IO速度为500M/s,读取1TB的文件约2000s,约30分钟。
与硬盘IO时间相比,CPU计算以及内存存取时间可以忽略。因此,以下估算中,主要估算的是硬盘IO时间,忽略了CPU计算以及内存存取时间。
最简单的思路:
- 读取文件的第一行到内存中
- 读取文件的第二行,并与第一行内存做比较
- 如果两行内容相同,则找到结果
- 如果两行内容不同,则将第二行从内存中清理掉,并读取下一行进行比较
- 将所有行都读取一遍与第一行进行比较,耗费时间约30分钟
- 假设这1TB文件共有N行,最坏情况(最后两行相同)下需要(N-1)*30分钟才能得到结果
思路优化:
- 创建2000个空文件
- 依次读取文件的每一行,并计算这一行的hashcode
- 将hashcode与2000取模,得到一个0~2000的数,假设为n
- 将这一行内容追加写入到之前创建的第n个文件中
- 经过一次IO时间,即30分钟,可以得到2000个小文件(假设均匀分布,每个文件约500M)
- 经过以上处理后,内容相同的两行一定处于同一个文件中
- 读取第一个小文件全部内容到内存中(可用内存500M)查找是否有相同行
- 最坏情况下(相同两行处于最后一个小文件中),总共需要2*30分钟得出结果
PS:假设问题是需要对1TB文件中的每一行(假设为数字)进行排序,也可以采用类似的思路:
思路一(外部无序,内部有序):
- 读取文件的每一行,根据hashcode将其散列到2000个小文件中
- 对每个小文件中的内容进行排序
- 得到2000个小文件,每个小文件内部内容有序,但是两个小文件之间的内容是无序的
- 采用归并算法,最终得到一个有序大文件
思路二(外部有序,内部无序)
- 同样将1TB大文件拆分为2000个小文件
- 拆分方式不再是根据hashcode拆分,而是根据每行中数字的大小进行拆分
- 比如大小为0~99的放到第一个文件中,大小为100~199的放到第二个文件中
- 最终得到的2000个小文件,每两个小文件之间的内容是有序的,小文件内部是无序的
- 对每个小文件内部内容进行排序
- 最后将每个小文件拼接起来即得到一个有序大文件
3、集群处理思路
使用集群处理上述找相同两行内容的需求:
- 同样假设硬盘IO为500M/s
- 假设每台机器内存为500M
- 假设网络IO为100M/s
PS:忽略1TB数据分发到2000台机器的时间,假设这1TB文件本来就是采用分布式存储系统分散存在2000台机器中的,每台机器存储数据为500M
- 2000台机器,每台机器并行将各自存储的500M数据根据hashcode各自拆分为2000个小文件,耗费时间约1s(每台机器读取数据为500M)
- 2000台机器,每台机器负责处理hashcode相同的文件,比如第一台机器负责处理2000台机器上所有hashcode为0的数据,第二台机器负责处理2000台机器上所有hashcode为1的数据
- 那么每台机器需要从其他机器上通过拉取它需要处理的文件,假设均匀分不下,则每台机器需要拉取的文件大小约为500M,花费时间约为5s
- 2000台机器并行计算,1秒得出结果
- 累计耗费总时间为7秒
参考链接 :
清华大牛精讲Hadoop全套教程_从入门到精通(HDFS集群/MapReduce底层原理、源码~~)_哔哩哔哩_bilibili