映射-归并算法

20.4 映射-归并算法和磁盘索引程序

现在我们要从理论转向实践。首先,我们要来看看高阶函数mapreduce,然后我们会在一个简单的索引引擎中使用这种技术。在这里,我们的目标并不是要做一个世上最快最好的索引引擎,而是要通过这一技术来解决相关应用场景下真实面对的设计问题。

20.4.1 映射-归并算法

在图20-2中,向我们展示了映射-归并(map-reduce)算法的基本思想。开启一定数量的映射进程,让它们负责产生一系列的{Key, Value}这样的键-值对。映射进程把这些键-值对发送给一个归并进程,它负责合并这些键-值对,合并的方式就是把有相同键的值组合起来。

警告

这里提到的map这个词,尤其是在mapreduce的上下文中,与本书其他部分中提到的map函数全然不同,切忌混淆。

mapreduce(映射-归并算法)是由Google公司的Jeffrey Dean和Sanjay Ghemawat提出的高阶并行函数,据说Google的集群中每天都要大量使用这个算法。

图20-2 映射-归并算法

我们可以用多种不同的方式来实现多种不同语意的映射-归并算法。这个算法与其说是一个特定的算法,还不如说是一个算法族。

mapreduce是这么定义的:

F1(Pid, X)是映射函数。F1的任务是发送一组{Key, Value}数据给Pid,然后退出。mapreduce每次会给列表中的每个X创建一个新的进程。

F2(Key, [Value], Acc0) -> Acc是归并函数。当所有的映射函数都退出的时候,归并函数要负责针对每一个键,将它对应的所有的值合并到一起。此时,它会对每一个它收集到的{Key, [Value]}调用F2(Key, [Value], Acc)函数。Acc是一个累加器,它的初始值是Acc0。F2会返回一个新的累加器(另外一种描述方式是这样,F2在所有它收集到的{Key, [Value]}对上执行一个折叠操作)。

Acc0是累加器的初始值,当调用F2时会被使用。

L是一个X的列表。F1(Pid, X)会对列表L中的每一个X进行运算,Pid是由mapreduce创建的归并进程的进程标识符。

mapreduce定义在phofs(parallel higher-order function的缩写)模块中:

进一步深入之前,先来对这个mapreduce函数做一下测试,这样我们能更加理解它的工作机制。

我们要写一个小程序,以统计这本书所附的代码中所有单词的出现频率,代码是这样的:

运行的时候,代码目录里有102个Erlang模块,因此mapreduce也就创建了102个并发进程,它们每一个都向归并进程发送由键值对组成的数据流。这在100个核心处理上应该运行得很好(如果硬盘跟得上的话)。

现在我们已经明白mapreduce是怎么回事了,可以回到索引引擎了。

时间: 2024-09-25 05:30:35

映射-归并算法的相关文章

C++归并算法实例_C 语言

本文实例讲述了C++归并算法.分享给大家供大家参考.具体如下: /* 归并算法:把两个或两个以上的线性表合并在一起,形成一个新的线性表 函数模版的基本使用 程序意图:将两个相同类型的线性表元素排好序,然后将他们组合成一个排好的线性表 */ #include <iostream> using namespace std; const int n = 5; //5个元素 //输出数据元素 template <class T1> void OutPut(T1 out[(2*n)]) {

线性表-归并算法

/*例如:有两个线性表LA=(1,5,7,15) LB=(3,6,8,9,13,15,17) 则: LC=(1,3,6,8,9,13,15,15,17) 上述问题要求可知,LC中的数据元素或是LA中的数据元素,或是LB中的数据元素,则首先设LC为空表,然后将LA或LBs中的元素逐个插入到LC当中. 为使LC中元素按值非递减排列,可设两个指针i,j分别向LA和LB中的某个元素,若设i当所指的元素为a,j所指的元素为b则当前应插LC元素c为 |-> b a>b c=|-> a a=b |-&

常见的五类排序算法图解和实现(归并类:二路归并排序)

归并类的排序算法 归并:将两个或两个以上的有序表组合成一个新的有序表. 内部排序中,通常采用的是 2-路归并排序.即:将两个位置相邻的记录有序子序列归并为一个记录有序的序列.归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 图解如下 看成是 n 个有序的子序列(长度为 1),然后两两归并. 得到 n/2 个长度为2 或 1 的有序子序列.继续亮亮归并 最后一趟 代码如下: 1 //二路一次归并过程的算法 2 //lo

各种排序算法汇总

目录 简介 交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 总结 简介 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的过程

(算法导论习题解problem2.4)寻找一个序列中逆序对的数量

一个序列的逆序对是这样的两个元素, 对于序列A而言, i>j且A[i]<A[j], 于是A[i]和A[j]就形成一个逆序对. 研究一个序列中逆序对的数量是有实际意义的, 对于插入排序而言, 它排序的时间与待排序序列的逆序对数量成正比. 下面给出求出一个序列中逆序对数量的算法,类似于归并排序中使用的分治算法:一个序列的逆序对数量为它的左半部分逆序对的数量,加上右半部分逆序对的数量, 最后在合并的时候左半部分元素大于右半部分元素的数量.这几乎和归并算法的过程一模一样,只是在归并的时候加入了计数的操

经典算法(5) 归并排序的实现

归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一 个非常典型的应用. 首先考虑下如何将将二个有序数列合并.这个非常简单,只要从比较二个数列的 第一个数,谁小就先取谁,取了后就在对应数列中删除这个数.然后再进行比较,如果有数列为空,那直接 将另一个数列的数据依次取出即可. //将有序数组a[]和b[]合并到c[]中 void MemeryArray(int a[], int n, int b[], int m, int c[]) { i

Javascript和HTML5利用canvas构建Web五子棋游戏实现算法

这只是一个简单的JAVAscript和HTML5小程序,没有实现人机对战. 五子棋棋盘落子点对应的二维数组.数组的元素对应落子点.比如数组元素值为0表示该元素对应的落子点没有棋子,数组元素值为1表示该元素对应的落子点有白棋子,数组元素值为2表示该元素对应的落子点有黑棋子: 判断五子棋赢棋的算法是通过对五子棋棋盘落子点对应的二维数组的操作来实现的. 判断五子棋赢棋算法 下边的函数可以实现判断五子棋赢棋的算法,也可以按照教材中相应的算法实现. 其中函数的参数xx.yy为数组下标,chess数组实现五

归并排序算法

归并排序(Merge sort)是创建在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 一个归并排序的例子:对一个随机点的链表进行排序 本文地址:http://www.cnblogs.com/archimedes/p/merge-sort-algorithm.html,转载请注明源地址. 算法描述 归并操作的过程如下: 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 设定两个指针,最初位置分别为两个已经排序序

各种排序算法汇总(转)

  目录 简介 交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 总结 简介 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的