热身1T文件操作的思考
- 分治思想引入案例
- 单机处理大数据的问题
- 集群分布式处理大数据
- 集群分布式处理大数据优劣的辩证
分治思想引入案例
- 十万个元素(单词)需要存储,如何存储?
- 如果想查找某一个元素,最简单的遍历方式的复杂度是多少?
-
如果我们期望复杂度是O(4)呢?
对十万个元素的哈希值分25000个桶存放,平均每个桶存放四个,理想情况下复杂度是O(4)
分而治之的思想非常重要,常见于以下技术:
- Redis集群
- Hadoop
- Hbase
- ElasticSearch
单机处理大量数据的问题
需求:有一个非常大的文本文件,里面有非常多的行,只有两行内容一样,它们出现在未知的位置,需要查找到它们。硬件:单台机器,而且可用的内存很少,也就500MB
- 假如IO速度是500MB/S
- 1T文件读取一遍需要2000秒约30分钟
- 循环遍历需要N次IO时间
- 分治思想可以使时间降为2次IO
一行1000B,1T数据约10亿行,为了找到相同的行,从第一行开始向下遍历,最坏情况下需要读取文件10亿次,每次都是从读取的位置开始向后遍历所有行,并比较直到找到相同的行,假设平均每次读取需要耗时15分钟,最坏情况下需要10亿*15分钟=2.5亿小时。
下面采用分而治之的方法,遍历一遍1T文件,将所有行数据哈希之后对2000取余,这样就能将1T大文件拆成2000个小文件,每个小文件平均大小500M,大于500M的再次当成大文件继续单独处理,这样相同的行一定位于这些小文件中,这些小文件可以一次性读取到内存中,逐行进行比较(内存寻址比Io寻址快10万倍),这样只需读1T文件两次并写一次,就可以得到结果,假设写一次需要30分钟,则一共需要1.5个小时。与上面需要2.5亿小时相比,处理时间完全不在一个数量级,而且分而治之之后不同的小文件还可以交给不同的节点处理,这样并行去处理还可以减少处理的时间
如何对1TB文件按照每行的hash值进行排序?
- 假如IO速度是500MB/S
- 1T文件读取一遍需要约30分钟
方式1:外部有序,内部无序。读取每一行计算哈希值,哈希值分2000个范围存放到2000个文件中,这样读取一遍就能得到2000个文件外部有序,内部无序
方式2:逐一读取500M排序,内部有序,外部无序 ,然后进行归并排序。每次读取500M的数据,在内存中排序,然后将结果写到文件中,这样读取一遍就能得到2000个文件内部有序,外部无序,然后进行归并排序
集群分布式处理大数据
需求:
- 有一个非常大的文本文件,里面有几百亿行,只有两行内容一样,它们出现在未知的位置,需要查找到它们。
- 分钟、秒级别完成,单机是不可能做到的,分布式集群可以做到
- 硬件:2000台机器,而且可用的内存500MB
由于涉及到计算机之间文件传输,千兆带宽,100MB/s
假设1T数据平均分布在2000个节点上,每个节点500M数据,所有节点同时读取500M的数据,对每行做哈希然后对2000取余,再将处理后的数据发送到对应的机器上(取余的结果对应节点),然后每个节点继续同步处理已经处理过一次的数据,这次处理秒级就可以出结果。这里主要耗时是在节点之间的数据传输上,拉取网卡100MB/S,每个节点拉取512MB的数据,需要5s时间,所有节点可以并行拉取数据,并受限于网卡速度,第一次处理并将数据发送到不同节点上可能需要耗时几十秒(这里假设是1分钟),这比单机处理还是要快很多的。在存储数据时如果就是按照每行的哈希值取余存储的,则不需要第一次处理了,秒级就可以出结果
之前忽略了上传时间:1TB/100MB = 10000S 10000s/3600S = 3H,这个在实际使用时是可以忽略的,数据可以一开始就存储在分布式系统上
集群分布式处理大数据优劣的辩证
- 2000台真的比一台快吗?
- 如果考虑分发上传文件的时间呢?
- 如果考虑每天都有1TB数据的产生呢?
- 如果增量了一年,最后一天计算数据呢?
- 1 天 1H(单机) 3H1M2S(集群)
- 2 天 2H 3H2M4S
- 3 天 3H 3H3M6S
- 4 天 4H 3H4M8S
集群分布式处理大数据时,有以下的处理思想:分而治之、并行计算、计算向数据移动、数据本地化读取