如何并行运行一些作业

时间:2017-01-05 15:24:55

标签: ruby parallel-processing

在阅读了Ruby中关于并行性的所有帖子之后,我只是感到困惑,所以我将描述我想要做的事情。

我的names包含大约1000个名字。

names
=> [{"name"=>"tickets"}, {"name"=>"events"}, {"name"=>"channel"}, {"name"=>"primes"}]

对于每个名称,如果表格存在,请使用pg。

删除该表格
drop_str = "DROP TABLE IF EXISTS %s ;"
create_str = "CREATE TABLE %s (id SERIAL PRIMARY KEY,bkk varchar(255))"

names.each do |name|
    conn.exec((drop_str % name["name"]) + (create_str % name["name"]))
end

但是,我不想一个接一个地删除表。我想要并行完成。

我的想法是使用以下内容:

threads = []
drop_str = "DROP TABLE IF EXISTS %s ;"
create_str = "CREATE TABLE %s (id SERIAL PRIMARY KEY,bkk varchar(255))"

names.each do |name|
    threads.push(Thread.new{conn.exec((drop_str % name["name"]) + (create_str % name["name"]))})
end

然后加入主题。

实际上,这些表会被并行删除还是一个接一个地删除?

1 个答案:

答案 0 :(得分:0)

原则上,您可以并行运行多个SQL语句。大多数数据库引擎都是多线程的,并且可以并行执行多个语句有时它并没有多大意义,就像使用SQLite一样。

虽然有几个警告可能会破坏您当前的代码。

最重要的是,与数据库的单个连接始终会附加一些状态。通常,它将保存数据库适配器的事务和内部状态。因此,单个数据库连接通常一次只能在单个线程中使用。如果您尝试通过单个连接发送多个并行语句,那么事情可能会在确定性方面发生。

因此,当尝试使用线程并行运行多个语句时,每个线程都需要自己的数据库连接。在这里,使用线程池通常是有意义的,这些线程池创建固定的大量连接数并从队列中调度工作来运行这些连接。

您可以使用例如轨道' ConnectionPool使用优秀ThreadPool implementations gem中的concurrent-ruby之一来处理数据库连接并安排语句。