- 浏览: 11949 次
- 性别:
- 来自: 北京
-
最新评论
当你的索引数量越来越大,你会发现你的搜索响应时间变得更慢,索引新内容的时间也会越来越长,那么,到了做出一些改变的时候了,幸运的是,solr很好的考虑到了这些情况,你只需要改变你的配置就可以了。
以下将从三个方面讲述solr的scaling:
l 调优某个Solr服务器(Scale High)
通过缓存和内存管理优化某个单实例的Solr。将Solr部署到一个拥有快速的CPU和硬件的专用服务器,通过调优,最大化的将单个服务器的性能达到最高。
l 使用多Solr服务器(Scale Wide)
使用多Solr服务器。如果你的avgTimePerRequest参数在你可接受的范围内(数据量一般在数百万),那么可以通过配置将你的master上的索引完整地复制到slave机器上;如果你的查询已经很慢,那么使用分片来讲你的单个查询的负载分发到多个Solr服务器上。
l 使用复制(replication)和分片(sharding)(Scale Deep)
当你的数据量足够大,你需要同时使用复制和分片,那么每个分片将对应一个master和若干slave,这将是一个最复杂的架构。
我们将会对三个性能参数进行优化:
l TPS(Transaction Per Second) 每秒事务处理量,可以查看http://localhost:8983/solr/mbtracks/admin/stats.jsp或者查看requesHandler的avgTimePerRequest和avgRequestsPerSecond参数。
l CPU Usage CPU使用情况,在Windows下可以使用PerfMon获得CPU使用的相关信息,而在Unix类操作系统上使用top。
l Memory Usage 内存使用情况,可以使用PrefMon、top和jConsole来查看。
接下来将会介绍对于Solr的scaling。
调优某个Solr服务器(Scale High)
Solr提供了一系列可选的配置来增强性能,具体怎么使用将取决于你的应用程序。下面将对其中最常用的进行介绍
JVM配置
Solr运行在JVM之上,因此对JVM的调优将直接影响Solr的性能,不过对于JVM参数的改变要慎重,因为,很可能一丁点改变会引发很大的问题。
可以在启动的时候指定JVM参数:
java -Xms512M -Xmx1024M -server -jar start.jar
你的Xmx参数应当为你的操作系统以及运行在服务器上的其他进程预留足够的内存,比如你有4G的索引文件,你可以指定6G的RAM(并指定较大的缓存)那么你就能取得比较好的性能。
另外,在可能的情况下,尽量使用版本较高的Java版本,因为新版本的Java虚拟机性能越来越好。
HTTP缓存
因为Solr的许多操作都是基于HTTP的,因此Solr对HTTP缓存有很大的支持。如果你想使用HTTP缓存,那么你需要在solrconfig.xml中做如下配置:
<httpCaching lastModifiedFrom="openTime" etagSeed="Solr" never304="false">
<cacheControl>max-age=43200, must-revalidate</cacheControl>
</httpCaching>
默认情况下,Solr是不使用304 not modified状态给客户端的,而是始终返回200 OK,上面的配置指明max-age是43200秒。下面是例子:
>> curl -v http://localhost:8983/solr/mbartists/select/?q=Smashing+Pumpkins
< HTTP/1.1 200 OK
< Cache-Control: max-age=43200
< Expires: Thu, 11 Jun 2009 15:02:00 GMT
< Last-Modified: Thu, 11 Jun 2009 02:55:39 GMT
< ETag: "YWFkZWIyNjVmODgwMDAwMFNvbHI="
< Content-Type: text/xml; charset=utf-8
< Content-Length: 1488
< Server: Jetty(6.1.3)
很显然,HTTP缓存配置生效了,那么,我们也可以指定If-modified-since参数,这样服务器会比较,如果在最新更改时间之后,那么服务器会返回最新数据。
>>curl -v -z "Thu, 11 Jun 2009 02:55:40 GMT"
http://localhost:8983/solr/mbartists/select/?q=Smashing+Pumpkins
* About to connect() to localhost port 8983 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 8983 (#0)
> GET /solr/mbartists/select/?q=Smashing+Pumpkins HTTP/1.1
> User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3
OpenSSL/0.9.7l zlib/1.2.3
> Host: localhost:8983
> Accept: */*
> If-Modified-Since: Thu, 11 Jun 2009 02:55:40 GMT
>
< HTTP/1.1 304 Not Modified
< Cache-Control: max-age=43200
< Expires: Thu, 11 Jun 2009 15:13:43 GMT
< Last-Modified: Thu, 11 Jun 2009 02:55:39 GMT
< ETag: "YWFkZWIyNjVmODgwMDAwMFNvbHI="
< Server: Jetty(6.1.3)
Entity tag也是一种新的方法来进行鉴别,它比使用last modified date更加的强健和灵活。ETag是一个字符串。在Solr的索引更新以后,当前的ETag会随之改变。
Solr缓存
Solr为缓存使用了LRU算法,缓存存放在内存中,缓存和Index Searcher关联在一起,维持了一个数据的快照(a snapshot view of data).在一个commit之后,新的index searcher打开,并会自动预热(auto-warmed).自动预热指的是之前搜索的缓存会被拷贝到新的searcher。接着,预先在solrconfig.xml中定义的searcher会运行。为那些需要排序的字段(field)加入一些典型的query到newSearcher和firstSearcher,这样,新的searcher就能为新的搜索提供服务了。
Solr1.4使用了FastLRUCache,它比LRUCache要更快,因为它无需单独的线程来移除无用的items。
通过Solr的statistics页面,你可以看到你的缓存有多大,并且可以根据实际情况对缓存的大小进行调整以适应最新的情况。
设计更好的Schema
你需要考虑是否indexed,是否stored等等,这些将决定于你应用程序的具体情况。如果你存储很大的文本到你的索引中,你最好使用field的compressed选项配置对其进行压缩。如果你不是总需要读取所有的fields,那么在solrconfig.xml中配置使用field延迟加载:<enableLazyFieldLoading>true</enableLazyFieldLoading>
这会起到很好的作用。
注意:如果你使用了compressed,那么你可能需要使用field延迟加载,同时还要降低解压缩的代价。另外降低文本分析的数量将有效提高性能,因为文本分析会消耗大量的CPU时间,并且使得你的索引大幅增大。
索引策略
一种加速索引的方式是分批索引,这样将会显著加速性能。但是,随着你的document增加,性能还是会开始下降。根据经验,对于大的document,每批索引10个,而对于小的document,每批索引100个,并分批提交。
另外,使用多线程进行索引将会再次提高性能。
取消document唯一性检查(Disable unique document check)
默认情况下,索引的时候Solr会检查主键是否有重复的,以避免不同的document使用相同的主键。如果你确认你的document不会有重复的主键,将参数allowDups=true加到url上可以取消检查,对于scv文档,使用overwrite=false。
Commit/optimize因子( factors)
对于大的索引以及频繁的更新,使用较大的mergeFactor,它决定了Lucene会在segments数量达到多少时将它们合并(merge)。
优化Faceting(分组查询)的性能
使用Term Vectors
Term Vectors是某field经文本分析之后的一系列terms。它一般包括了term的频率,document的频率和在文本中的数值偏移量,启用它有可能会增强MoreLikeThis查询和Hignlight查询的性能。
但是启用tern vectors会增加索引的大小,并且可能根本不会在MoreLikeThis和Highlight查询结果中。
提升phrase查询的性能
在大索引的查询中,phrase查询的性能会很慢,因为,某个phrase可能会出现在很多的document中,一种解决办法是使用filter过滤掉诸如“the”这样没有意义的词语。但是这样会使得搜索出现歧义,解决方案是使用Shingling,它使用类似n-gram的方法将搜索句子切分,如“The quick brown fox jumped over the lazy dog”将会变为"the quick", "quick brown",
"brown fox", "fox jumped", "jumped over", "over the", "the lazy", "lazy dog".粗糙的测试表明,这样至少可以提高2-3倍的性能。
使用多Solr服务器(Scale wide)
当你对单台Solr服务器的调优仍然无法满足性能需求的时候,接下来你应该考虑拆分查询请求到不同的机器上,具备横向扩展(Scale wide)是可扩展系统的最基本的特点,因此,solr也具备了该特点。
Script VS Java replication
在Solr1.4之前,replication是通过使用Unix脚本进行的。一般来说,这种方案还算不错,但是可能有一些复杂了,需要编写shell脚本,cron jobs和resync daemon。
从1.4开始,Solr实现了基于Java的复制策略,不用再编写复杂的shell脚本,并且运行得更快。
[扩展 Solr - 雪中飞 - 品位人生]
Replication的配置在solrconfig.xml之中,并且配置文件本身可以在master和slave服务器之间被复制。Replication目前已经支持Unix和Windows系统并且已经集成到了Admin interface之中。Admin interface目前可以控制复制---例如,强制开始replication或者终止失效(stalled)的复制。复制是通过ReplicationHandler提供的REST API进行的。
开始体验多Solr服务器
如果你在多个Solr服务器之间使用了同一个solrconfig.xml文件,那么你需要在启动的时候指定以下几个参数:
l -Dslave=disabled:指定当前solr服务器是Master。Master将负责推送索引文件到所有slave服务器。你将会存储document到master上,而在slave服务器上进行查询。
l -Dmaster=disabled:指定当前solr服务器是Slave。Slave要么定期轮询Master服务器来更新索引,要么手动的通过Admin interface触发更新操作。一组slave将会被负载均衡(可能是HAProxy之类)器管理着来对外提供搜索。
如果你想在同一机器上运行多个Solr服务器,那么你需要通过-Djetty.port=8984指定不同的端口,并且通过-Dsolr.data.dir=./solr/data8984指定不同的data目录。
配置Replication
配置replication很简单,在./examples/cores/mbreleases/solrconfig.xml中就有示例配置:
<requestHandler name="/replication" class="solr.ReplicationHandler" >
<lst name="${master:master}">
<str name="replicateAfter">startup</str>
<str name="replicateAfter">commit</str>
<str name="confFiles">stopwords.txt</str>
</lst>
<lst name="${slave:slave}">
<str name="masterUrl">http://localhost:8983/solr/replication</str>
<str name="pollInterval">00:00:60</str>
</lst>
</requestHandler>
注意${}将能够运行期进行配置,它将通过-Dmaster=disabled 或-Dslave=disabled决定这里的参数是master还是slave。Master机器已经配置了在每次commit之后进行replication。并且可通过confFiles属性以指定复制配置文件。复制配置文件非常有用,因为你可以在运行期修改配置而无需重新部署。在master上修改配置文件,replication到slave后,Slave将会知道配置文件被修改了,并reload core。
可以参考http://wiki.apache.org/solr/SolrReplication
Replication的实现
Master是感知不到Slave的存在的,Slave会周期性的轮询Master来查看当前的索引版本。如果Slave发现有新的版本,那么Slave启动复制进程。步骤如下:
1. Slave发出一个filelist命令来收集文件列表。这个命令将返回一系列元数据(size,lastmodified,alias等等)
2. Slave查看它本地是否有这些文件,然后它会开始下载缺失的文件(使用命令filecontent)。如果连接失败,则下载终止。它将重试5次,如果仍然失败则放弃。
3. 文件被下载到了一个临时目录。因此,下载中途出错不会影响到slave。
4. 一个commit命令被ReplicationHandler执行,然后新的索引被加载进来
跨多个Slave的分布式搜索
索引一些文件到Master上
你可以用SSH运行两个session,一个开启Solr服务,另一个索引一些文件:
>> curl http://localhost:8983/solr/mbreleases/update/csv -F f.r_
attributes.split=true -F f.r_event_country.split=true -F f.r_event_
date.split=true -F f.r_attributes.separator=' ' -F f.r_event_country.
separator=' ' -F f.r_event_date.separator=' ' -F commit=true -F stream.
file=/root/examples/9/mb_releases.csv
上面的命令索引了一个csv文件。你可以通过Admin interface监控这个操作。
配置Slave
之前已经索引了文件,并且通过复制已经到了slave上,接下来,需要使用SSH到slave机器上,配置masterUrl如下:
<lst name="${slave:slave}">
<str name="masterUrl">
http://ec2-67-202-19-216.compute-1.amazonaws.com:8983/solr/mbreleases/replication
</str>
<str name="pollInterval">00:00:60</str>
</lst>
你可以到Admin interface上查看当前的replication状况。
[点击查看原始大小图片]
分发搜索请求到不同的Slave上
由于使用了多个Slave,所以我们没有一个固定的请求URl给客户的,因此,我们需要使用负载均衡,这里使用了HAProxy。
在master机器上,配置/etc/haproxy/haproxy.cfg,将你的salve机器的url放入:
listen solr-balancer 0.0.0.0:80
balance roundrobin
option forwardfor
server slave1 ec2-174-129-87-5.compute-1.amazonaws.com:8983
weight 1 maxconn 512 check
server slave2 ec2-67-202-15-128.compute-1.amazonaws.com:8983
weight 1 maxconn 512 check
solr-balancer处理器将会监听80端口,并将根据权重将请求重定向到每个Slave机器,运行
>> service haproxy start
来启动HAProxy。
当然,SolrJ也提供了API来进行负载均衡,LBHttpSolrServer需要客户端知道所有slave机器的地址,并且它没有HAProxy这样的强健,因为它在架构上实现得很简略。可以参考:
http://wiki.apache.org/solr/LBHttpSolrServer
索引分片(Sharding indexes)
Sharding是一种当你的数据太多时很普遍的对单台数据库进行扩展的策略。在Solr中,sharding有两种策略,一是将一个单一的Solr core分成多个Solr服务器,二是将单核的Solr变成多核的。Solr具备将单一的查询请求分发到多个Solr shards上,并聚集结果到一个单一的result里返回调用者。
[扩展 Solr - 雪中飞 - 品位人生]
当你的查询在单台服务器上执行太慢时你就需要组合多台solr服务器的能力来共同完成一个查询。如果你的查询已经足够快了,而你只是想扩展以为更多用户服务,那么建议你使用全索引而使采用replication的方法。
使用Sharding并不是一个完全透明的操作。关键的约束就是当索引一个document,你需要决定它应当在哪个Shards上。Solr对于分布式索引并没有相关的逻辑支持。那么当你搜索的时候你需要加上shards参数到url,以确定需要到哪些shards上收集结果。这意味着客户端需要知道Solr的架构。另外,每个document需要一个唯一的id,因为你是基于行将其拆分的,需要一个id来区分彼此。
分发documents到shards
一种比较好的办法是对id进行hash,在模分片的大小来决定应当分发到哪个shards上:
SHARDS = ['http://ec2-174-129-178-110
.compute-1.amazonaws.com:8983/solr/mbreleases',
'http://ec2-75-101-213-59
.compute-1.amazonaws.com:8983/solr/mbreleases']
unique_id = document[:id]
if unique_id.hash % SHARDS.size == local_thread_id
# index to shard
end
这样,在你的shards不变化的情况下,你的document将会很好的找到它的shards。
跨多个shards搜索(Searching across shards)
这个功能是已经配置在query request handler里面的。因此你无需做额外的配置,如果你想在两个shards上面进行查询,那么你只需要在url跟相关的参数即可:
>> http://[SHARD_1]:8983/solr/select?shards=ec2-174-129-178-110.
compute-1.amazonaws.com:8983/solr/mbreleases,ec2-75-101-213-59.compute-
1.amazonaws.com:8983/solr/mbreleases&indent=true&q=r_a_name:Joplin
注意shards后的参数不能跟http这样的传输协议,并且你可以跟尽量多的shards,只要你不超过GET URL的最大字符数4000.
在使用Shards的时候,请务必注意以下内容:
l Shards仅仅支持以下组件(Component):Query,faceting,Hignlighting,Stats和Debug
l 每个document必须有一个唯一的id。Solr是根据这个来合并搜索结果document的。
l 如果多个shards返回了相同id的document,那么第一个会被选中,而余下的被忽略。
联合使用Replication和Shards(Scale Deep)
如果你使用了前面的方法,仍然发现性能无法满足要求,那么是到了将两个联合起来组成更高层次的架构来达到你的需要的时候了。
[扩展 Solr - 雪中飞 - 品位人生]
你需要使用同样的方法配置一组Master,这样最终你将有一棵树一样的Masters和Slaves。你甚至可以有一个专用的Solr服务器,它没有索引,只负责将查询分发的shards上,并在最后合并结果返回用户。
数据的更新将通过在Master机器上更新并replication到slave机器上实现。前端需要相关的负载均衡支持,但是这样一来,Solr将能够处理极大的数据。
关于Solr的下一步scaling,在Solr的邮件列表里面已经讨论了很多次,一些调查研究显示,Hadoop能够提供强健可靠的文件系统。另一个有趣的项目是ZooKeeper,它将能对分布式系统进行集中式的管理,对于将ZooKeeper集成进来已经有不少努力。
以下将从三个方面讲述solr的scaling:
l 调优某个Solr服务器(Scale High)
通过缓存和内存管理优化某个单实例的Solr。将Solr部署到一个拥有快速的CPU和硬件的专用服务器,通过调优,最大化的将单个服务器的性能达到最高。
l 使用多Solr服务器(Scale Wide)
使用多Solr服务器。如果你的avgTimePerRequest参数在你可接受的范围内(数据量一般在数百万),那么可以通过配置将你的master上的索引完整地复制到slave机器上;如果你的查询已经很慢,那么使用分片来讲你的单个查询的负载分发到多个Solr服务器上。
l 使用复制(replication)和分片(sharding)(Scale Deep)
当你的数据量足够大,你需要同时使用复制和分片,那么每个分片将对应一个master和若干slave,这将是一个最复杂的架构。
我们将会对三个性能参数进行优化:
l TPS(Transaction Per Second) 每秒事务处理量,可以查看http://localhost:8983/solr/mbtracks/admin/stats.jsp或者查看requesHandler的avgTimePerRequest和avgRequestsPerSecond参数。
l CPU Usage CPU使用情况,在Windows下可以使用PerfMon获得CPU使用的相关信息,而在Unix类操作系统上使用top。
l Memory Usage 内存使用情况,可以使用PrefMon、top和jConsole来查看。
接下来将会介绍对于Solr的scaling。
调优某个Solr服务器(Scale High)
Solr提供了一系列可选的配置来增强性能,具体怎么使用将取决于你的应用程序。下面将对其中最常用的进行介绍
JVM配置
Solr运行在JVM之上,因此对JVM的调优将直接影响Solr的性能,不过对于JVM参数的改变要慎重,因为,很可能一丁点改变会引发很大的问题。
可以在启动的时候指定JVM参数:
java -Xms512M -Xmx1024M -server -jar start.jar
你的Xmx参数应当为你的操作系统以及运行在服务器上的其他进程预留足够的内存,比如你有4G的索引文件,你可以指定6G的RAM(并指定较大的缓存)那么你就能取得比较好的性能。
另外,在可能的情况下,尽量使用版本较高的Java版本,因为新版本的Java虚拟机性能越来越好。
HTTP缓存
因为Solr的许多操作都是基于HTTP的,因此Solr对HTTP缓存有很大的支持。如果你想使用HTTP缓存,那么你需要在solrconfig.xml中做如下配置:
<httpCaching lastModifiedFrom="openTime" etagSeed="Solr" never304="false">
<cacheControl>max-age=43200, must-revalidate</cacheControl>
</httpCaching>
默认情况下,Solr是不使用304 not modified状态给客户端的,而是始终返回200 OK,上面的配置指明max-age是43200秒。下面是例子:
>> curl -v http://localhost:8983/solr/mbartists/select/?q=Smashing+Pumpkins
< HTTP/1.1 200 OK
< Cache-Control: max-age=43200
< Expires: Thu, 11 Jun 2009 15:02:00 GMT
< Last-Modified: Thu, 11 Jun 2009 02:55:39 GMT
< ETag: "YWFkZWIyNjVmODgwMDAwMFNvbHI="
< Content-Type: text/xml; charset=utf-8
< Content-Length: 1488
< Server: Jetty(6.1.3)
很显然,HTTP缓存配置生效了,那么,我们也可以指定If-modified-since参数,这样服务器会比较,如果在最新更改时间之后,那么服务器会返回最新数据。
>>curl -v -z "Thu, 11 Jun 2009 02:55:40 GMT"
http://localhost:8983/solr/mbartists/select/?q=Smashing+Pumpkins
* About to connect() to localhost port 8983 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 8983 (#0)
> GET /solr/mbartists/select/?q=Smashing+Pumpkins HTTP/1.1
> User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3
OpenSSL/0.9.7l zlib/1.2.3
> Host: localhost:8983
> Accept: */*
> If-Modified-Since: Thu, 11 Jun 2009 02:55:40 GMT
>
< HTTP/1.1 304 Not Modified
< Cache-Control: max-age=43200
< Expires: Thu, 11 Jun 2009 15:13:43 GMT
< Last-Modified: Thu, 11 Jun 2009 02:55:39 GMT
< ETag: "YWFkZWIyNjVmODgwMDAwMFNvbHI="
< Server: Jetty(6.1.3)
Entity tag也是一种新的方法来进行鉴别,它比使用last modified date更加的强健和灵活。ETag是一个字符串。在Solr的索引更新以后,当前的ETag会随之改变。
Solr缓存
Solr为缓存使用了LRU算法,缓存存放在内存中,缓存和Index Searcher关联在一起,维持了一个数据的快照(a snapshot view of data).在一个commit之后,新的index searcher打开,并会自动预热(auto-warmed).自动预热指的是之前搜索的缓存会被拷贝到新的searcher。接着,预先在solrconfig.xml中定义的searcher会运行。为那些需要排序的字段(field)加入一些典型的query到newSearcher和firstSearcher,这样,新的searcher就能为新的搜索提供服务了。
Solr1.4使用了FastLRUCache,它比LRUCache要更快,因为它无需单独的线程来移除无用的items。
通过Solr的statistics页面,你可以看到你的缓存有多大,并且可以根据实际情况对缓存的大小进行调整以适应最新的情况。
设计更好的Schema
你需要考虑是否indexed,是否stored等等,这些将决定于你应用程序的具体情况。如果你存储很大的文本到你的索引中,你最好使用field的compressed选项配置对其进行压缩。如果你不是总需要读取所有的fields,那么在solrconfig.xml中配置使用field延迟加载:<enableLazyFieldLoading>true</enableLazyFieldLoading>
这会起到很好的作用。
注意:如果你使用了compressed,那么你可能需要使用field延迟加载,同时还要降低解压缩的代价。另外降低文本分析的数量将有效提高性能,因为文本分析会消耗大量的CPU时间,并且使得你的索引大幅增大。
索引策略
一种加速索引的方式是分批索引,这样将会显著加速性能。但是,随着你的document增加,性能还是会开始下降。根据经验,对于大的document,每批索引10个,而对于小的document,每批索引100个,并分批提交。
另外,使用多线程进行索引将会再次提高性能。
取消document唯一性检查(Disable unique document check)
默认情况下,索引的时候Solr会检查主键是否有重复的,以避免不同的document使用相同的主键。如果你确认你的document不会有重复的主键,将参数allowDups=true加到url上可以取消检查,对于scv文档,使用overwrite=false。
Commit/optimize因子( factors)
对于大的索引以及频繁的更新,使用较大的mergeFactor,它决定了Lucene会在segments数量达到多少时将它们合并(merge)。
优化Faceting(分组查询)的性能
使用Term Vectors
Term Vectors是某field经文本分析之后的一系列terms。它一般包括了term的频率,document的频率和在文本中的数值偏移量,启用它有可能会增强MoreLikeThis查询和Hignlight查询的性能。
但是启用tern vectors会增加索引的大小,并且可能根本不会在MoreLikeThis和Highlight查询结果中。
提升phrase查询的性能
在大索引的查询中,phrase查询的性能会很慢,因为,某个phrase可能会出现在很多的document中,一种解决办法是使用filter过滤掉诸如“the”这样没有意义的词语。但是这样会使得搜索出现歧义,解决方案是使用Shingling,它使用类似n-gram的方法将搜索句子切分,如“The quick brown fox jumped over the lazy dog”将会变为"the quick", "quick brown",
"brown fox", "fox jumped", "jumped over", "over the", "the lazy", "lazy dog".粗糙的测试表明,这样至少可以提高2-3倍的性能。
使用多Solr服务器(Scale wide)
当你对单台Solr服务器的调优仍然无法满足性能需求的时候,接下来你应该考虑拆分查询请求到不同的机器上,具备横向扩展(Scale wide)是可扩展系统的最基本的特点,因此,solr也具备了该特点。
Script VS Java replication
在Solr1.4之前,replication是通过使用Unix脚本进行的。一般来说,这种方案还算不错,但是可能有一些复杂了,需要编写shell脚本,cron jobs和resync daemon。
从1.4开始,Solr实现了基于Java的复制策略,不用再编写复杂的shell脚本,并且运行得更快。
[扩展 Solr - 雪中飞 - 品位人生]
Replication的配置在solrconfig.xml之中,并且配置文件本身可以在master和slave服务器之间被复制。Replication目前已经支持Unix和Windows系统并且已经集成到了Admin interface之中。Admin interface目前可以控制复制---例如,强制开始replication或者终止失效(stalled)的复制。复制是通过ReplicationHandler提供的REST API进行的。
开始体验多Solr服务器
如果你在多个Solr服务器之间使用了同一个solrconfig.xml文件,那么你需要在启动的时候指定以下几个参数:
l -Dslave=disabled:指定当前solr服务器是Master。Master将负责推送索引文件到所有slave服务器。你将会存储document到master上,而在slave服务器上进行查询。
l -Dmaster=disabled:指定当前solr服务器是Slave。Slave要么定期轮询Master服务器来更新索引,要么手动的通过Admin interface触发更新操作。一组slave将会被负载均衡(可能是HAProxy之类)器管理着来对外提供搜索。
如果你想在同一机器上运行多个Solr服务器,那么你需要通过-Djetty.port=8984指定不同的端口,并且通过-Dsolr.data.dir=./solr/data8984指定不同的data目录。
配置Replication
配置replication很简单,在./examples/cores/mbreleases/solrconfig.xml中就有示例配置:
<requestHandler name="/replication" class="solr.ReplicationHandler" >
<lst name="${master:master}">
<str name="replicateAfter">startup</str>
<str name="replicateAfter">commit</str>
<str name="confFiles">stopwords.txt</str>
</lst>
<lst name="${slave:slave}">
<str name="masterUrl">http://localhost:8983/solr/replication</str>
<str name="pollInterval">00:00:60</str>
</lst>
</requestHandler>
注意${}将能够运行期进行配置,它将通过-Dmaster=disabled 或-Dslave=disabled决定这里的参数是master还是slave。Master机器已经配置了在每次commit之后进行replication。并且可通过confFiles属性以指定复制配置文件。复制配置文件非常有用,因为你可以在运行期修改配置而无需重新部署。在master上修改配置文件,replication到slave后,Slave将会知道配置文件被修改了,并reload core。
可以参考http://wiki.apache.org/solr/SolrReplication
Replication的实现
Master是感知不到Slave的存在的,Slave会周期性的轮询Master来查看当前的索引版本。如果Slave发现有新的版本,那么Slave启动复制进程。步骤如下:
1. Slave发出一个filelist命令来收集文件列表。这个命令将返回一系列元数据(size,lastmodified,alias等等)
2. Slave查看它本地是否有这些文件,然后它会开始下载缺失的文件(使用命令filecontent)。如果连接失败,则下载终止。它将重试5次,如果仍然失败则放弃。
3. 文件被下载到了一个临时目录。因此,下载中途出错不会影响到slave。
4. 一个commit命令被ReplicationHandler执行,然后新的索引被加载进来
跨多个Slave的分布式搜索
索引一些文件到Master上
你可以用SSH运行两个session,一个开启Solr服务,另一个索引一些文件:
>> curl http://localhost:8983/solr/mbreleases/update/csv -F f.r_
attributes.split=true -F f.r_event_country.split=true -F f.r_event_
date.split=true -F f.r_attributes.separator=' ' -F f.r_event_country.
separator=' ' -F f.r_event_date.separator=' ' -F commit=true -F stream.
file=/root/examples/9/mb_releases.csv
上面的命令索引了一个csv文件。你可以通过Admin interface监控这个操作。
配置Slave
之前已经索引了文件,并且通过复制已经到了slave上,接下来,需要使用SSH到slave机器上,配置masterUrl如下:
<lst name="${slave:slave}">
<str name="masterUrl">
http://ec2-67-202-19-216.compute-1.amazonaws.com:8983/solr/mbreleases/replication
</str>
<str name="pollInterval">00:00:60</str>
</lst>
你可以到Admin interface上查看当前的replication状况。
[点击查看原始大小图片]
分发搜索请求到不同的Slave上
由于使用了多个Slave,所以我们没有一个固定的请求URl给客户的,因此,我们需要使用负载均衡,这里使用了HAProxy。
在master机器上,配置/etc/haproxy/haproxy.cfg,将你的salve机器的url放入:
listen solr-balancer 0.0.0.0:80
balance roundrobin
option forwardfor
server slave1 ec2-174-129-87-5.compute-1.amazonaws.com:8983
weight 1 maxconn 512 check
server slave2 ec2-67-202-15-128.compute-1.amazonaws.com:8983
weight 1 maxconn 512 check
solr-balancer处理器将会监听80端口,并将根据权重将请求重定向到每个Slave机器,运行
>> service haproxy start
来启动HAProxy。
当然,SolrJ也提供了API来进行负载均衡,LBHttpSolrServer需要客户端知道所有slave机器的地址,并且它没有HAProxy这样的强健,因为它在架构上实现得很简略。可以参考:
http://wiki.apache.org/solr/LBHttpSolrServer
索引分片(Sharding indexes)
Sharding是一种当你的数据太多时很普遍的对单台数据库进行扩展的策略。在Solr中,sharding有两种策略,一是将一个单一的Solr core分成多个Solr服务器,二是将单核的Solr变成多核的。Solr具备将单一的查询请求分发到多个Solr shards上,并聚集结果到一个单一的result里返回调用者。
[扩展 Solr - 雪中飞 - 品位人生]
当你的查询在单台服务器上执行太慢时你就需要组合多台solr服务器的能力来共同完成一个查询。如果你的查询已经足够快了,而你只是想扩展以为更多用户服务,那么建议你使用全索引而使采用replication的方法。
使用Sharding并不是一个完全透明的操作。关键的约束就是当索引一个document,你需要决定它应当在哪个Shards上。Solr对于分布式索引并没有相关的逻辑支持。那么当你搜索的时候你需要加上shards参数到url,以确定需要到哪些shards上收集结果。这意味着客户端需要知道Solr的架构。另外,每个document需要一个唯一的id,因为你是基于行将其拆分的,需要一个id来区分彼此。
分发documents到shards
一种比较好的办法是对id进行hash,在模分片的大小来决定应当分发到哪个shards上:
SHARDS = ['http://ec2-174-129-178-110
.compute-1.amazonaws.com:8983/solr/mbreleases',
'http://ec2-75-101-213-59
.compute-1.amazonaws.com:8983/solr/mbreleases']
unique_id = document[:id]
if unique_id.hash % SHARDS.size == local_thread_id
# index to shard
end
这样,在你的shards不变化的情况下,你的document将会很好的找到它的shards。
跨多个shards搜索(Searching across shards)
这个功能是已经配置在query request handler里面的。因此你无需做额外的配置,如果你想在两个shards上面进行查询,那么你只需要在url跟相关的参数即可:
>> http://[SHARD_1]:8983/solr/select?shards=ec2-174-129-178-110.
compute-1.amazonaws.com:8983/solr/mbreleases,ec2-75-101-213-59.compute-
1.amazonaws.com:8983/solr/mbreleases&indent=true&q=r_a_name:Joplin
注意shards后的参数不能跟http这样的传输协议,并且你可以跟尽量多的shards,只要你不超过GET URL的最大字符数4000.
在使用Shards的时候,请务必注意以下内容:
l Shards仅仅支持以下组件(Component):Query,faceting,Hignlighting,Stats和Debug
l 每个document必须有一个唯一的id。Solr是根据这个来合并搜索结果document的。
l 如果多个shards返回了相同id的document,那么第一个会被选中,而余下的被忽略。
联合使用Replication和Shards(Scale Deep)
如果你使用了前面的方法,仍然发现性能无法满足要求,那么是到了将两个联合起来组成更高层次的架构来达到你的需要的时候了。
[扩展 Solr - 雪中飞 - 品位人生]
你需要使用同样的方法配置一组Master,这样最终你将有一棵树一样的Masters和Slaves。你甚至可以有一个专用的Solr服务器,它没有索引,只负责将查询分发的shards上,并在最后合并结果返回用户。
数据的更新将通过在Master机器上更新并replication到slave机器上实现。前端需要相关的负载均衡支持,但是这样一来,Solr将能够处理极大的数据。
关于Solr的下一步scaling,在Solr的邮件列表里面已经讨论了很多次,一些调查研究显示,Hadoop能够提供强健可靠的文件系统。另一个有趣的项目是ZooKeeper,它将能对分布式系统进行集中式的管理,对于将ZooKeeper集成进来已经有不少努力。
相关推荐
**PHP扩展Solr-1.0.1:Linux系统下的编译与安装指南** PHP扩展Solr是PHP与Apache Solr搜索引擎之间的桥梁,它允许PHP应用程序无缝地与Solr服务器进行交互,执行搜索、索引操作等。在Linux环境下安装这个扩展,需要...
Solr Redis 扩展Solr Redis 扩展此扩展是一个 ParserPlugin,它根据存储在 Redis 中的数据提供 Solr 查询解析器。RedisQParserPlugin 与 Redis 创建连接并将连接对象传递给负责获取数据和构建查询的 RedisQParser。...
使用过滤后的点击流数据重新排序和扩展Solr查询返回值,从而提供一个简单,灵活的协作过滤框架。 Clickthroughfilter-xxxjar将过滤器作为Solr / Lucene的查询解析器插件运行。 过滤器(来自单独的clicks核心)对...
7. **contrib 目录**:包含了一些社区贡献的模块,如数据分析器、搜索组件和请求处理器等,这些可以扩展Solr的功能。 在Solr 8.11.1版本中,可能包含以下特性: - **性能优化**:Solr团队不断努力提升查询速度和...
1.2.1 Solr使用Lucene并且进行了扩展 Solr基于Apache Lucene,它提供了更高级的功能,如集群、分布式搜索、复制和负载均衡,使得Solr更适合大规模、高并发的搜索应用。 1.2.2 Schema(模式) Schema是Solr的核心...
同时,书中也介绍了如何通过扩展Solr的功能,例如使用插件或自定义代码来实现特定的搜索需求。 最后,《Solr In Action》书籍中的例子和最佳实践将引导读者完成一系列实际项目,从建立索引到执行搜索查询,再到后续...
通过这个"solr demo",你不仅能够掌握Solr的基本操作,还能深入理解其内部机制,这对于进一步优化和扩展Solr应用程序至关重要。无论你是初学者还是有经验的开发者,这个例子都能提供宝贵的学习材料,帮助你在全文...
这个压缩包"solr 4-10.3 工具包 包含工程jar包"显然包含了Solr 4.10.3版本的相关组件和库,这对于开发者来说是极其宝贵的资源,特别是那些在Java环境下工作并需要构建或扩展Solr应用的人。 Solr 4.10.3是一个重要的...
- 可以通过编写插件扩展Solr的功能,如自定义分析器、查询处理器等。 总之,Apache Solr 8.1.1是一款强大的全文搜索引擎,特别适合Windows系统的部署,提供了丰富的搜索功能和高度可定制性,广泛应用于各种需要...
通过分析这个源码包,开发者可以学习到如何配置和扩展Solr,理解Solr内部的工作流程,例如请求处理、查询解析、索引构建和优化、以及集群管理等。此外,对于想要为Solr贡献代码的开发者,源码包也是一个宝贵的资源,...
这意味着随着业务需求的增长,可以通过简单地增加更多的服务器来扩展Solr的能力,无需重构或重新设计系统。 **1.2 开箱即用** - **开源性质:** 作为一个开源项目,Solr不仅免费,而且易于获取和部署。 - **预配置...
- **灵活的插件机制**:允许用户通过插件的方式轻松扩展Solr的功能。 - **强大的数据导入能力**:Solr具备将来自不同数据源(如数据库)的数据导入并转换为索引的能力。 #### 二、Solr与Lucene的关系 - **Solr和...
这些文件是Solr 8.9.0版本的DIH组件,用于扩展Solr的核心功能,使得数据导入过程更加灵活和高效。 1. **Solr DataImportHandler (DIH):** DIH是一个Solr插件,它提供了一个框架,允许用户通过简单的配置从关系型...
本手册还包括了关于如何扩展Solr的指导,包括如何添加自定义组件,以支持更复杂的数据模型和搜索需求。它也提供了关于监控和调试Solr集群的建议,这对于保证搜索服务的高可用性和故障排查有重要意义。 手册的最后一...
5. 高级Solr应用:包括如何扩展Solr/SolrCloud、实现多语言搜索、执行复杂数据操作、相关性调整和创造性思维等高级主题。 6. 附录部分提供了从源代码构建Solr以及与Solr社区合作的指导。 Solr的特性使它非常适合于...
#### 扩展Solr - **水平扩展**:讨论如何通过增加节点来提高Solr的处理能力和可用性。 - **垂直扩展**:介绍通过升级单个节点硬件来提升性能的方法。 #### 复杂数据操作 - **多值字段处理**:讲解如何有效地存储和...
- **插件开发**:可以通过编写自定义请求处理器、过滤器和查询解析器等插件,扩展Solr的功能。 5. **实战应用** - **搜索建议与拼写纠错**:利用Solr的自动完成和拼写检查功能,提升用户体验。 - **多语言支持**...
源码中包含的插件框架展示了如何扩展Solr的功能。 8. **性能优化**:通过源码,你可以看到Solr如何优化内存使用、并发控制和缓存策略,这对于提升系统的吞吐量和响应速度至关重要。 9. **二次开发**:如果你计划对...
- 扩展Solr/Solr云:探讨了如何将Solr扩展至分布式系统,以及Solr Cloud的原理和使用。 - 多语言搜索:介绍Solr如何支持多语言搜索,包括翻译和语言分析等。 - 复杂数据操作:涉及到如何处理复杂的数据结构,包括...
标题中的“php与solr交互扩展库包”指的是PHP与Apache Solr搜索引擎之间的一个扩展库,这个库使得在PHP环境中可以方便地与Solr服务进行数据的增删查改操作。Solr是一款强大的、高性能的全文检索服务器,常用于大型...