Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.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
Mysql 将大型XML文件解析到数据库中。使用多线程?_Mysql_Ruby_Xml_Multithreading - Fatal编程技术网

Mysql 将大型XML文件解析到数据库中。使用多线程?

Mysql 将大型XML文件解析到数据库中。使用多线程?,mysql,ruby,xml,multithreading,Mysql,Ruby,Xml,Multithreading,我有一个5GB+XML文件,我想将其解析到MySQL数据库中。我目前有一个Ruby脚本,它使用Nokogiri SAX解析器将每一本新书插入数据库,但是这个方法非常慢,因为它逐个插入。我需要找到一种方法来解析具有多个并发线程的大文件 我在想我可以把文件分成多个文件,每个子文件上都有多个脚本。或者让脚本将每个项目发送到后台作业,以便插入数据库。可能使用延迟工作、重新调整或sidekiq <?xml version="1.0"?> <ibrary> <NAME>

我有一个5GB+XML文件,我想将其解析到MySQL数据库中。我目前有一个Ruby脚本,它使用Nokogiri SAX解析器将每一本新书插入数据库,但是这个方法非常慢,因为它逐个插入。我需要找到一种方法来解析具有多个并发线程的大文件

我在想我可以把文件分成多个文件,每个子文件上都有多个脚本。或者让脚本将每个项目发送到后台作业,以便插入数据库。可能使用延迟工作、重新调整或sidekiq

<?xml version="1.0"?>
<ibrary>
  <NAME>cool name</NAME>
  <book ISBN="11342343">
    <title>To Kill A Mockingbird</title>
    <description>book desc</description>
    <author>Harper Lee</author>
  </book>
  <book ISBN="989894781234">
    <title>Catcher in the Rye</title>
    <description>another description</description>
    <author>J. D. Salinger</author>
  </book>
</library>

酷名
杀死一只知更鸟
书名
哈珀·李
麦田守望者
另一种描述
杰罗姆·大卫·塞林格

有人有这方面的经验吗?使用当前脚本,加载数据库需要一年时间。

对于生产者/消费者队列来说,这似乎是一项完美的工作。您只需要一个线程来解析XML,但当它解析项目时(可能将它们转换为准备插入的对象类型),它可以将转换后的对象放入多个线程正在读取的队列中。每个使用者线程只会阻塞队列,直到队列“完成”(即,生产者说不再有任何数据)或队列中有一个项目——在这种情况下,它会处理它(将项目添加到数据库),然后返回等待数据。您将需要试验有多少消费者线程可以为您提供最大吞吐量—这将取决于各种考虑因素,主要是数据库的配置方式以及与数据库的连接情况


我对Ruby中的线程技术一无所知,所以我无法给出示例代码,但我确信一定有一个标准的生产者/消费者队列可用,其余的应该相当简单。

对不起,我想这是很清楚的。DB插入是瓶颈。SAX解析器识别和对象,然后等待DB插入完成,然后再继续下一步。单独读取XML文件而不插入DB不会花费很长时间。也许30分钟?快速读取文件绝对不是在插入之前删除索引的问题。您是否尝试过将插入内容分组成更大的批<代码>插入账簿值('title1','desc1'),('title2','desc2')?一次执行多个插入应该比一个快得多。Sidekiq可以异步运行,但如果您有25个工作线程,并且您希望能够将连接池也增加到25个。如果您不将代码转换为每个请求插入多个记录,您将永远无法解决速度问题:。看看这里如何使用ActiveRecord:谢谢Jon。这是我考虑的方法之一。ruby版本的消费者队列通常是延迟的、重新创建的和/或sidekiq。只是没有太多的经验,所以这就是为什么我在这里问。我计划在AWS上运行该作业。您是否有运行线程多于内核的一般经验?i、 e.在一个4核实例上运行10个线程正常吗?@Jeff:如果线程是IO绑定的(例如,异步调用无法避免),那么是的,拥有比线程更多的内核是非常有意义的。Ruby的文档中有一个简单的示例,说明如何使用生产者和消费者。使用它,再加上Nokogiri代码和类似ORM的代码,将很容易组合出一个解决方案。