Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何并行:6台机器,800万独立文档在数据库中进行处理_Python_Mysql_Parallel Processing - Fatal编程技术网

Python 如何并行:6台机器,800万独立文档在数据库中进行处理

Python 如何并行:6台机器,800万独立文档在数据库中进行处理,python,mysql,parallel-processing,Python,Mysql,Parallel Processing,背景: 我在数据库中有800万个独立文档要处理。文档之间没有依赖关系,这意味着流程可以并行化。处理一个文档后,结果将保存回数据库 有6台机器供我使用 当前解决方案 在MySQL中使用一个表存储文档 现在,我将这些行平均划分为6个共享,每个共享由一台机器处理 当前解决方案的缺点 某些分区可能需要更长的时间来处理,从而使某些计算机在其他计算机空闲时处于忙碌状态 要求 我想找到一种有效地平衡任务负载的方法/框架 我使用Python作为数据处理工具,希望有适合Python的工具 您不应该将行划分为相等的

背景:

我在数据库中有800万个独立文档要处理。文档之间没有依赖关系,这意味着流程可以并行化。处理一个文档后,结果将保存回数据库

有6台机器供我使用

当前解决方案

在MySQL中使用一个表存储文档

现在,我将这些行平均划分为6个共享,每个共享由一台机器处理

当前解决方案的缺点

某些分区可能需要更长的时间来处理,从而使某些计算机在其他计算机空闲时处于忙碌状态

要求

  • 我想找到一种有效地平衡任务负载的方法/框架
  • 我使用Python作为数据处理工具,希望有适合Python的工具

  • 您不应该将行划分为相等的共享,而应该向文档表中添加一个进度字段(您应该真正创建一个进度表并进行外部联接,但您会明白这一点)。然后在每个worker中,您首先预订一组文档(假设
    id
    是主键,
    WORKERID
    是每个worker的唯一id):

    (如果您使用的是旧版本的MySQL,则可能需要更复杂的语法:)

    确保您的限制足够大,以便数据库有喘息的空间,但不要太大,以至于您必须等待最后一个工作人员完成他的第10000个文档:-)

    然后可以开始迭代:

    c.execute("select * from documents where progress = %s", my_worker_id)
    for doc in c.fetchall():
        # process doc..
        c.execute("update documents set progress = 'done' where id = %s", doc.id)
        cn.commit()
    
    这样做的优点是非常容易实现,速度非常快,并且可以重新启动任何工作程序等

    如果你只有6个工人,我就用手启动他们

    哦,您可以使用简单的sql语句手动监视进度:

    select progress, count(*)
    from documents
    group by progress
    order by progress
    

    这将告诉您还有多少剩余(progress=null)、多少已完成(progress='done')以及每个工人队列中有多少人(progress=WORKERID)。

    这一条对我帮助很大,而且非常容易使用您的文档有多大?您希望每个文档的处理速度有多快?请尝试进行循环流式分发,而不是一开始就将数据拆分为6个文件。您想要的称为简单分发。你可以试试,如果你在某处安装了redis,这真的很容易。如果你想要更复杂的东西,看看。谢谢@thebjorn。但不幸的是,这并不能回答我的问题。我想要的东西,可以做负载平衡的东西。或者类似于循环的方法。@xiaohan2012实际上,这将自动进行负载平衡(假设您的限制是合理的)。工人将以他们能够处理的速度登记和处理工作。这种方法比循环法更好(更具并行性),因为在循环法中,即使工作人员没有完成最后一个切片,也需要给他一个切片——这可能会导致速度较慢的工作人员积压更多的切片。如果您想要自动启动流程的东西,请尝试使用fabric。@xiaohan2012。。。而且,循环方法需要某种中央权威,这可能成为瓶颈(尽管可能不是只有六台服务器…)
    select progress, count(*)
    from documents
    group by progress
    order by progress