我正在使用 Solrj 索引一些文件,但我注意到使用ConcurrentUpdateSolrServer类的奇怪行为。我的目标是非常快速地索引文件(每秒 15000 个文档)。
我已经在具有 8 个 CPU 的 Linux 上的远程虚拟机 (VM) 上设置了一个 Solr 实例,并使用 Eclipse 在我的计算机上实现了一个带有 Solrj 的 java 程序。我将描述我尝试过的两种情况以解释我的问题:
方案 1:
我已经使用 eclipse 运行我的 java 程序来索引我的文档,使用我的 VM 的地址定义我的服务器,如下所示:
String url = "http://10.35.1.72:8080/solr/";
ConcurrentUpdateSolrServer server = new ConcurrentUpdateSolrServer(url,4000,20);
我添加了我的文档,创建了一个扩展Thread的 java 类:
@Override
public void run(){
SolrInputDocument doc = new SolrInputDocument();
/*
* Processing on document to add fields ...
*/
UpdateResponse response = server.add(doc);
/*
* Response's Analysis
*/
但是为了避免以顺序方式添加文档,我使用了一个Executor以并行方式添加我的文档,如下所示:
Executor executor = Executors.newFixedThreadPool(nbThreads);
for (int j = 0; j < myfileList.size(); j++) {
executor.execute(new myclassThread(server,new myfileList(j)));
}
当我运行这个程序时,结果很好。我所有的文档都在 solr 索引中得到了很好的索引。我可以在 solr admin 上看到它:
Results :
numDocs: 3588
maxDoc: 3588
deletedDocs: 0
问题是与不使用 solrj 的索引和 VM 上的索引相比,索引性能非常低(索引速度慢)。这就是为什么我创建了我的程序的 jar 文件以在我的 VM 上运行它。
方案 2:
所以,我用 eclipse 生成了一个 jar 文件并在我的虚拟机上运行它。我已经像这样更改了服务器的网址:
String url = "http://localhost:8080/solr/";
ConcurrentUpdateSolrServer server = new ConcurrentUpdateSolrServer(url,4000,20);
我已经使用相同的文档集合(具有唯一 ID 的 3588 个文档)运行我的 jar 文件:
java -jar myJavaProgram.jar
Solr Admin 上的结果是:
Results :
numDocs: 2554
maxDoc: 3475
deletedDocs: 921
这个结果取决于我的线程设置(对于 Executor 和 SolrServer)。最后,并非所有文档都被索引,但索引速度更好。我想我的文档的添加对于 Solr 来说太快了,并且有一些损失。
我没有成功找到我的线程的正确设置。无论我设置的线程多或少,无论如何,我都有损失。
问题 :
- 有人听说过 ConcurrentUpdateSolrServer 类的问题吗?
- 这些损失有解释吗?为什么在第二种情况下我的所有文档都没有被索引?为什么有些文档即使有唯一的密钥也会被删除?
- 是否有适当的方法以并行方式(非顺序)添加 Solrj 文档?
我见过另一个 Solrj 类来索引数据:EmbeddedSolrServer。此类是否允许提高索引速度或比 ConcurrentUpdateSolrServer 更安全地索引数据?- 当我分析 add() 方法的响应时,我注意到结果总是可以的(response.getstatut()=0),但事实并非如此,因为我的文档没有被很好地索引。那么,这个 add() 方法的行为是否正常?
- 最后,如果有人能在快速索引数据的方法上给我建议,我将不胜感激!:-)
编辑 :
我尝试在每次调用 ConcurrentUpdateServer 的 add() 方法之间使用Thread.sleep(time)来降低索引速度。
在每次调用 ConcurrentUpdateServer 的 add() 方法后,我都尝试过 commit() (我知道这不是每次添加时提交的好解决方案,但它是为了测试)。
我尝试不使用 Executor 来管理我的线程,并且我创建了一个或多个静态线程。
在测试了这几种策略来索引我的文档集合之后,我决定使用 EmbeddedSolrServer 类来查看结果是否更好。
所以我实现了这段代码来使用 EmbeddedSolrServer :
final File solrConfigXml = new File( "/home/usersolr/solr-4.2.1/indexation_test1/solr/solr.xml" );
final String solrHome = "/home/usersolr/solr-4.2.1/indexation_test1/solr";
CoreContainer coreContainer;
try{
coreContainer = new CoreContainer( solrHome, solrConfigXml );
}catch( Exception e ){
e.printStackTrace( System.err );
throw new RuntimeException( e );
}
EmbeddedSolrServer server = new EmbeddedSolrServer( coreContainer, "collection1" );
我添加了正确的 JAR 以使其正常工作,并且成功地为我的收藏建立了索引。
但是,在这些尝试之后,我仍然对 Solr 的行为感到困扰……我仍然有同样的损失。
Result :
Number of documents indexed :2554
2554 个文档 / 3588 个文档 (myCollection) ...
我想我的问题更具技术性。但是我的计算知识就止步于此了!:( 为什么当我在我的 VM 上索引我的文档时会出现一些损失,而当我从我的计算机执行我的 java 程序时却没有这些损失?
是否有与 Jetty 的链接(也许它无法吸收输入流?)?是否有一些组件(缓冲区、RAM 溢出?)对 Solr 有一些限制?
如果我对我的问题不够清楚,请告诉我,我会尽量让它更清楚。
谢谢
科伦廷