Language agnostic 什么是Map/Reduce?

Language agnostic 什么是Map/Reduce?,language-agnostic,mapreduce,Language Agnostic,Mapreduce,我听说过很多关于map/reduce的事情,尤其是在谷歌大规模并行计算系统的背景下。到底是什么? 这比我能解释的更好。这有帮助吗?来自谷歌研究出版物页面的摘要: MapReduce是一种编程模型和 的关联实现 处理和生成大型数据 设置。用户指定映射函数 将密钥/值对处理为 生成一组中间值 键/值对和reduce函数 合并所有中间值的 与同一中间体有关 钥匙 MapReduce的优点是可以在多个处理节点(多台服务器)上并行执行处理,因此它是一个可以很好地扩展的系统 由于它是基于模型的,map和re

我听说过很多关于map/reduce的事情,尤其是在谷歌大规模并行计算系统的背景下。到底是什么?


这比我能解释的更好。这有帮助吗?

来自谷歌研究出版物页面的摘要:

MapReduce是一种编程模型和 的关联实现 处理和生成大型数据 设置。用户指定映射函数 将密钥/值对处理为 生成一组中间值 键/值对和reduce函数 合并所有中间值的 与同一中间体有关 钥匙

MapReduce的优点是可以在多个处理节点(多台服务器)上并行执行处理,因此它是一个可以很好地扩展的系统

由于它是基于模型的,
map
reduce
步骤都没有任何副作用(一个
map
过程的每个部分的状态和结果不依赖于另一个),因此映射和缩减的数据集可以在多个处理节点上分开

Joel的文章讨论了理解函数式编程对Google开发MapReduce的重要性,MapReduce是Google搜索引擎的动力。如果您不熟悉函数式编程以及它如何允许可伸缩代码,那么这本书将是一本非常好的读物

另见:

相关问题:

MapReduce和/或SQL:

对MapReduce的批评


映射是一个函数,它将另一个函数应用于列表中的所有项目,以生成另一个包含所有返回值的列表。(另一种说“将f应用到x”的方式是“调用f,传递x”。因此,有时说“应用”而不是“调用”听起来更好。)

这就是map可能是如何用C#编写的(它被称为
Select
,并且在标准库中):

这些Java版本需要添加泛型,但我不知道如何在Java中这样做。但是您应该能够将匿名内部类传递给它们,以提供functor:

string[] names = getLotsOfNames();

