ConcurrentUpdateSolrServer类的奇怪行为

时间:2013-07-01 16:19:53

标签: solr solrj

我正在使用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文件并在我的VM上运行它。我已经像这样更改了服务器的URL:

String url = "http://localhost:8080/solr/";
ConcurrentUpdateSolrServer server = new  ConcurrentUpdateSolrServer(url,4000,20);

我使用相同的文档集运行我的jar文件(带有唯一ID的3588个文档):

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 docs / 3588 docs(myCollection)......

我猜我的问题更具技术性。但是我的计算知识就此止步! :( 当我在我的VM上索引文档时,为什么我会在从计算机执行java程序时没有这些损失时获得一些损失?

是否有与Jetty的链接(可能无法吸收输入流?)? 是否有一些组件(缓冲区,RAM溢出?)对Solr有一些限制?

如果我对我的问题不够清楚,请告诉我,我会尽量让它更清楚。

由于

Corentin

1 个答案:

答案 0 :(得分:1)

我的代码只是一个错误。我的文件在我的计算机和我的VM上没有以相同的顺序读取。所以问题的原因不是来自Solr。这是因为我。