5

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

我的问题出现在我需要用来构建索引的大约 14m 行。我运行了填充命令,昨天大约 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 。我正在使用学说和默认提供程序。

谢谢-

4

3 回答 3

7

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

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

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

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

将我的 php memory_limit 设置为 4G(!)我能够获得超过 5m 条记录而不会出现错误,因此经过几批我应该完成这个过程。

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

于 2014-06-30T18:57:31.993 回答
1

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

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

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

于 2017-06-27T08:10:40.063 回答
0

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

monolog:
    handlers:
        main:
            type: fingers_crossed
            action_level: critical
            handler: grouped
            excluded_404s:
                - ^
            buffer_size: 30
于 2019-09-09T14:19:57.720 回答