Can’t find resource ‘solrconfig.xml’ in classpath

 Solr是一个高性能独立的企业级搜索应用服务器,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

1、索引配置

 

mainIndex 标记段定义了控制Solr索引处理的一些因素.

  • useCompoundFile:通过将很多 Lucene 内部文件整合到单一一个文件来减少使用中的文件的数量。这可有助于减少 Solr 使用的文件句柄数目,代价是降低了性能。除非是应用程序用完了文件句柄,否则 false 的默认值应该就已经足够。
  • useCompoundFile:通过将很多Lucene内部文件整合到一个文件,来减少使用中的文件的数量。这可有助于减少Solr使用的文件句柄的数目,代价是降低了性能。除非是应用程序用完了文件句柄,否则false的默认值应该就已经足够了。
  • mergeFacor:决定Lucene段被合并的频率。较小的值(最小为2)使用的内存较少但导致的索引时间也更慢。较大的值可使索引时间变快但会牺牲较多的内存。(典型的时间与空间 的平衡配置)
  • maxBufferedDocs:在合并内存中文档和创建新段之前,定义所需索引的最小文档数。段是用来存储索引信息的Lucene文件。较大的值可使索引时间变快但会牺牲较多内存。
  • maxMergeDocs:控制可由Solr合并的 Document 的最大数。较小的值(<10,000)最适合于具有大量更新的应用程序。
  • maxFieldLength:对于给定的Document,控制可添加到Field的最大条目数,进而阶段该文档。如果文档可能会很大,就需要增加这个数值。然后,若将这个值设置得过高会导致内存不足错误。
  • unlockOnStartup:告知Solr忽略在多线程环境中用来保护索引的锁定机制。在某些情况下,索引可能会由于不正确的关机或其他错误而一直处于锁定,这就妨碍了添加和更新。将其设置为true可以禁用启动索引,进而允许进行添加和更新。(锁机制)

 

2、查询处理配置

 

query标记段中以下一些与缓存无关的特性:

  • maxBooleanClauses:定义可组合在一起形成以个查询的字句数量的上限。正常情况1024已经足够。如果应用程序大量使用了通配符或范围查询,增加这个限制将能避免当值超出时,抛出TooMangClausesException。
  • enableLazyFieldLoading: 如果应用程序只会检索Document上少数几个Field,那么可以将这个属性设置为 true。懒散加载的一个常见场景大都发生在应用程序返回一些列搜索结果的时候,用户常常会单击其中的一个来查看存储在此索引中的原始文档。初始的现实常 常只需要现实很短的一段信息。若是检索大型的Document,除非必需,否则就应该避免加载整个文档。

 

query部分负责定义与在Solr中发生的时间相关的几个选项:

 

 

概念:Solr(实际上是Lucene)使用称为Searcher的Java类来处理Query实例。Searcher将索引内容相关的数据加载到 内存中。根据索引、CPU已经可用内存的大小,这个过程可能需要较长的一段时间。要改进这一设计和显著提高性能,Solr引入了一张“温暖”策略,即把这 些新的Searcher联机以便为现场用户提供查询服务之前,先对它们进行“热身”。

  • newSearcher和firstSearcher事件,可以使用这些事件来制定实例化新Searcher或第一个Searcher 时,应该执行哪些查询。如果应用程序期望请求某些特定的查询,那么在创建新Searcher或第一个Searcher时就应该反注释这些部分并执行适当的 查询。

 

query中的智能缓存:

 

  • filterCache:通过存储一个匹配给定查询的文档 id 的无序集,过滤器让 Solr 能够有效提高查询的性能。缓存这些过滤器意味着对Solr的重复调用可以导致结果集的快速查找。更常见的场景是缓存一个过滤器,然后再发起后续的精炼查 询,这种查询能使用过滤器来限制要搜索的文档数。
  • queryResultCache:为查询、排序条件和所请求文档的数量缓存文档 id 的有序集合。
  • documentCache:缓存Lucene Document,使用内部Lucene文档id(以便不与Solr唯一id相混淆)。由于Lucene的内部Document id 可以因索引操作而更改,这种缓存不能自热。
  • Named caches:命名缓存是用户定义的缓存,可被 Solr定制插件 所使用。

其中filterCache、queryResultCache、Named caches(如果实现了org.apache.solr.search.CacheRegenerator)可以自热。

