MongoDB Mapreduce剖析

最近在使用LSI进行海量去重时发现效率及其低下,所以采用了mongodb内置的mapreduce来提升海量数据筛选的速度和性能。本文主要稍微整理了下mapReduce的基本原理以及方法调用逻辑。

Part 1: 业务背景

对海量数据进行一一比较,这个过程中需要不断地从数据库中读取数据,然后再进行一一比较。然而对于海量数据而言,这个数据的读取时间是不可小觑的。那么如果快速地降低这个时间呢?那么就可以直接使用mongodb内部地mapreduce来提升效率。

Part 2: MapReduce原理

MapReduce简单来说是一个分布式的并行计算框架,通过map函数将海量数据筛选出来符合条件的记录,再通过reduce函数将map函数筛选下来的记录进行一一处理,得到的最后结果就是mapReduce的结果。

举个例子,假设有如下记录:

{id:1,name:"A",score:0.1}
{id:2,name:"B",score:0.2}
{id:2,name:"C",score:0.3}
{id:2,name:"D",score:0.3}

现在需要计算每个分数的个数:

{id:1,name:"A",score:0.1,related:1}
{id:2,name:"B",score:0.2,related:2}
{id:3,name:"C",score:0.3,related:2}
{id:4,name:"D",score:0.3,related:2}

那么map方法则是筛选出来上述这些记录(这里没有过滤条件):

emit(0.1,1)
emit(0.2,2)
emit(0.3,3)
emit(0.3,4)

reduce则表达如下:

reduce(0.1,[1])
reduce(0.2,[2])
reduce(0.3,[3,4])

在reduce中,我们进行累加即可得到最终的结果。

MapReduce是一种编程模型,主要应用于大规模数据集的并行运算。其将并行计算简化为Map和reduce过程,极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。

Part 3: Mongodb对mapReduce的支持

mongodb内置了mapReduce方法,可以动态地执行一段mapReduce方法来实现并行计算,从而快速地提升计算效率。

db.collection_name.mapReduce(
    #第一个参数:map()方法
    function() {
        #调用emit方法,将记录转化为k,v的形式传递给reduce
        emit(key,value) 
    },
    #第二个参数: reduce方法, key和value来自map()方法
    function(key,values) {
        return sum(key)  
    }
    #第三个参数,可选,筛选条件,query
    {
        "query":{
            xxx:xxx  #普通的查询过滤条件
        }
    },
    #第四个条件,可选,输出集合,会将结果写入到指定的集合中
    {
        out: "out_collection_name"
    }
)

Part 4: 使用心得

  • 对于MapReduce的使用,要注意map函数和reduce函数的设计,设计不好会使得性能也不好。
  • 最好使用MongoDB的集群分片来提高并行计算效率。
赞赏我吗