填充FosElasticaBundle耗尽php内存,可能是内存泄漏?

时间:2014-06-27 12:34:36

标签: php symfony memory-leaks elasticsearch foselasticabundle

我已经安装了FOSElasticaBundle并让它处理我的数据的横截面。

我的问题出现了,我需要使用大约14m行来构建索引。我运行了populate命令,在昨天大约6个小时后,它出现了10.8%的错误并出现内存错误:

PHP Fatal error:  Allowed memory size of 2147483648 bytes exhausted (tried to allocate 52277 bytes) in /var/www/html/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php on line 111

正如您所看到的,我已将我的php内存限制设置为2G,这应该是相当多的。

错误前的最后一行看起来像

Populating index/entity, 10.8% (1315300/12186320), 36 objects/s (RAM : current=2045Mo peak=2047Mo)

每条线的电流和峰值都在上升,大约30mb。

我的假设是存在某种内存泄漏?当然,php的记忆不应该被这个过程所累。我还尝试了一些额外参数的命令

app/console fos:elastica:populate --no-debug --no-reset --env=prod

但是当我看着它正在运行时,当前的内存仍然在增加。

对这里可能发生的事情以及我可以做些什么来调试它的想法?我发现这个讨论听起来像我的问题,但并没有真正提供一个好的解决方案:https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/82。我使用的是doctrine和默认提供程序。

谢谢 -

3 个答案:

答案 0 :(得分:6)

我无法完全解决内存泄漏,而是通过运行命令

app/console fos:elastica:populate --no-debug --no-reset --env=prod --offset=n

我已经能够分批填充。我使用此页面上的解决方案,通过关闭记录器来大幅减少内存泄漏量

https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/273

将我的php memory_limit设置为4G(!)我能够在没有错误的情况下填充超过500万条记录,因此在完成几个批次之后,我应该完成此过程。

大多数解决方案似乎都涉及编写自定义提供程序(请参阅https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/457),但通过一个荒谬的memory_limit并尽可能地限制内存泄漏,我并不需要。

答案 1 :(得分:1)

这里的主要问题是一切都在一个进程中完成,所有实体都必须加载到内存中。它由块完成,但仍然会加载所有数据。你可以做很多事情来解决设计中的问题。

解决方案:数据可以拆分为块,这些块在不同的进程中并行处理。工作进程可能会不时退出(它们必须由Supervisord或类似工具重新启动)释放内存和资源。因此,您将获得更好的性能和更好的容错能力以及更少的内存占用。

有很多方法可以实现这一点(使用forks,pthreads或消息队列),但我个人建议查看enqueue/elastica-bundle。它通过拆分作业和发送消息来改进populate命令。

答案 2 :(得分:0)

如果--no-debug选项不够用,您可能要检查是否有fingers_crossed处理程序并设置buffer_size

monolog:
    handlers:
        main:
            type: fingers_crossed
            action_level: critical
            handler: grouped
            excluded_404s:
                - ^
            buffer_size: 30