在Laravel 6.x中提取3M+记录时,我正在使用cursor()
方法降低内存。
我有一个运行以下代码的artisan命令:
Product::cursor()->each(function ($product) {
calculateStats::dispatch($product);
});
根据文档,这应该会导致内存使用率较低,但内存一直在攀升,直到达到我的2G限制。
我读到这可能是因为PDO连接使用了缓冲查询,所以我试图在运行查询之前添加这个:
DB::connection()->getPdo()->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
从这里:https://github.com/laravel/framework/issues/14919
这导致启动内存使用率降低,但结果仍然相同。我还尝试将它添加到database.php
配置文件中,但结果相同。
如果有什么不同的话,我使用的是MySQL 8。
我使用dispatch()
方法将其分发给工人,因为一次处理一个工人需要很长时间。
关于如何解决记忆力问题,有什么好的建议吗?
编辑
经过一些额外的调试,我觉得是作业调度占用了内存。作业已经发送到Redis队列,如何从内存中释放?
FIY:设置使用Redis和Horizon。
在我的案例中,Laravel的Telescope
插件保留了对调度作业的引用,在运行10000多个作业时导致了非常明显的内存泄漏。
相反,"记住您停止的地方":http://mysql.rjweb.org/doc.php/pagination
对不起,我怀疑这是否可以直接用拉拉威尔表达;您可能必须进入SQL才能完成此任务。考虑为Laravel提交功能请求。