有关导入大量数据的性能提示

时间:2015-04-27 00:48:58

标签: php mysql json laravel amazon-sqs

我有一个允许用户导入联系人(电子邮件地址和姓名)的功能。一些用户导入大约70,000个联系人的文件。可以是xls或csv。这就是我现在所拥有的。

  1. 用户从他们的计算机中选择要从中导入联系人的文件。
  2. 我将文件保存在服务器上,并创建一个带有文件位置引用的数据库条目。
  3. Amazon SQS用于在后台处理此问题。
  4. 作业第一次运行时我处理文件,只保存带有电子邮件地址和名称的行(如果找到)。数据将保存到同一位置的json文件中并进行缓存。然后我将这份工作放回队列中。
  5. 现在可以导入联系人了。我在每个作业中接受1000个联系人,并将每个联系人保存在数据库中自己的行中。我使用array_slice跳过json文件中的联系人。跳过计数将保存到数据库中。
  6. 当没有留下任何联系人时,该作业将被删除,一切都已完成。
  7. 这几乎就是整个过程。我还有一个检查(数据库查找)来检查重复项。只允许使用唯一的电子邮件地址。

    我遇到的问题是这项工作似乎需要花费太多时间才能实现超时。这导致进口需要很长时间。

    所以我的问题是:我能做得更好吗?

    如果您还有其他需要,请告诉我。我对大数据和许多用户没有多少经验。

    编辑:我不需要代码。我所追求的是,​​问题是服务器问题?也许将数据库移动到自己的服务器就可以了?或者我应该使用不同的方法?

    编辑2:用户可以看到导入的进度。所以我需要计算联系人的数量,为此我需要首先过滤掉没有电子邮件地址的行。我还修剪它和名称列。当我这样做时,我发现更容易将新的数据集保存到JSON文件中。

    编辑3:将用户保存到数据库时发生超时,而不是在初始处理和创建json文件时发生。

    编辑4 :加快工作速度的一种方法可能是从一开始就将其保存到块中(在第一次处理中)。这样我就不需要处理跳过计数器了,我不必在大数据集上使用array_slice。现在,当我考虑它时,将它保存到json文件然后缓存它是多么愚蠢。为什么不从头开始缓存数组?

2 个答案:

答案 0 :(得分:2)

  

我在每个作业中接受1000个联系人,并将每个联系人保存在自己的行中   在数据库中。

我之前也遇到过这个问题,但在我的问题中,我需要导入员工状态大约50000条记录,我已经使用并行化解决了问题。您可能也会注意到它,因此您可以在每个作业队列中接收1000个联系人。真正的问题是"处理超时" 如果我们这么做的话,我们会面对吗?

因此,我的解决方案是创建更多子进程来完成工作。如果我创建一个作业来进行1000次导入,它将使用更多的时间和更慢的时间。所以,我用e ach job import 100 records 创建100个职位队列 e。我一起运行它。在这种方法中,你的CPU负载会因此而增加。如果你是高规格的计算机,这不是问题。

我的建议是:

  1. 创建更多作业队列以进行导入。
  2. 避免使用太多循环。
  3. 如果可能,请将您的数据存储在memcached中,因为它可以加快您的流程。我想你也是这么想的。阅读APC
  4. 您可以阅读here如何将数据存储在内存中。希望这对你有所帮助:))

答案 1 :(得分:0)

您的php程序是否在等待此任务完成?那不行。它会超时。你已经注意到了。

您需要以这样的方式组织您的操作:php程序在AWS SQS上启动作业,然后告诉您的用户作业正在运行并且将在一段时间后完成。设定较低的用户期望(“在15分钟内完成”)然后超过它们(5分钟)而不是相反。

然后,您需要单独的操作来查询作业的状态以查看是否已完成。您可以通过安排作业完成后更新表中的行来完成此操作。