频道栏目
IT货架 > > 正文
用 memcached 实现 Solr Cache
网友分享于:Jun 12, 2018 8:13:43 PM    来源: IT货架   

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 如:

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,把原来的注释掉,改如下的:

<!--
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 )新增加如下内容:

<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

广告服务联系QQ:1134687142 | 网站地图

版权所有: IT货架- 内容来自互联网,仅供用于技术学习,请遵循相关法律法规. 京ICP备11030978号-1