基于 MongoDB 分布式存储进行 MapReduce 并行查询

21 篇文章 0 订阅
6 篇文章 0 订阅

转自:http://www.cnblogs.com/daizhj/archive/2010/09/09/1822264.html

 

之前的文章中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询。虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询。
有关MongoDb的MapReduce之前我写过一篇文章 Mongodb Mapreduce 初窥,

今天介绍如何基于sharding机制进行mapreduce查询。在MongoDB的官方文档中,这么一句话:

Sharded Environments
In sharded environments, data processing of map/reduce operations runs in parallel on all shards.

即: map/reduce操作会并行运行在所有的shards上。
下面我们就用之前这篇文章中白搭建的环境来构造mapreduce查询:

首先要说的是,基于sharding的mapreduce与非sharding的数据在返回结构上有一些区别,我目前注意到的主要是不支持定制式的json格式的返回数据,也就是下面方式可能会出现问题:

return { count : total };

注意:上面的情况目前出现在了我的测试环境下,如下图:

http://daizhj.cnblogs.com/images/cnblogs_com/daizhj/mongodb_sharding_mapreduce4.gif

就需要改成 return count;

下面是测试代码,首先是按帖子id来查询相应数量(基于分组查询实例方式):

 

  1. public partial class getfile : System.Web.UI.Page   
  2. {   
  3.   
  4. public Mongo Mongo { getset; }   
  5.   
  6. public IMongoDatabase DB   
  7. {   
  8. get  
  9. {   
  10. return this.Mongo["dnt_mongodb"];   
  11. }   
  12. }   
  13.   
  14. ///   
  15. /// Sets up the test environment. You can either override this OnInit to add custom initialization.   
  16. ///   
  17. public virtual void Init()   
  18. {   
  19. string ConnectionString = "Server=10.0.4.85:27017;ConnectTimeout=30000;ConnectionLifetime=300000;MinimumPoolSize=512;MaximumPoolSize=51200;Pooled=true";   
  20. if (String.IsNullOrEmpty(ConnectionString))   
  21. throw new ArgumentNullException("Connection string not found.");   
  22. this.Mongo = new Mongo(ConnectionString);   
  23. this.Mongo.Connect();   
  24. }   
  25. string mapfunction = "function(){/n" +   
  26. " if(this._id=='548111') { emit(this._id, 1); } /n" +   
  27. "};";   
  28.   
  29. string reducefunction = "function(key, current ){" +   
  30. " var count = 0;" +   
  31. " for(var i in current) {" +   
  32. " count+=current[i];" +   
  33. " }" +   
  34. " return count ;/n" +   
  35. "};";   
  36.   
  37. protected void Page_Load(object sender, EventArgs e)   
  38. {   
  39. Init();   
  40.   
  41. var mrb = DB["posts1"].MapReduce();//attach_gfstream.files   
  42. int groupCount = 0;   
  43. using (var mr = mrb.Map(mapfunction).Reduce(reducefunction))   
  44. {   
  45. foreach (Document doc in mr.Documents)   
  46. {   
  47. groupCount = int.Parse(doc["value"].ToString());   
  48. }   
  49. }   
  50. this.Mongo.Disconnect();   
  51. }   
  52. }  

下面是运行时的查询结果,如下:

http://daizhj.cnblogs.com/images/cnblogs_com/daizhj/mongodb_sharding_mapreduce1.gif

接着演示一下如何把查询到的帖子信息返回并装入list集合,这里只查询ID为548110和548111两个帖子:

 

  1. string mapfunction = "function(){/n" +   
  2. " if(this._id=='548110'|| this._id=='548111') { emit(this, 1); } /n" +   
  3. "};";   
  4.   
  5. string reducefunction = "function(doc, current ){" +   
  6. " return doc;/n" +   
  7. "};";   
  8.   
  9. protected void Page_Load(object sender, EventArgs e)   
  10. {   
  11. Init();   
  12.   
  13. var mrb = DB["posts1"].MapReduce();//attach_gfstream.files   
  14. List postDoc = new List();   
  15. using (var mr = mrb.Map(mapfunction).Reduce(reducefunction))   
  16. {   
  17. foreach (Document doc in mr.Documents)   
  18. {   
  19. postDoc.Add((Document)doc["value"]);   
  20. }   
  21. }   
  22. this.Mongo.Disconnect();   
  23. }  

下面是运行时的查询结果,如下:

http://daizhj.cnblogs.com/images/cnblogs_com/daizhj/mongodb_sharding_mapreduce3.gif

上面的map/reduce方法还有许多写法,如果大家感兴趣可以看一下如下这些链接:

http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

http://www.mongodb.org/display/DOCS/MapReduce

以及之前我写的这篇文章:http://www.cnblogs.com/daizhj/archive/2010/06/10/1755761.html

当然在mongos进行map/reduce运算时,会生成一些临时文件,如下图:
http://daizhj.cnblogs.com/images/cnblogs_com/daizhj/mongodb_sharding_mapreduce2.gif

我猜这些临时文件可能会对再次查询系统时的性能有一些提升(但目前未观察到)。

当然对于mongodb的gridfs系统(可使用它搭建分布式文件存储系统,我之前在这篇文章中已介绍过,我也做了测试,但遗憾的是并未成功,它经常会报一些错误,比如:

Thu Sep 09 12:09:29 Assertion failure _grab client/parallel.cpp 461

看来mapreduce程序链接到mongodb上时,会产生一些问题,但不知道是不是其自身稳定性的原因,还是我的机器环境设置问题(内存或配置的64位系统mongos与32位的client连接问题)。

好了,今天的文章就先到这里了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值