【问题标题】:techniques for bulk data processing批量数据处理技术
【发布时间】:2011-10-04 11:57:10
【问题描述】:

我正在寻找一种技术来执行以下操作,我需要您的建议。 我有一个带有注册 ID 的巨大(真的)表,我需要向这些 ID 所有者发送消息。我无法一次将消息发送给多个收件人,这需要逐个进行。所以我想要一个脚本(php),它可以通过从数据库中获取一些数量并处理它来在许多并行实例(进程)中运行。换句话说,每个流程都需要处理特定范围的数据。我还想停止每个进程,并能够继续从停止的用户向另一组尚未收到消息的用户发送消息。 如果它是可能的?欢迎任何提示和建议。

【问题讨论】:

    标签: php message bulk


    【解决方案1】:

    您可能希望设置一个 cron 作业,这通常是使用 PHP 脚本运行大批量操作的最佳方法之一:

    http://www.developertutorials.com/tutorials/php/running-php-cron-jobs-regular-scheduled-tasks-in-php-172/

    您的 cron 作业需要指向执行以下操作的 PHP 脚本:

    1. 从大型数据库表中选择收件人子集,基于 标志设置为 #3(如下),标识要处理的下一批
    2. 向选定的收件人发送电子邮件
    3. 保存当前职位成功/失败的记录(即您可以设置一个 数据库中成功邮寄的每个收件人旁边的标记,然后在重新运行作业时不会选择这些标记)

    【讨论】:

      【解决方案2】:

      仅在您的服务器配置范围内可以进行并行处理。许多服务器可以以并行方式提供页面,但话又说回来,它仅限于少数。相反,经验法则是尽可能快地跳转到下一个请求。

      关于您对数据库中非常大的数据列表的处理。您首先需要一个您正在发送的邮件的 id 列表:

      INSERT INTO `mymailinglisttable` (mailing_id, recipient_id, senton) SELECT 123 AS mailing_id, mycontacttable.recipient_id, NULL FROM mycontacttable WHERE [insert your criterias for your contacts]
      

      接下来,您将需要使用 innodb 或一些巧妙的逻辑来进行并行处理:

      使用 InnoDB,您可以进行一些行级锁定,但不要问我如何,自己搜索,我根本不使用 InnoDB,但我知道这是可能的。因此,您阅读了相关文档,选择并锁定了一些行,发送电子邮件,标记为已发送,然后通过回调您自己的脚本来重复操作。 (使用 AJAX 或使用 php 套接字)

      没有 InnoDB,您可以简单地向数据库添加 2 个字段,一个是 processid,另一个是 lockon 字段。当您想锁定某些地址以进行处理时,请执行以下操作:

      $mypid = getmypid().rand(1111,9999);
      $now = date('Y-m-d G:i:s');
      mysql_query('UPDATE mymailinglisttable SET mypid = '.$mypid.', lockedon = "'.$now.'" LIMIT 3');
      

      这将为您的 pid 锁定 3 行,并在当前时间,选择被锁定的行:

      mysql_query('SELECT * FROM mymailinglisttable WHERE mypid = '.$mypid.' AND lockedon = "'.$now.'")
      

      您将检索正确锁定的 3 行以进行处理。我倾向于使用这个版本而不是 innodb 版本,因为我是用这种方法长大的,但不是因为它性能更高,实际上,我确信 InnoDB 的版本要好得多,只是从未尝试过。

      【讨论】:

      • 此时我们可以释放一些收件人,因为我将在过程中停止发送消息。 :( 但也许我无法消除这种情况。要么我会失去一些收件人,要么会发送两次。
      • 不,使用我的版本,而不是 innodb 版本,可以在所有非 SENTON 的行上重置锁。您仅在邮件消失时设置“SENTON”日期。锁是为了防止两次选择行...
      • 抱歉,误解了你的意思:)所以你的意思是每次发送消息时我都必须更新 senton ?如果是的话,嗯..这意味着定期更新不是很好。
      • 好吧,请记住,我们在此板上所说的只是建议,您应该选择最适合您的并在必要时进行调整。这是成为一名优秀程序员的过程的一部分...... :)
      • 同意:) 现在我想知道 php 处理部分。即,如果我能以某种方式获得前 1000 行,那么我应该获得下一组 1000 个我尚未发送消息的用户。我应该添加超时还是其他东西。实际上我不喜欢超时的想法,但不知道我还能做什么。
      【解决方案3】:

      如果您对使用 PEAR 模块感到满意,我建议您看看 pear Mail_Queue 模块。

      http://pear.php.net/package/Mail_Queue

      有很好的文档和一个很好的教程。我之前使用过这个的修改版本向客户发送了数千封电子邮件,但它还没有给我带来任何问题:

      http://pear.php.net/manual/en/package.mail.mail-queue.mail-queue.tutorial.php

      【讨论】:

      • 感谢 Tom,但实际上这些消息不是普通的电子邮件,而是 android 推送通知。因此我需要自己处理发送消息。
      • 那么这可能会起作用:您可以像这样从列表中选择:$threads = 10 // How many threads are you running$thread_id = 1 // Which of your PHP threads is this$sql = 'SELECT * FROM list WHERE sent=0 AND id % ' . $threads . ' = ' . $thread_id;
      猜你喜欢
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 2014-11-10
      • 2011-11-20
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多