每个缓存声明都接受最多四个属性:

  • class:是缓存实现的Java名
  • size:是最大的条目数
  • initialSize:是缓存的初始大小
  • autoWarmCount:是取自旧缓存以预热新缓存的条目数。如果条目很多,就意味着缓存的hit会更多,只不过需要花更长的预热时间。

对于所有缓存模式而言,在设置缓存参数时,都有必要在内存、cpu和磁盘访问之间进行均衡。统计信息管理页(管理员界面的Statistics)对 于分析缓存的 hit-to-miss 比例以及微调缓存大小的统计数据都非常有用。而且,并非所有应用程序都会从缓存受益。实际上,一些应用程序反而会由于需要将某个永远也用不到的条目存储在 缓存中这一额外步骤而受到影响。

在自定义了自己的solrj web的时候启动会报如下错误

java.lang.RuntimeException:  Can't  find resource 'solrconfig.xml'  in classpath  or 'solr\.\conf/',  cwd=......

解决方法有如下几种任选一种即可:

(1) 在

D:\Apache Software Foundation\Tomcat 6.0\conf\Catalina\localhost

这个目录下新建一个和你自己web 相同名字的xml,(mySolr.xml(我自己发布的solrj 工程名就是mySolr))

里面内容如下

<?xml version="1.0" encoding="UTF-8"?>

 

<Context docBase="D:\Apache Software Foundation\Tomcat 6.0\webapps\mySolr" debug="0" crossContext="true" >

 

<Environment name="solr/home" type="java.lang.String" value="D:\solr" override="true" />

 

</Context>

( 2) 在自己的 web 里找到 WEB-INF 下的web.xml

在  <filter> 标签的上方 添加如下内容

<env-entry>

<env-entry-name>solr/home</env-entry-name>

<env-entry-value>D:/solr</env-entry-value>

<env-entry-type>java.lang.String</env-entry-type>

</env-entry>

 

 

要使用Solr进行开发,必须得自己搭建其开发环境,Solr自带的只有运行例子,而且直接部署运行还会报错。这里就来说明一下搭建Solr开发环境的过程,我的开发环境为Eclipse、Tomcat。

目前Solr和Lucene的最新版本已经是3.6.0的了,我就以该最新的版本为例。先从其官网下载到最新的发布包apache-solr-3.6.0.zip和源码包apache-solr-3.6.0-src.tgz,分别将

apache-solr-3.6.0-src.tgz解压开来为apache-solr-3.6.0.src及apache-solr-3.6.0.zip解压开来为apache-solr-3.6.0。

1.创建工程

在Eclipse创建一个Web工程solr-3.6.0(如果不清楚如何通过Eclipse创建Web工程的话可以参见这里), 然后将解压开的目录apache-solr-3.6.0.src\solr\core\src\java和apache-solr-3.6.0.src \solr\solrj\src\java下面的目录及java文件拷贝到刚创建的工程solr-3.6.0的src下面。

找到apache-solr-3.6.0\dist目录下面的apache-solr-3.6.0.war文件,解压后,将其根目录下的所有文件都拷贝到工程solr-3.6.0的根目录WebRoot下面。

另外还需要如下Jar包:

httpclient支持包httpclient-4.1.3.jar、httpcore-4.1.4.jar、httpmime-4.1.3.jar,这些包都可以从httpclient的官网上下载到。

Jetty支持包jetty-6.1.26.jar、jetty-util-6.1.26.jar,下载地址:http://dist.codehaus.org/jetty/

将所有jar包引入到工程进行编译,正确无误后工程就创建完了。

2.配置运行

在tomcat配置文件server.xml中进行配置:

<Context path=”/solr” docBase=”D:/program/solr-3.6.0/WebRoot” />

然后运行tomcat看看,报错:

严重: java.lang.RuntimeException: Can't find resource 'solrconfig.xml' in classpath or
'solr\.\conf/', cwd=D: \tomcat-7.0.23
at org.apache.solr.core.SolrResourceLoader.openResource(SolrResourceLoader.java:273)
at org.apache.solr.core.SolrResourceLoader.openConfig(SolrResourceLoader.java:239)
严重: Could not start Solr. Check solr/home property and the logs
org.apache.solr.common.SolrException: No cores were created
at org.apache.solr.core.CoreContainer$Initializer.initialize(CoreContainer.java:172)

这是因为我们还需要进行一些配置才能让Solr正确运行起来。在web.xml中找到被注释的节点:

<!--
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>/put/your/solr/home/here</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
-->

然后将注释去掉并修改为:

<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>D:/solr/</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

