用 memcached 实现 Solr Cache

solr 1.3 中使用的 cache 是 LRUCache,可以用 memcached 实现 SolrCache,替换 solr 的默认的 LRUCache。

环境描述:有 N 台 solr 的子机(只提供搜索服务,用户搜索请求负载均衡到这些机器,N > 2),solr 默认缓存是 LRUCache。单台机的内存是有限制的,而且每台机的缓存是独立的,而请求是轮询分布到每台机上,所以缓存会有重复、且会浪费。把每台机的缓存都放到 memcached 中,每台子机共同创建缓存,并且可以分享其它机器创建的缓存,再加上 memcached 容量大,命中率会有提升。

于是,我就想用 memcached 来实现 solr 的 queryresultCache,其实其它 SolrCache 也一样吧。实现的过程,发现 solr 相关的某些类不支持序列化的,所以无法保存到 memcached 中。还是先为 solr 打个 patch 吧。补丁文件 solr-memcache.patch 如:

  1. Index: src/java/org/apache/solr/search/DocSet.java  
  2. ===================================================================  
  3. --- src/java/org/apache/solr/search/DocSet.java (revision 781268)  
  4. +++ src/java/org/apache/solr/search/DocSet.java (working copy)  
  5. @@ -17,6 +17,8 @@  
  6.   
  7.  package org.apache.solr.search;  
  8.   
  9. +import java.io.Serializable;  
  10. + 
  11.  import org.apache.solr.common.SolrException;  
  12.  import org.apache.solr.util.OpenBitSet;  
  13.   
  14. @@ -138,7 +140,7 @@  
  15.  }  
  16.   
  17.  /** A base class that may be usefull for implementing DocSets */  
  18. -abstract class DocSetBase implements DocSet {  
  19. +abstract class DocSetBase implements DocSet, Serializable {  
  20.   
  21.    // Not implemented efficiently... for testing purposes only  
  22.    public boolean equals(Object obj) {  
Index: src/java/org/apache/solr/search/DocSet.java =================================================================== --- src/java/org/apache/solr/search/DocSet.java	(revision 781268) +++ src/java/org/apache/solr/search/DocSet.java	(working copy) @@ -17,6 +17,8 @@   package org.apache.solr.search;  +import java.io.Serializable; +  import org.apache.solr.common.SolrException;  import org.apache.solr.util.OpenBitSet;  @@ -138,7 +140,7 @@  }   /** A base class that may be usefull for implementing DocSets */ -abstract class DocSetBase implements DocSet { +abstract class DocSetBase implements DocSet, Serializable {     // Not implemented efficiently... for testing purposes only    public boolean equals(Object obj) { 

我已经放在 google 项目中,可以下载:http://code.google.com/p/solr-side/issues/detail?id=1&can=1

上面只是先直接看下补丁文件,solr memchached 缓存查询结果的实现也可以在 google 项目中下载:http://solr-side.googlecode.com/files/solr-memcache.zip,全部东西都在这个 zip 里。现讲下怎么用它。

假设已经下载 solr 1.3 并解压到 d:/apache-solr-1.3.0,solr-memcache.zip 解压到 d:/apache-solr-1.3.0/contrib/solr-memcache。

复制 patch-build.xml 和 solr-memcache.patch 到 d:/apache-solr-1.3.0,然后cmd 进入 d:/apache-solr-1.3.0 目录,运行

D:\apache-solr-1.3.0>ant -f patch-build.xml -Dpatch.file=solr-memcache.patch
Buildfile: patch-build.xml

apply-patch:
[patch] patching file src/java/org/apache/solr/search/DocSet.java

BUILD SUCCESSFUL
Total time: 0 seconds

为 solr 1.3 打缓存系列化相关的补丁成功了(ant 为 solr 打补丁的方式请看:http://blog.chenlb.com/2009/02/ant-apply-source-patch-task-demo.html,另一 solr 补丁示例 http://blog.chenlb.com/2009/04/apply-solr-collapsing-patch-remove-duplicate-result.html)。接下来构建 solr 与 solr-memcahce,运行如下:

D:\apache-solr-1.3.0>ant dist
...

现在可以发现已经有 D:\apache-solr-1.3.0\dist\apache-solr-memcache-1.3.0.jar 文件了,同时也有 D:\apache-solr-1.3.0\dist\apache-solr-1.3.0.war 文件(已经打过补丁的)。

把 solr-memcache 安装使用上。把 apapache-solr-memcache-1.3.0.jar 和依赖的 memcached-2.2.jar、spy-2.4.jar(可以在 solr-memcache/lib 下找到) 放到 solr.home/lib 下(我想把它独立没有把它放到 apache-solr-1.3.0.war 里)。

修改 solr.home/conf/solrconfig.xml 配置告诉 solr 怎么使用 Memcached 实现的 Cache。这次实现的目的主要用在 queryresultCache 上。在 solrconfig.xml 的 query 元素内找到 queryresultCache,把原来的注释掉,改如下的:

  1. <!--  
  2. MemcachedCache params:  
  3.   
  4. memcachedHosts (required), "," split.  
  5. name (optional) no default.  
  6. expTime (optional) default 1800 s (= 30 minute)  
  7. defaultPort (optional) default 11211  
  8. keyPrefix (optional) default ""  
  9.   
  10. -->  
  11.   
  12. <queryResultCache  
  13.     class="solr.MemcachedCache"  
  14.     memcachedHosts="192.168.0.100,192.168.0.101:1234,192.168.0.103"  
  15.     expTime="21600"  
  16.     defaultPort="11511"  
  17.     keyPrefix=""/>  
<!-- MemcachedCache params:  memcachedHosts (required), "," split. name (optional) no default. expTime (optional) default 1800 s (= 30 minute) defaultPort (optional) default 11211 keyPrefix (optional) default ""  -->  <queryResultCache 	class="solr.MemcachedCache" 	memcachedHosts="192.168.0.100,192.168.0.101:1234,192.168.0.103" 	expTime="21600" 	defaultPort="11511" 	keyPrefix=""/> 

再在 query 元素内(就在 queryResultCache 下面不远处可以找到类似的 listener )新增加如下内容:

  1. <listener event="newSearcher" class="solr.MemcachedCache" />  
  2. <listener event="firstSearcher" class="solr.MemcachedCache" />  
<listener event="newSearcher" class="solr.MemcachedCache" /> <listener event="firstSearcher" class="solr.MemcachedCache" /> 

用打过补丁的 war 安装到 tomcat (安装可参考:http://blog.chenlb.com/2009/05/apache-solr-quick-start-and-demo.html)。

上面 listener 的内容主要是取得索引版本号。启动运行,效果如下:

solr memcached query result cache,点击放大

solr memcached query result cache,点击放大

 多个子机共用一个 memcached 的确可以提高命中率,在我的实际应用环境中,原来命中率在 10% - 15% 左右,用 solr memcached cache 后,提高到了 58%  左右。不过我没测试过它有多少的性能提升(索引比较大,命中的情况,查询时间是可以减少的),主要用它来提高命中率的。

把它用在 documentCache 也应该可以的(我没测试过,因为我觉得 documentCache 没必要用 memcached 除非网络速度快过磁盘),所有我不建议 documentCache 使用它。

我为了以后升级 solr 方便,已经把 solr memcached 实现提交给 solr 官方 jira 里,并且官方已经接受,准备在 solr 1.5 中实现这个功能。请看:http://issues.apache.org/jira/browse/SOLR-1197

转载于:https://www.cnblogs.com/wycg1984/archive/2009/09/16/1567638.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值