为什么计算也要分布式
使用HDFS可以把文件分割为一个一个的片段,然后存储在各个节点上,同时为了保证高可靠性,存的是3副本。
这一切的操作对客户端都是透明的,它仍然是觉得是在对同一个文件进行操作。这样就可以把海量的Web日志文件存储到了HDFS当中。
但是存储架构已经分布式了,如果只有一个节点把所有文件读出来,然后在一台机器上处理,对于海量数据来说,依然没有什么用。
所以现在更重要的是把计算也分而治之,让计算程序也分布式。也就是我们在【大话存储】多CPU架构变迁, SMP,NUMA,MPP里面说到过的,当底层架构分布式了以后,上层的应用也需要分布式
而且要尽可能让计算靠近数据,这样的好处就是不需要大规模的交换数据,降低网络流量的开销。
过程
比如说要统计URL的访问次数,可以把计算程序分发到每个节点上,然后在节点上并行计算,首先把log按照行进行分隔,提取URL,把次数初始化为1。
然后进行分组,就是把相同的URL合并同类项,也就是Shuffle
最后累积URL的访问次数
这样程序要做的就比较简单的了
把分片中的URL提取出来,记数
累计每个URL的访问量
而且这两个步骤不需要维护中间状态,也就是只需要根据输入得到输出即可,类似于一个函数。
这样的好处在于,程序之间不互相依赖,可以把程序部署在任意的机器上去,并行处理。
还有一个问题,如果一个程序没有运行完就宕了怎么办?
可以跟踪每个程序的状态,如果发现它不可用了,就可以在另一个机器重新运行,甚至也可以多开几个程序,让他们竞争,谁先出结果就用谁的。
计算框架——MapReduce
那么完全可以搞一个计算框架来处理呢?
所谓框架就是把重复的工作都做了,让用户的程序越简单越好。那么这个框架应该包含
把程序分布在各个节点上运行
监控状态
这个框架就叫MapReduce
所谓Map指的是把一个函数施加于一组数据上,然后可以得到另一组数据。
也就是说map就是数据的变换,把一个数据变成另一个。
比如说我们先对日志按行进行分割,所以程序输入就是一行一行的日志记录。
对每一行 进行处理,提取出URL,变换成键值对的形式{URL:1},这就是map操作
而Reduce操作就是给一个函数和初始值,对列表的每个一元素都调用该函数,不断折叠列表,变成一个值。类似于合并
比如初始值为0,列表是[1,2,3,4],可以依次取出列表中的值与之前累积的值进行“+”。