string commaSeparatedNames = (string)reduce(names, 
   new IBinaryFunctor {
       public object invoke(object arg1, object arg2)
           { return ((string)arg1) + ", " + ((string)arg2); }
   }
希望泛型可以摆脱类型转换。C#中的类型安全等价物是:

为什么这个“酷”?将较大的计算分解为较小的部分,以便以不同的方式将它们重新组合在一起的简单方法总是很酷的。谷歌应用这一思想的方式是并行化,因为map和reduce都可以在多台计算机上共享


但关键的要求不是您的语言可以将函数视为值。任何OO语言都可以做到这一点。并行化的实际要求是传递给map和reduce的小
func
函数不能使用或更新任何状态。它们必须返回一个仅依赖于传递给它们的参数的值。否则,当你试图并行运行整个过程时,结果将完全搞砸。

在对很长的华夫饼干或很短的模糊博客帖子感到非常沮丧之后,我最终发现了这一点

然后,我继续将其转换为Scala,使其更加简洁,在Scala中,我提供了一个最简单的例子,用户只需指定应用程序的
map
reduce
部分。严格地说,在Hadoop/Spark中,采用了一种更复杂的编程模型,要求用户明确指定以下4个函数:

导入scalaz.syntax.id_
特征映射模型{
类型MultiSet[T]=Iterable[T]
//`map`必须是纯函数
def映射相位[K1,K2,V1,V2](映射:((K1,V1))=>MultiSet[(K2,V2)])
(数据:多集[(K1,V1)]):多集[(K2,V2)]=
data.flatMap(地图)
def shufflepase[K2,V2](mappedData:MultiSet[(K2,V2)]):Map[K2,MultiSet[V2]]=
mappedData.groupBy(u._1).mapValues(u.map(u._2))
//“reduce”必须是幺半群
def reducePhase[K2,V2,V3](reduce:((K2,MultiSet[V2])=>MultiSet[(K2,V3)])
(shuffledData:Map[K2,MultiSet[V2]]):MultiSet[V3]=
shuffledData.flatMap(reduce).map(U2)
def mapReduce[K1,K2,V1,V2,V3](数据:多集[(K1,V1)])
(映射:((K1,V1))=>MultiSet[(K2,V2)])
(reduce:((K2,MultiSet[V2])=>MultiSet[(K2,V3)]:MultiSet[V3]=
mapPhase(地图)(数据)|>ShufflePase |>ReducePase(还原)
}
//MapReduce在Hadoop和Spark中的工作原理,除了“.par”可以确保1个元素在集群上获得进程/线程
//此外,这里的拆分不会强制执行任何类型的平衡,而且正如人们所期望的那样,完全没有必要
//它已经在HDFS上被分割了,也就是说,文件名将构成K1
//洗牌阶段也将并行化,并使用与映射阶段相同的分区。
抽象类ParMapReduce(mapParNum:Int,reduceParNum:Int)扩展了MapReduceModel{
def split[T](splitNum:Int)(数据:MultiSet[T]):Set[MultiSet[T]]
覆盖def映射阶段[K1,K2,V1,V2](映射:((K1,V1))=>MultiSet[(K2,V2)])
(数据:多集[(K1,V1)]):多集[(K2,V2)]={
val groupedByKey=data.groupBy(u._1).map(u._2)
groupedByKey.flatMap(拆分(mapParNum/groupedByKey.size+1))
平面地图(图.map)。
}
覆盖def reducePhase[K2,V2,V3](reduce:((K2,MultiSet[V2])=>MultiSet[(K2,V3)])
(shuffledData:Map[K2,MultiSet[V2]]):MultiSet[V3]=
shuffledData.map(g=>split(reduceParNum/shuffledData.size+1)(g._2.map((g._1,_)))
平局图(图:(缩小))
.plant.map(u._2).toList
}

Map是一种可以应用于数组的本机JS方法。它创建一个新数组,作为映射到原始数组中每个元素的某个函数的结果。因此,如果映射一个函数(element){return element*2;},它将返回一个新数组,每个元素都加倍。原始数组将不被修改

Reduce是一个
// represents a function that takes one arg and returns a result
public interface IFunctor
{
    object invoke(object arg);
}

public static object[] map(object[] list, IFunctor func)
{
    object[] returnValues = new object[list.length];

    for (int n = 0; n < list.length; n++)
        returnValues[n] = func.invoke(list[n]);

    return returnValues;
}
// represents a function that takes two args and returns a result
public interface IBinaryFunctor
{
    object invoke(object arg1, object arg2);
}

public static object reduce(object[] list, IBinaryFunctor func)
{
    if (list.length == 0)
        return null; // or throw something?

    if (list.length == 1)
        return list[0]; // just return the only item

    object returnValue = func.invoke(list[0], list[1]);

    for (int n = 1; n < list.length; n++)
        returnValue = func.invoke(returnValue, list[n]);

    return returnValue;
}
string[] names = getLotsOfNames();

string commaSeparatedNames = (string)reduce(names, 
   new IBinaryFunctor {
       public object invoke(object arg1, object arg2)
           { return ((string)arg1) + ", " + ((string)arg2); }
   }
string commaSeparatedNames = names.Aggregate((a, b) => a + ", " + b);
li = [5, 7, 4, 9] 
final_list = list(map(lambda x: x*x , li)) 
print(final_list)  #[25, 49, 16, 81]
#reduce func to find product/sum of list
x=(1,2,3,4)
from functools import reduce
reduce(lambda a,b:a*b ,x) #24