`
yinxiaoman
  • 浏览: 11627 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

扩展 Solr

    博客分类:
  • solr
阅读更多
当你的索引数量越来越大,你会发现你的搜索响应时间变得更慢,索引新内容的时间也会越来越长,那么,到了做出一些改变的时候了,幸运的是,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-ctf-query-parser:使用Clickstream数据重新排名和扩展Solr查询返回

    使用过滤后的点击流数据重新排序和扩展Solr查询返回值,从而提供一个简单,灵活的协作过滤框架。 Clickthroughfilter-xxxjar将过滤器作为Solr / Lucene的查询解析器插件运行。 过滤器(来自单独的clicks核心)对...

    solr扩展词库

    solr扩展词库,共100多万条,供大家下载使用,内容很全

    搜索引擎solr的扩展词库

    电商搜索引擎solr的扩展词库,20W+的专业名词,txt文件;

    php与solr交互扩展库包

    php与solr开源数据库的进行数据交互的扩展包,使用时直接导入到文档中即可

    php 扩展 -- solr-1.0.1

    php 扩展 -- solr-1.0.1,linux系统编译安装

    电商solr用扩展词库商品名称大全关键词库ext.dic

    可做为电商搜索引擎solr的扩展词库,20W+专业名词,txt文件可修改后缀名,不定时更新。

    Apache_Solr_初级教程

    本文介绍的Apache Solr 即是一个基于Lucene 的全文检索服务,通过本文的介绍您将了解到如何安装、使用和 扩展Solr 全文检索服务。

    solr软件包扩展词典可停词配置学习和开发文档

    solr的linux环境安装软件、扩展词典和停词配置,还有学习和开发文档

    solr5.4.0完整包

    Solr 依存于Lucene,因为Solr底层的核心技术是使用Lucene 来实现的,Solr和Lucene的本质区别有以下三点:搜索服务器,企业级和管理。...所以说,一句话概括 Solr: Solr是Lucene面向企业搜索应用的扩展。

    已编译版本solr-8.11.2.tgz

    并对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置,可扩展并对查询性能进行了优化,提供了一个完善的功能管理页面,是一款非常优秀的全文搜索引擎。 3,solr工作方式 文档通过http利用xml加...

    solr可用的3.5万高频英文单词扩展字典

    3.5万的Google大数据高频词库,整理成了solr的扩展字典,下载放入solr服务器,直接用,很方便

    solr-ocrhighlighting:直接在Solr中突出显示各种OCR格式

    它通过扩展Solr的标准UnifiedHighlighter ,支持加载外部字段值并从这些字段值确定OCR位置。 这意味着OCR突出显示也支持UnifiedHighlighter支持的所有选项和查询类型。 该插件还可以与非OCR字段透明地工作,只允许...

    SOLR的应用教程

    1.2.1 Solr使用Lucene并且进行了扩展 4 1.2.2 Schema(模式) 5 1.2.3 查询 5 1.2.4 核心 5 1.2.5 缓存 5 1.2.6 复制 6 1.2.7 管理接口 6 1.3 Solr服务原理 6 1.3.1 索引 6 1.3.2 搜索 7 1.4 源码结构 8 1.4.1 目录...

    全文检索solr7.5.0

    Solr 是Apache下的一个顶级开源项目,采用Java开发,基于Lucene的全文搜索服务器。Solr可以独立运行在Jetty、...并且Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。

    Solr权威指南-上卷

    从完成的结果上来看,我们的目标接近完成,Solr的基础知识、核心技术、进阶知识和扩展知识悉数包括在内。 全书一共16章,分为上下两卷: 上卷(第1~10章) 全面、系统地讲解了Solr的基础知识和核心技术。包括部署、...

    自己动手写搜索引擎(罗刚著).doc

    8.1.14 扩展Solr 277 8.1.15 Solr的.net客户端 285 8.1.16 Solr的php客户端 286 8.2 图片搜索 291 8.2.1 图像的OCR识别 292 8.3 竞价排名 296 8.4 Web图分析 297 8.5 使用并行程序分析数据 302 8.6 RSS搜索 303 8.7 ...

    Solr扩展依赖Jar包

    分词器依赖部分jar包

    solr下载安装教程

    同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。本文为solr下载安装教程

    solr 企业搜索引擎教程

    1.2.1 Solr使用Lucene并且进行了扩展  一个真正的拥有动态域(Dynamic Field)和唯一键(Unique Key)的数据模式(Data Schema)  对 Lucene 查询语言的强大扩展!  支持对结果进行动态的分组和过滤  高级的,可配置...

    solr安装教程,安装包

    本人最近学习了传智播客的一个电商项目...同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎

Global site tag (gtag.js) - Google Analytics