【问题标题】:Zend Framework 2 Doctrine MongoDB ODM and Apache too slowZend Framework 2 Doctrine MongoDB ODM 和 Apache 太慢了
【发布时间】:2015-01-08 06:51:18
【问题描述】:

我们在运行时遇到了奇怪的性能问题:

我们确定这不是数据库问题(用真正的 MongoDB 实例尝试过,结果仍然相同)。


场景

我们已经定义了与 Doctrine ODM 类似的对象:

<?php

namespace CatalogueManager\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Doctrine\Common\Collections\ArrayCollection;

/*
 * @ODM\Document(repositoryClass="CatalogueManager\Repository\ProductRepository")
 */
class Item
{
    /** @ODM\Id */
    protected $id;

    /** @ODM\String */
    protected $name;

    /** @ODM\Timestamp */
    protected $created;

    /** @ODM\Timestamp */
    protected $updated;

    // ---------------------------------------------------------------------- //

    /**
     * Return properties as an array. Helper method to assist with converting
     * doctrine objects to arrays so we can return front-end api calls as json.
     *
     * Required as currently Doctrine ODM do not support array hydration of
     * referenced documents.
     *
     * @access public
     * @return array
     *
     */
    public function toArray()
    {
        $arr = ['id'          => $this->id,
                'name'        => $this->name,
                'urlSlug'     => $this->urlSlug,
                'desc'        => $this->desc,
                'metaData'    => $this->metadata,
                'category'    => $this->category,
                'brand'       => $this->brand,
                'assets'      => $this->assets,
                'shipping'    => $this->shipping,
                'specs'       => $this->specs,
                'attrs'       => $this->attrs,
                'optionTypes' => $this->optionTypes
                ];

        return $arr;
    }

    // ---------------------------------------------------------------------- //

    /**
     * Getter
     *
     * @access public
     * @return string
     *
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Getter
     *
     * @access public
     * @return string
     *
     */
    public function getName()
    {
        return $this->name;
    }

    // ---------------------------------------------------------------------- //

    /**
     * Setter
     *
     * @param string $value Property value
     *
     * @access public
     * @return void
     *
     */
    public function setName($value)
    {
        $this->name = $value;
    }

}

我们使用这些来导入大约。 100 个产品进入产品数据库。这一切在真机上大约需要 5 秒,但在 虚拟机 上尝试时,大约需要 5 秒。 25 秒 做同样的事情。

看起来问题可能出在 Apache,它在处理这一切时占用了 99% 的负载,但我很难确定到底发生了什么。

任何建议都将不胜感激......


更新

这似乎只在写入数据时发生。读取数据好像没问题。

Webgrind 数据(截图)可用:https://www.dropbox.com/s/jjlg7ano6epy6t1/webgrind.png?dl=0

【问题讨论】:

    标签: php doctrine-orm zend-framework2 virtualbox doctrine-mongodb


    【解决方案1】:

    所以这不是一个答案,我会寻求建议。在本地机器上运行速度较慢是正常的,更不用说在虚拟机器上。

    可能有帮助的事情:

    1. 您可以通过将其添加到您的 vagrant 文件中来使您的虚拟机拥有更多内存

    config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", "1024"] end

    1. 还可以使用 zf2 模块 ZendDeveloperTools,它会显示您的请求、轮询、数据库查询(它适用于原则)和不占用的时间。您还可以查明运行缓慢的原因。

    只是一个旁注。你为什么在 12.04 上运行 php 5.5,为什么不是 14.04(它更可靠,但不那么精确)。设置起来更容易。

    【讨论】:

    • 感谢您的建议 :) VM 已经分配了 4GB 内存和 2 个处理器,我们确实使用了 ZDT,但在任何调试信息中都没有任何可见的信息可以告诉我们什么需要这么长时间。我也手动将每个步骤回显到浏览器,基本上只需要比在 VM 之外执行更多的时间来写入数据库。这是使用 VM 的本机文件系统,到目前为止,它本身对我们来说已经非常快了。唯一的问题是这个 Mongo 的东西,所以我在这里问:P 我们从 12.04 开始并使用 Puppet 来启动我们的开发实例,这就是原因
    【解决方案2】:

    在查看了一些 XDebug 数据的屏幕截图后,我认为您只是以错误的方式使用 ORM/ODM,因为您正在批处理 > 13K 结果。

    这种操作的正确解决方案在http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html进行了解释

    发生的事情很简单: - ODM 从数据库中加载一条记录 - ODM 将记录存储到UnitOfWork - 在刷新时,ODM 会遍历 UnitOfWork 中的所有条目,寻找更改的文档/实体

    如果您继续在UnitOfWork 中存储更多数据,那么显然每次重复操作都会花费更长的时间。

    您应该在正在处理的批处理块之间调用ObjectManager#clear()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多