导入大型数据集的性能提示

Performance tips on importing large sets of data

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

  1. 用户选择了他们想要从中导入联系人的文件(从他们的计算机)。
  2. 我将文件保存在服务器上并创建一个数据库条目并引用文件位置。
  3. Amazon SQS 用于在后台处理此问题。
  4. 作业第一次运行时,我处理文件,仅保存包含电子邮件地址和名称(如果找到)的行。数据保存到同一位置的 json 文件并缓存。然后我将作业放回队列中。
  5. 现在可以导入联系人了。我在每个工作中获取 1000 个联系人,并将每个联系人保存在数据库中自己的行中。我使用 array_slice 跳过 json 文件中的联系人。跳过计数保存到数据库中。
  6. 当没有联系人时,作业被删除,一切都完成。

这就是整个过程。我还有一个检查(数据库查找)来检查重复项。只允许使用唯一的电子邮件地址。

我遇到的问题是这项工作似乎花费了太多时间,而且我会超时。这导致导入需要很长时间。

所以我的问题是:有什么我可以做得更好的吗?

如果您还需要什么,请告诉我。我对大数据和很多用户没有太多经验。

编辑: 我不需要代码。我想要的是,问题是服务器问题吗?也许将数据库移到它自己的服务器上就可以了?还是我应该使用不同的方法?

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

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

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

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

您需要以 php 程序在 AWS SQS 上启动作业的方式组织您的操作,然后告诉您的用户作业是 运行 并将在一段时间后完成.设置较低的用户期望值 ("done in 15 minutes"),然后超过它们(5 分钟),而不是相反。

然后您需要一个单独的操作来查询作业的状态以查看它是否已完成。您可以通过安排作业在完成后更新 table 中的一行来做到这一点。

I take 1000 contacts in each job and saves each contact in its own row in the database.

我以前也遇到过这个问题,但在我的问题中,我需要导入大约 50000 条员工在场记录,我已经使用并行化解决了这个问题。您可能也注意到了,因此您在每个作业队列中接收了 1000 个联系人。真正的问题是"Process Time out"我们拿那么多面子对不对?

因此,我的解决方案是 创建更多子进程 来完成一项工作。如果我创建一个作业来进行 1000 次导入,它会花费更多的时间和更慢的速度。因此,我创建了 100 个作业队列e,每个作业导入 100 个记录。和我运行一起吧。在这种方法中,您的 CPU 负载将因此增加。如果你有高规格的电脑,这不是问题。

我的建议是:

  1. 创建更多作业队列以进行导入。
  2. 避免使用过多的循环。
  3. 如果可能,请将您的数据存储在 memcached 中,因为它会加快您的进程。我想你也这么认为。了解 APC

您可以阅读here如何将数据存储在内存中。希望这对你有点帮助:)