【发布时间】:2017-07-11 15:07:10
【问题描述】:
说明
我目前有一组队列用于上传和处理大量数据。这种设置非常繁琐,因为我必须检查记录是否已经存在,并且由于我要在 10k 记录的远端上传,所以我必须减少每个队列必须处理的记录数量。
我已经设置了一个队列来处理数据并将其分成 500 条记录的位,然后我将这些块传递到它自己的单独队列中,该队列检查每条记录是否存在,然后继续将其上传到数据库.
我已经设置了一个监听器来检查这个确切的过程需要多长时间,这就是问题发生的地方。
在我的 CLI 中运行 php artisan queue:listen --memory=1024 --timeout=100 可以让前几个队列花费大约 5-10 秒。然后它们会随着时间呈指数增长。
This batch took: 29.013844013214 Seconds to process
This batch took: 28.680887937546 Seconds to process
This batch took: 28.172641992569 Seconds to process
This batch took: 27.722810983658 Seconds to process
This batch took: 20.302350997925 Seconds to process
This batch took: 16.653347969055 Seconds to process
This batch took: 16.353777885437 Seconds to process
This batch took: 15.923125982285 Seconds to process
This batch took: 15.426895856857 Seconds to process
This batch took: 15.151268005371 Seconds to process
这可以持续到 100 多秒,然后再次随机重置到 5-10 秒。
这是我用来处理记录的代码。
foreach ($data as $record) {
$batch_id = $record['batch_id'];
unset($record['batch_id']);
if (is_null(Record::where($record)->first())) {
$record['batch_id'] = $batch_id;
$upload[] = $record;
} else {
$duplicatechunks++;
}
}
if (!empty($upload)) {
DB::table('records')->insert($upload);
}
此代码删除值Batch_id,因为它是唯一的,因此我不能在搜索现有记录时使用它。该代码还跟踪$duplicatechunks 值,这只是了解该记录之前是否已上传的一种方式。 $duplicatechunks 被上传到 $batch 我也在这个队列中跟踪。代码开头是从$duplicatechunks = $batch->chunks_duplicate设置的,然后在数据库插入下面是$batch->chunks_duplicate = $duplicatechunks保存。
到目前为止我已经尝试过什么
- 我尝试为处理插入记录的进程提供更多处理能力,但这只能持续一分钟左右。
- 我还尝试编辑代码,从单独上传每条记录到批量上传。这将每个队列的一般时间从 19 秒缩短到 5 秒。
重要
- 队列处理程序是数据库,使用内置的 laravel 作业表
有人遇到过类似的排队问题吗?
编辑:
由于这些记录在 InsertRecords 作业执行并将它们存储在数据库中之前不会保存在任何地方,这会对这些记录的执行时间产生任何影响吗?将所有记录暂时存储在不同的表中,然后再将它们迁移到实际的表中会更明智吗?
【问题讨论】: