Solr MultiCore LRU队列

当服务器资源有限但是加载的core特别多的时候怎么办?我们当然希望能够根据索引或查询请求而动态的加载卸载多核,https://issues.apache.org/jira/browse/SOLR-1293 给Solr4.2提供了一个补丁,能够在大规模cores上进行动态的加载卸载,可以参考框架:http://wiki.apache.org/solr/LotsOfCores LotsOfCores. 相关的配置很简单,Solr4.3以后的版本已经集成了此功能,目前我使用的是solr4.4版本,在solr.xml中配置如下: <?xml version=“1.0″ encoding=“UTF-8″ ?>   <solr persistent=“true”>     <cores transientCacheSize=“2″ adminPath=“/admin/cores”>       <core loadOnStartup=“true” instanceDir=“multicore/collection1970_01_1″ transient=“false” name=“core1970_01_1″/>       <core loadOnStartup=“false” instanceDir=“D:\jacoxu\solrHome\multicore\collection0004″ transient=“true” name=“core0004″/>       <core loadOnStartup=“false” instanceDir=“D:\jacoxu\solrHome\multicore\collection0005″ transient=“true” name=“core0005″/>       <core loadOnStartup=“false” instanceDir=“D:\jacoxu\solrHome\multicore\collection0006″ transient=“true” name=“core0006″/>       <core loadOnStartup=“false” instanceDir=“D:\jacoxu\solrHome\multicore\collection0007″ transient=“true” name=“core0007″/>     </cores>   </solr>   这也就是之前讲的删除一个core时,必须先进行一下query访问才能删除dataDir. Solr5.0版还没出,不过估计会有较大的改动。在上次讲过的利用solrj动态添加多核中可以设置新添加core的属性,loadOnStartup和transient属性,但是新添加的core并不参加LRU队列交换,直接修改solr源代码是一件冒险的事,一种可行的方法是进行定时进行tomcat重启操作,重启时要注意的是,在linux上,tomcat很有可能shutdown无效,那么需要进行强制Kill: public static void restartTomcat() {        if (SmsBase.osName==“windows”) {            String[] changePath_cmd = {                “cmd”,                “/c”,                 “cd ”+ SmsBase.tomcatPath,            };            String[] shutdown_cmd = {                “cmd”,                “/c”,                 “shutdown.bat”              };    … 继续阅读

优化solr中那难缠的facet

solr中facet功能对于特定字段的统计任务非常实用,可以对特定字段的term进行统计排序,对于单核的小数据来说还好,但是当数据变得很大时,需要进行multicore进行shards查询时,facet功能消耗的内存会异常的高。 对于solr4.2版本来说,通过facet.offset和facet.limit可以实现翻页查询,通过小翻页能够降低内存的使用。但是并不是可行之计,测试进行每页1个结果的翻页,在亿级规模多核上的facet查询还是会很快把64G服务器的JVM爆掉。如果只是去找很少的一些结果,另一种可以人工简化的操作是进行逐一单核查询,取topN,然后扔给前端归并,效果会好很多。 大规模的全局facet功能本是件很头疼的事,solr4.4版本在schema.xml中增加了一个字段属性 docValues, (其实是从4.2版本开始就有了,不过schema中没有介绍,而且并没有完善其功能,所以被忽视了) 在solr4.4中能对solr的facet功能进行优化的有两点: 1. docValues,配置方法:在schema.xml中的字段配置添加docValues属性,例: <field name=“test” type=“string” indexed=“true” stored=“false” docValues=“true” omitNorms=“true” default=“”/>   2. 在schema.xml中为facet配置一特殊的fieldType, String_disk. 这样能够大量节省很多的内存,因为默认的配置方法是docValuesFormat=”Lucene42″,相关更多介绍可以参见docValues: <fieldType name=“string_disk” class=“solr.StrField” docValuesFormat=“Disk” />   配置特殊订制的字段需要在solrconfig.xml中进行相应的配置: <codecFactory class=“solr.SchemaCodecFactory”/>   通过上面的两种配置方法能够大手笔的优化solr中比较难缠的facet爆JVM问题。

获取当前solr.xml中register的所有coreName

有时候需要通过对solr实例URL的一次http访问,获得该实例当前register的存活core,实现方法如下: public static List<String> GetShardsList(String serverName) {        List<String> shardlist = new ArrayList<String>();        //http://localhost:8080/solr        HttpSolrServer server = new HttpSolrServer(serverName);        server.setConnectionTimeout(1000);        server.setDefaultMaxConnectionsPerHost(100);        server.setMaxTotalConnections(100);        server.setRequestWriter(new BinaryRequestWriter());        // Get Shards        SolrQuery solrQuery = new SolrQuery();        solrQuery.setParam(CommonParams.QT, “/admin/cores”);        solrQuery.setParam(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.STATUS.name));        QueryResponse ds = null;        try {            ds = server.query(solrQuery);        } catch (SolrServerException e1) {            // TODO Auto-generated catch block            e1.printStackTrace();        }        NamedList<NamedList<Object>> ctLst = (NamedList<NamedList<Object>>)ds.getResponse().get(“status”);// 得到响应的头信息 … 继续阅读

利用solrj加载卸载solr多核并更新solr.xml

在使用solr多核时会有这样的需求,动态的加载卸载新core,并更新solr.xml 这样的实现比较容易,实验版本为solr4.2,solr5之后可能会有比较大的改动,还没有出,目前solr4.4的solr.xml配置还是兼容的: 1.动态加载新core public  static void load_solrCore(String coreName, String insPath, String serverName){              try {               //path=”D:/jacoxu/solrHome/multicore/collection0″;            //serverName=”http://localhost:8080/solr”;            HttpSolrServer tempServer= solrServer.setServer(serverName);               CoreAdminRequest.createCore(coreName, insPath, tempServer);           } catch (Exception e) {               e.printStackTrace();           }       }     2.动态卸载旧core public static void unload_solrCore(String coreName, String serverName) {        try {            HttpSolrServer tempServer= solrServer.setServer(serverName);            CoreAdminRequest.unloadCore(coreName, tempServer);        } catch (Exception e) {            e.printStackTrace();        }    }   3.有时在执行上面两个操作的时候需要动态的更新solr.xml,因为如果突然断电或solr服务重新启动,都需要重新初始化solr.xml文件中的多核配置,为了能恢复中断前的多核状态需要能够实时根据上面的两个操作更新solr.xml 只需要配置solr.xml中 … 继续阅读

订制tomcat下的logs输出路径

tomcat输出的日志比较多,对于处理实时数据流的实例,每天可以产生上百M的log日志,位于tomcat/logs目录下,维护一个完整的大系统,希望自定义一个日志路径,但是tomcat日志过于繁多。对于一个使用solr4.4版本实例的tomcat用户来说,需要修改的地方大致有4个地方: 1,修改tomcat/conf/logging.properties 中的${catalina}/logs 路径 –> 所有的.log日志 1catalina.org.apache.juli.FileHandler.level = FINE #设置日志级别 1catalina.org.apache.juli.FileHandler.level = FINE #日志级别为FINE 1catalina.org.apache.juli.FileHandler.level = OFF #禁用日志输出 1catalina.org.apache.juli.FileHandler.level = ALL #输出所有日志 级别一般分为:SEVER > WARNING > INFO > CONFIG > FINE > FINER > FINEST 2,修改tomcat/conf/server.xml中最后的directory=”logs”路径 -> localhost.date.txt日志 不需要时,注释掉以下代码即可 <!– … 继续阅读

关于Solr的性能调优

如何能在有限的服务器资源上较好的使用Solr服务,性能调优是必不可少的。鉴于个人经验,给出几条可调优方法: 1. 配置SolrConfig中的Directory, 不当的Directory会消耗大量的内存或IO资源,当索引规模变大时也很容易导致内存溢出,或索引维护的Map Failed现象!如何选择合适的Directory可参看《Lucene in Action》(第二版) Section2.10 中文本P52; 2. 配置Schema中的字段的 omitNorm= true, Norm中保存了大量的字段信息用于评分排序. 如果不是很必要的话可把omitNorm设置为true能够减少磁盘和内存的使用并加快索引速度,同时只用来索引而不需要显示的字段也可设置indexed=”true” stored=”false”, 具体Norm的作用可参见《Lucene in Action》(第二版) Section2.53 中文本P47; 3. 调整SolrConfig中的合并因子mergeFactor和内存触发机制setRAMBBufferSizeMB。mergeFactor越小,索引合并越频繁,索引段越少,同时,setRAMBBufferSizeMB越小,Writer更新的越频繁,索引段越多;《Lucene in Action》(第二版) Section11 4. 在索引阶段,不进行索引优化能够接受的话,就不进行索引优化optimize(),很耗时的一件事!但是在查询阶段,优化往往能够大幅度提高查询效率,因而如果可以,考虑周期性optimize()或optimize(maxNumSegments);《Lucene in Action》(第二版) Section11 注意:1. 在优化过程中,索引文件很容易占用超过自身文本大小10倍的硬盘空间,因而一定要考虑服务器的资源限制问题!《Lucene in Action》(第二版) Section11 中文本P355 2.字段中必留的三个: uniqueKey:id ,version, … 继续阅读

Solr的主从模式Master-Slave

在做Solr索引的时候,频繁读取数据文件,造成了Linux很大的物理内存分配给了cache, 即使已经设置了NIO模式.况且查询的时候压力也很大, 尤其是facet用shards进行多核查询统计时占用的内存极高. 而且为了避免读写的并发冲突问题可考虑利用主从Master/Slave进行同步操作, 使得读写操作分到不同的服务器上. 关于Solr的Replication机制是这么解释的: The SolrReplicationHandler supports replicating indexes from a “master” used for indexing and “slaves” used for queries. http://wiki.apache.org/solr/SolrReplication It is also neccessary for SolrCloud to function (in Cloud mode, the replication handler is used to … 继续阅读

关于Solr的各种DirectoryFactory

看到一个关于Solr的中文Book网站,介绍的有些简易,不过专注于Solr值得关注:http://www.solrcn.com/books/ 最近快被Solr的Map Failed快弄崩溃了==b,继续调研。。。,还没好。下面从中摘一段关于SolrDirectoryFactory的配置, Apache Lucene 以及 Solr 一个重要的属性是 Lucene 目录实现。目录接口为 Lucene 提供抽象的 IO 操作层。尽管选一个目录实现看起来很简单,但是在极端情况下,它会影响性能。以下将为你讲解如何选择正确的目录实现。 为了使用期望的目录,要做的就是选择正确的目录实现的工厂类,然后告知 solr。假设你打算使用 NRTCachingDirectory 作为你的目录实现,为了实现这个,需要在 solrconfig.xml 中设置以下内容: 这就是所有要做的,很简单,但是有哪些工厂可用呢,在Solr4.2版本中,有以下工厂可用: solr.StandardDirectoryFactory solr.SimpleFSDirectoryFactory solr.NIOFSDirectoryFactory solr.MMapDirectoryFactory solr.NRTCachingDirectoryFactory solr.RAMDirectoryFactory 现在,让我们分别看看每个工厂。 在深入了解每个工厂的细节前,我们先了解一些工厂的配置参数。directoryFactory 的参数一共两个,一个是 name,name 要设置成 “DirectoryFactory”,另外一个是 class,class 设置成我们所选的工厂实现类。 打算让 solr 自行决定使用哪个工厂时,可以使用 solr. StandardDirectoryFactory。该实现是基于文件系统形式的,依赖当前操作系统和 … 继续阅读