mongodb的mapreduce

在功能点统计中,我是用mongodb所提供的mapreduce功能所实现的。关于mongodb,其实并没有多少可说的。简单的概述一下,它其实不过是一个可以存放很多json的仓库,只不过它对于json做了优化,使用二进制存储,改了个名叫做bson,这不过是很多年前就有的面向对象数据库的新的实现。至于性能,也可以简单的认为它自带了一个缓存,与硬盘做异步同步。这些其实都是很无趣的东西,真正有意思的,是它带了一个mapreduce工具(虽说,实现的真的很烂)。

 

 

mapreduce在我看来,是在互联网时代,一个程序员必须去了解的概念。在中文维基中,mapreduce被这样定义:“MapReduce是Google提出的一个软件架构,用于大规模数据集(大于1TB)的并行运算”。其实,这不准确,它其实是函数式语言中由来已久的一个概念。只不过,在这个互联网上信息爆炸的年代,google帮我们发现了它。

 

 

顾名思义,mapreduce分两部分,map和reduce。

map函数的定义为Map(k1,v1) → list(k2,v2)

reduce函数的定义Reduce(k2, list(v2)) → list(v3)

简单的描述一下,map接收一个list,通过某一个函数,把它变成另一个list。在这个过程中,对list中任一元素的变换都与其他操作无关。这样的函数天生具备了并行计算的能力。而reduce,它通过某种操作,具体来说也是通过一个函数,把接收到的list转变为一个简单的结果。reduce函数不是那么方便并行,所以通常mapreduce框架会把reduce操作集中到某个特定的节点进行。

 

 

看一下功能点统计中一段具体的mapreduce函数

var map =function () {

   var a = new Date,

       d = new Date(a.getFullYear(), a.getMonth(), a.getDate()),

       e = this.auid;

   this.features.forEach(function (b) {

       var a = b.log.length,

           c = 0;

       b.log.forEach(function (a) {

           a > d && c++

       });

       emit({

           auid: e,

           fid: b.id,

           fname: b.name,

           version: b.version

       }, {

           total: a,

           today: c

       })

   })

}

在这段函数中,前面具体的逻辑操作不重要,重要的是后面的emit函数。这个函数由mongodb提供,在这个例子中,它将原始数据进行分割,分割结果是这样的结构

[{_id:{auid:xxx,fid:xxx,fname:xxx,version:xxx},value:[{total:xx,today:xxx}....]}]

换句话说,emit的作用就是根据第一个参数提供的属性,将原始数据分割为一个新的list

这里是reduce函数

var reduce = function (d, c) {

   var a = {

       total: 0,

       today: 0

   };

   c.forEach(function (b) {

       a.total += b.total;

       a.today += b.today

   });

   return a

}

这个函数看起来就简单很多了,它要做的就是,接收上一个list中某个元素的value的值,这是一个小的list,把它变成一个对象输出。

从逻辑上可以看到,这个reduce对之前那个list的每个元素要执行一次,这个调度工作由mongodb执行。最终,这些输出结果合并到一起,变成新的list,成为我们的最终结果。

之前提到,我对mongodb的mapreduce其实非常不满。原因很多,首先它不能利用index,导致性能不高;其次,它对mapreduce所用到的数据有诸多限制;最重要的一点,其实是它根本没有很好的实现并行:在单机环境下,mongodb的mapreduce只能单线程运行,在分布式环境下有限制了很多有用的特性。这样看来,mongodb的mapreduce事实上只是起到了一个简单的group by作用,而不是一个真正最强有力的并行计算工具。在这里,我的观点是研究mapreduce的思想,远比研究mongodb的这个实现有价值的多。

 

 

附几篇参考资料:

http://www.blogjava.net/emu/archive/2006/08/08/62318.html

http://blog.csdn.net/sithlqf/archive/2009/09/06/4523886.aspx

http://erlang-china.org/study/yet-another-pf-guide.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值