mondb的特性

一、特性

    1、Aggregation有几个核心的特性:

    1)支持多种stages

    2)可以将计算结果保存在collection中,在sharding环境中仍然适用,而且在output之前可以对结果数据进行“修剪”;当然可以将结果数据保存在内存(inline)并返回cursor,便于客户端访问结果数据。

    3)同一种stage可以出现多次 ,这相对于mapreduce而言是个巨大的进步。(这种情况通常需要多个mapreduce才能完成) 

    4)stages中可以使用内置的多种计算操作、表达式,几乎可以覆盖绝大部分数据统计、分析的需求,所以用aggregation开发日常数据处理任务,是非常简单的事情。当然相对于mapreduce这种更加开放的计算模型(基于javascript语法和解析引擎),aggregation在计算复杂的数据任务时还不够灵活,但是书写mapreduce脚本也是一件复杂的事情。

 

    2、局限性

    无论如何,aggregation返回的计算结果,每条document的大小不得超过16M(mongodb中document的最大尺寸,此参数不可修改),在下文中我们会了解到$push、$addToSet等计算操作,有可能会导致此问题的发生。在一些计算方式中,可能最终结果只产出一条document,那么就更需要注意此问题。通常情况下,aggregation可以output任意多条documents,结果数据的总size是没有限制的,但是结果不能输出到sharding collection中,这与mapreduce是有区别的。

    如果你从事过大数据计算、数据统计等相关工作,应该知道每个计算任务(job或task)都会使用独立的有限大小的内存空间,mongodb没有提供复杂的内存分配模型(任务调度算法),只是简单的限定每个stage最多使用100M内存,如果超过此值将终止计算并返回error;为了支持较大数据集合的处理,我们可以指定“allowDiskUse”参数将“溢出”的数据写入本地的临时文件中(临时的collection),这个参数我们通常需要设定为true。(参见上述示例)

    

    3、优化

    aggregation操作,简单而言就是将整个collection的数据全部input到pipeline中,经过多个stages计算之后,输出少量数据的过程。由mongodb引擎的特性决定,读取整个collection数据对磁盘和内存消耗都是非常巨大的,即使是在sharding环境中;那么尽可能的减少input数据量可以有效的提升处理的效率,对于有sort操作的,就需要更加谨慎,因为排序更加消耗内存和CPU。那么提高效率的手段之一,就是尽可能的使用索引(indexes),让$match和$sort尽可能的出现在pipeline的开端,$match使用索引可以更加高效的过滤input数据集进而不需要全表扫描,$sort使用索引可以避免额外的排序(因为索引本身就是有序的),索引只会在访问原始document时有效,如果是pipeline的中间数据,比如$group之后的$sort将无法使用到索引;当然索引的建立,是依据application中数据的访问模式而定,我们通常不会根据aggregation的需要而增加索引。

 

    如果只需要对部分数据进行计算,那么可以将$match、$limit、$skip放置在pipeline的开端,那么handler只需要读取有效的、较少数量的documents;不恰当的做法,是将$limit、$skip放置在pipeline的末端,这意味着可能读取、处理更多的数据,产生更多的结果集,这意味着对性能的浪费。

 

    4、sharded collection

    上文已经提到sharding collection不支持group方法(即db.<collection>.group(),而非pipeline中的$group);但是它支持aggregation pipeline和mapreduce操作。当aggregation操作sharded collection时,pipeline将会被分成2部分:源数据过滤(filters),和后期处理(prost-processing);第一部分主要就是从collection中读取数据,或者根据索引过滤数据,位于pipeline开端的$match、$limit将会包含在内,mongos将会把aggregation操作发给特定的shards,如果$match中不包含sharding key,那么将会把操作发给所有的shards,并在每个shard上执行aggregation的第一部分的stages,此部分最大的特点就是不对数据进行计算,仅仅筛选并创建cursor;第二部分是后期处理部分,它将在primary shard上运行(概念参见【primary shard】),通常为$group、$unwind、$out、$project,其他stages也可以在第二部分,priamry合并其他shards上的cursor(迭代读取数据),读取数据并执行aggregation的第二部分的操作,然后将最终执行结果返回给mongos。(旧版中第二部分pipeline在mongos上执行);由此可见,尽可能早的过滤数据,可以有效降低primary的负载压力。我们可以在aggregate方法中指定“explain”参数,查看各个阶段执行的计划,其中cursor字段即为第一部分,其他的为第二部分,我们也能看出cursor分布在shards的情况。

 

转载于:https://www.cnblogs.com/laowang12/p/8716890.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值