提高MongoDB聚合管道性能

时间:2017-02-01 17:44:24

标签: php linux mongodb performance aggregation-framework

我正在使用MongoDB聚合管道来生成报告。以下是一些快速键信息:

Machine: 8-Core-CPU, 16 GB RAM
OS: Ubuntu 16.04.1 LTS

MongoDB Version: 3.2.11
Mongo PHP Adapter: 1.6.14
PHP Version: 5.6.30

Amount of documents to aggregate: ~ 10+ million

我的聚合管道代码 - 我在PHP中编写和执行 - 看起来像这样:

// create indexes (ASC and DESC for each aggregation key)
$mongoCollection->createIndex('foo' => 1);
$mongoCollection->createIndex('foo' => -1);
$mongoCollection->createIndex('bar' => 1);
$mongoCollection->createIndex('bar' => -1);

// prepare aggregation (1. group, 2. sort)
$aggregationPipeline = [
    [
        '$group' => [
            '_id' => [
                '$foo' => 'foo',
                '$bar' => 'bar
            ],
            'count' => [
                '$sum' => 1
            ]
        ]
    ],
    [
        '$sort' => [
            'count' => -1
        ]
    ]
];


// run aggregation
$mongoCollection->aggregate($aggregationPipeline);

问题是:聚合速度不够快!根据我聚合的字段数量(在我的示例中只有2个),该过程大约需要90秒,通常更长。

我的目标是: 提高聚合的性能!

我的问题

  1. PHP

    • 如上所述,我使用PHP来控制和运行我的聚合。
    • =>使用PHP-Mongo-Classes和-Methods从PHP运行聚合是不好的做法吗?
    • =>升级到PHP 7.x会提高Mongo聚合性能吗?
  2. 索引

    • 我有主观感觉,添加DESC和ASC索引(参见示例代码)并不能提高性能。无论是否添加索引,运行时似乎都几乎相同。
    • =>是否有可能添加索引不会显着提高性能?
  3. CPU-芯

    • 聚合运行时,我可以观察到,只使用了CPU的一个核心。
    • =>如何管理/实现聚合管道同时使用所有CPU-CORES?
  4. 拆分

    • 我读到了MongoDB分片,这可能是提高Mongo整体性能的另一种可行方法。
    • =>是否有可能并且在SINGLE机器上设置/配置分片是否有意义?
  5. 非常感谢您提出任何意见,建议,批评和问题!

1 个答案:

答案 0 :(得分:2)

  1. PHP
  2. 毫无头绪,但我认为它在这里起着非常小的作用。 foo和bar的基数 - 聚合返回的文档/字节数也可能会产生影响。

    1. 索引
    2. 首先,对于单个字段同时具有升序和降序索引是没有意义的。其次,索引可用于$match聚合管道,但在进行o $group操作时无用。所以你的想法是正确的,索引可以帮助你。你正在进行全面扫描。

      1. CPU-芯
      2. 您无法并行运行聚合操作。您可以通过从外部控制聚合来实现技术,通过将其分解为子任务。但是,既然你正在进行全面扫描 - 再次 - 你的情况并不好。

        1. 拆分
        2. 在同一台计算机上拥有多个分片并通过相同的硬件进行竞争毫无意义。您可以通过使用更多硬件来添加分片。

          这里的资源非常有限16 GB RAM和100 M文档。这可能还不够,特别是如果您的文档不是很小并且您必须转到磁盘才能处理更多文档。我会检查聚合期间的IO利用率,以及WiredTiger缓存的行为(假设您使用的是WiredTiger)。

          总之,它可能是您有限的资源。客户/驱动程序对慢度的影响可能很小。首先运行并explain()到聚合,同时观察RAM,磁盘的运行情况。