在解压开的apache-solr-3.6.0目录\example\multicore中,将配置文件solr.xml及目录core0、core1拷贝到在web.xml配置的solr/home目录D:\solr中,solr.xml的内容如下:

<solr persistent="false">
<!--
adminPath: RequestHandler path to manage cores.
If 'null' (or absent), cores will not be manageable via request handler
-->
<cores adminPath="/admin/cores">
<core name="core0" instanceDir="core0" />
<core name="core1" instanceDir="core1" />
</cores>
</solr>

在solr.xml中创建了两个core。

然后再次运行tomcat,启动正确!访问solr的地址:

http://localhost:8080/solr/,出现如下正确页面:

点一个链接Admin core0进去看看:

然后再点其它链接及按钮试试,运行都正确无误!

 

 

 

solrconfig.xml

(2011-08-22 20:16:19)

标签:

solrconfig.xml

分类: Linux

设置增加的jar包目录

<lib dir="./lib"/>

 

存放索引数据

<dataDir>${solr.data.dir:/usr/local/tomcat/webapps/solr/data}</dataDir>

 

设置缓存

<directoryFactory name="DirectoryFactory"

class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>

 

配置查询选项

<requestHandler name="search" class="solr.SearchHandler" default="true">

配置高亮

<bool name="hl">true</bool>

<str name="hl.fl">title</str>

<int name="hl.snippets">3</int>

</requestHandler>

 

配置更新接口

<requestHandler name="/update" class="solr.XmlUpdateRequestHandler">

 

solr 自动提交autocommit

想让solr自动提交只需要修改solrconfig.xml文件的一些配置就能做到,方法很简单:

打开solrconfig.xml,增加以下配置(solrconfig.xml中以下配置已经被注释掉):

<updateHandler>
    <autoCommit>
         <maxDocs>10000</maxDocs>
         <maxTime>1000</maxTime>
    </autoCommit>
</updateHandler>

maxDocs:当内存索引数量达到指定值的时候,将内存的索引DUMP到硬盘中,并通知searcher类加载新的索引

maxTime:每隔指定的时间段,自动的COMMIT内存中的索引数据,并通知Searcher类加载新的索引。

以上两种方式,以最先达到条件执行为准。

这样solr auto commit就配置好了

 

 

 

solr索引目录与扩展

1.solr 如何读取索引

在solrconfig.xml中可以配置solr的索引目录。

<dataDir>${solr.data.dir:./solr/data}</dataDir>

默认是在目录./solr/data,如果使用分布式的话,这个配置要跟主机一致。

 

 

如果有存在文件index.properties,则读取index=index.20101102052813,获得指定的索引目录index.20101102052813,只在创建indexSearchers 或者indexwriters时调用。

 

在这里有个疑问,这个index.properties是什么时候出现的,在solrconfig里没有配置的,难道是因为分布式的时候,主机生成的,然后分发到各个子机上。暂时还没有看到这边的代码 ,不过听上司说是这样的。

 

2.solr扩展DirectoryFactory插件,以应用自己实现的Directory,比如使用HDFS

solr获取Directory,是由实现抽象类DirectoryFactory的StandardDirectoryFactory (默认),调用open(String path) 方法,而实现类StandardDirectoryFactory

public class StandardDirectoryFactory extends DirectoryFactory {
public Directory open(String path) throws IOException {
return FSDirectory.open(new File(path));
}
}

 

只是简单地在实现open(String path)中,使用lucene的FSDirectory.open(new File(path));来获取 Directory的引用。

在这里便用户便可以在些扩展自己的实现类,通过继承DirectoryFactory,比如实现内存的索引Directory

 

public class RAMDictoryFactory extends DirectoryFactory {
public Directory open(String path) throws IOException {
return new RAMDirectory();
}
}

 

然后在solrconfig.xml上配置扩展的DirectoryFactory

 

<directoryFactory name="DirectoryFactory">
Parameters as required by the implementation
</directoryFactory >

 

这样在初始化SolrCore时就会,调用

private void initDirectoryFactory() {
DirectoryFactory dirFactory;
PluginInfo info = solrConfig.getPluginInfo(DirectoryFactory.class.getName());
if (info != null) {
dirFactory = (DirectoryFactory) getResourceLoader().newInstance(info.className);
dirFactory.init(info.initArgs);
} else {
dirFactory = new StandardDirectoryFactory();
}
// And set it
directoryFactory = dirFactory;
}

 

从源代码可以看出,默认是不用配置DirectoryFactory的,如果没有配置就使用StandardDirectoryFactory类。

发表评论