设为首页 收藏本站
查看: 754|回复: 0

[经验分享] Solr之困

[复制链接]

尚未签到

发表于 2015-7-17 11:30:54 | 显示全部楼层 |阅读模式
  http://www.kafka0102.com/2010/08/319.html重写公司的站内搜索。经过前期一段时间对lucene和solr的熟悉,最后决定使用Solr作为新系统的基础框架。现在已经是第一阶段开发的后期,核心代码行数有11000+(不包含admin及client等)。现已实现的功能要比已有系统要丰富些,但综合比较两个系统总的代码量,其实新系统并不多得太多。新系统使用Solr代替了已有系统实现的部分功能,这减少了新系统的代码量,同是新系统实现了已有系统不具有的功能,也增加了一些代码量。开发的这段时间,因为新系统中很多代码是独立于Solr的,所以和Solr的交互也是时断时续,以使得即便到了开发后期我还能发现Solr实现的一些细节带给我的困扰。
  抛开我所做的系统来说,如果要选择一个站内搜索解决方案,Solr在某些场景下可能是个很不错的选择。因为Solr提供了Web server支持通过Http来更新索引、重建索引、查询等功能,如果需求对上Solr,甚至可以不需要基于Solr做二次开发就直接满足需要。多美妙的事情阿。不过,如果你需要些高级功能,那么可能你需要基于Solr做些工作了。比如,如果索引库很大,可以将索引库拆成多个shard,查询时对多个shard进行,这个功能Solr是支持的;不过,建索引的事情就需要自己搞定了,比如在Solr前面加个Proxy(或者只是个库函数),在建索引时根据特定的策略提交到不同的shard上。这个其实也还好了,但如果我需要一个涉及到多个索引库(各索引库有不同的schema)的查询,比如要做整站搜索,那么Solr的shard查询就用不上了,因为它必须要求各shard的schema一致。而我要做的实际是个通用搜索,这样的问题就有些接踵而至了。尽管和Solr磨合的过程花了不少时间,涉及到对它提供的功能、设计、源码的理解等等,并且有时还要妥协它开发,有时还要舍弃它已实现的功能而另起炉灶。但不可否认的是,对于初涉站内搜索开发的我来说,使用Solr并不是太坏的选择,从中也学到了Solr优秀的地方,同时也看到它不足的地方,都是收获。本文会简单的总结下个人在应用Solr过程中一些不是很爽的地方,爽的地方姑且按下不表。
  Solr实现上有个核心东西,就是SolrCore。每个SolrCore对应着一个索引库,几乎所有的操作都是针对单个SolrCore进行的,似乎Solr的初衷就是如此,并没有考虑到多个SolrCore之间的关联。所以,可以看到的是,每个SolrQueryRequest都会关联到一个SolrCore,SolrRequestHandler的获得也是从SolrCore取得的。这糟糕的设计使得,当需要对多个SolrCore做管理时,Solr不得不做出CoreAdminHandler,它虽然实现了SolrRequestHandler接口,但它是脱离于SolrCore的,使得配置上也和其他handler不一样。而Solr的shard查询的支持就更糟糕,它要求shard的SolrCore的schema都是一致的,而不能查询异构的SolrCore。为了解决这个问题,我在Solr基础上加了个VirtualCore(这个概念现在看起来不是很好,或许IndexCore会更好些),VirtualCore里面可以包含一个或多个SolrCore,而很多操作就不是针对SolrCore而是针对VirtualCore了。比如索引库index被拆分成index.0、index.1、index.2,无论索引还是查询,客户端只需要向系统针对core=index进行请求,无需关心index被系统拆分成几个库,这些库被如何分布,系统会通过配置把这些事情做好。对于整站多个库的联合查询,就是针对多个VirtualCore进行,可以通过配置指定各个VirtualCore的请求参数而不需要像Solr那样有严格的约束。
  引入了VirtualCore,使得Solr的一些实现不能得手的使用上。首当其冲的就是它的SearchHandler,我不得不在它的基础上重写了一个,它的shard请求异常处理策略也很有问题,如果shard请求中的某个出现异常,它就不会返回结果,这样做的好处是保证返回结果的全局准确性,但却降低了可用性。这里也需要考虑到查询结果cache的问题,如果在Solr前面加了查询结果Cache,那么Solr这种准确性要求就是有必要的。但在我的实现中,是可以有多少shard返回就处理多少,但在异常的情况下就不做查询结果cache处理。
  VirtualCore也使得Solr强悍的DIH也用不上了,但即便没有VirtualCore,DIH也很难解决单点提交多个shard索引的问题。DIH直接对索引的SolrCore做重建索引处理,并没有对重建索引过程提供灵活的hook(尽管它确实提供了一些hook)。就我的需求来说,我希望每索引一个文档同时会根据一定的策略来更新摘要数据库,我浏览了DIH的文档和代码,似乎很难做到。而且,DIH是直接在现有索引上做重建的,如果重建时间很长或者出现问题,使得同时进来的更新索引被阻塞,就会影响到正常的服务。
  Solr对配置文件的把握上也不够好。Solr对solrconfig.xml文件提供了Java属性值替换配置文件变量,但solr.xml却没有支持,使得线上线下配置文件中充斥着不同的绝对路径。也有好的一方面,比如schema.xml支持Xinclude,使得多个索引库的schema.xml可以共用相同的field type定义。不过,如果多个索引库的schema能集中在一个文件而不是散落成多个文件,管理起来会更方便。这样的问题同时也存在于solrconfig.xml,尽管solrconfig.xml大多数项的配置都是通用的,不过多个索引库时,searcher的warm请求参数可能就会不一样,这使得我在考虑安排时间改写它的默认Lisnter的实现。
  Solr的索引复制有一个细节,那就是master和slave保持长连接,master通过调用OutputStream的flush方法不断把数据发送给slave,如果使用Servlet容器,通过Servlet得到OutputStream这样做没什么问题,但如果使用Netty作为服务器框架,并且使用Netty的http实现,那就实现不了这个效果。这使得我不得不放弃Netty改用Jetty了。
  再回到查询上,Solr的SearchHandler只会得到doc id list,而不会得到需要的所请求的字段内容,它是在ResponseWriter输出时根据doc id从IndexReader得到需要的字段。在我的设计中,索引只会存储逻辑主键id,得到逻辑主键id后再从另外的摘要库把其他字段取回(或者就是返回id列表给客户端),但我显然需要在ResponseWriter输出前做完这些事情,这使得我并不得不修改request需要返回的字段列表为空。而这个ResponseWriter是需要和SolrCore的schema绑定的,结果对于并不存在的VirtualCore,我还不得不使用上配置为空并且没有索引的fake schema蒙混过去。
  还是关于配置,Solr复制slave端配置的master url需要指定参数core,这使得每个SolrCore都有不同的master url而不能共用一个solrconfig.xml,而我真的很希望它们能共用一个solrconfig.xml。其实这个core参数在ReplicationHandler中完全可以得到,Solr没这么做的一个可能的原因是,它支持的请求url格式是http://host/corename/qt?xx=dd,把corename作为url path的一部分让我用起来很不爽,所以我把请求的格式格式改成:http://host/qt?core=aaa&xx=dd,并出下策把Solr和复制相关的代码拷过来,增加了几行代码完事。
  问题当然还有,但就像上面提到的,遇到问题总要找个解决方案,尽管有的方案看起来有些二。在回想上面提到的问题之后,我对现在完成的产出的可用性有些怀疑,我到现在还没有完整的测试过这个系统,所以,它还需要我更仔细的打磨。值得庆幸的是,随着对Solr了解的深入,我能更好的驾驭它了。

==================== 华丽的终止符 ===================

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-87626-1-1.html 上篇帖子: solr 查询 实例分析 下篇帖子: solr高亮的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表