我想加快将 10GB 数据编入 Lucene 索引的速度。TPL 会是一个很好的方法吗?我是否需要将数据分成块,然后让每个线程开始索引块?
为了保持 UI 响应,BackgroundWorker 是最好的方法,还是 Task,还是别的什么?
SOLR 是否已经做了这样的事情?还是自己编写代码仍然值得。
我想加快将 10GB 数据编入 Lucene 索引的速度。TPL 会是一个很好的方法吗?我是否需要将数据分成块,然后让每个线程开始索引块?
为了保持 UI 响应,BackgroundWorker 是最好的方法,还是 Task,还是别的什么?
SOLR 是否已经做了这样的事情?还是自己编写代码仍然值得。
假设您使用的是 Java——我在使用多线程进行索引方面有很好的经验。根据我的经验,Lucene 索引基本上受 CPU 限制,这意味着如果您生成 N 个线程,您可以使用所有 N 个内核。
LuceneIndexWriter
处理并发,因此您无需担心。您的线程可以随时调用indexWriter.addDocument
。
在一个项目中,文档来自数据库中的 SELECT 语句。我创建了 N 个线程,每个线程都从中获取下一个文档ResultSet
并将其添加到索引中。当没有更多行并且主线程在CountDownLatch
.
第二个项目有点复杂。系统正在“抓取”一组文档,也就是说,从一开始就不清楚会有多少文档。所以有必要维护一个已经发现的文件的“队列”。在分析和索引这些文档的过程中,可以发现更多的文档,然后将这些文档也添加到队列中。队列在开始时填充了初始/种子文档。我创建了一个类AutoStopThreadPool来管理线程,如果你喜欢,欢迎下载。(您需要“添加”所有任务然后“等待完成”的 JVM 线程池,这是不合适的,因为处理任务可能会导致发现新任务)
如果您希望多个线程写入单个 IndexWriter,那么我只会生成一个执行类似操作的线程
Parallel.ForEach(docs, d => { writer.Add(d,analyzer) });
因此.NET 处理拆分数据。
在较大的索引大小下,有些人发现拥有多个写入的索引然后将所有索引合并在一起可以提高性能。我的理解是,这仅对真正的海量索引非常有用,但是如果您想这样做,那么您可能需要自己处理拆分数据。在这种情况下,使用像 tpl 这样功能更全面的库可能会很有用。
Solr 本质上是多线程的,因此您将执行与我之前给您完全相同的代码段,除了直接调用编写器而不是调用您的 REST/SolrNet 方法。
作为一般规则,如果您问“我应该使用 Solr 还是自己制作?” 答案几乎总是“使用 Solr”。我想不出有什么理由让你自己在这里做,除非你的 jvm 真的很糟糕或者你真的讨厌 java。