1.1 Solr到底是什么?
在本节中,我们通过从头设计一个搜索应用来介绍Solr的关键组件。这个过程将有助于你理解Solr的功能,以及设计这些功能的初衷。不过在我们开始介绍Solr的功能特性之前,还是要先澄清一下Solr并不具有的一些性质:
1) Solr并不是一个像Google或是Bing那样的web搜索引擎
2) Solr和网站优化中经常提到的搜索引擎SEO优化没有任何关系
好了,现在假设我们准备为潜在的购房客户设计一个不动产搜索的网络应用。该应用的核心用例场景是通过网页浏览器来搜索全美国范围内的房子。图1.1描述了这个虚拟应用的界面截图。不用太在意UI界面的简陋,这只是一个便于我们讨论的可视化模型。重点是通过这个例子,我们来看看Solr到底可以提供哪些类型的搜索体验。
让我们先快速浏览一下图1.1描绘了哪些Solr的关键特性。我们从左上角开始,沿顺时针方向看。首先,Solr提供了强大的功能来支持关键字搜索框。正如我们在1.1.2中讨论的那样,一个表现出色的关键字搜索功能,需要背后强大的复杂架构的支持。好在Solr所提供的这个复杂架构可以迅速的安装使用。具体来说,Solr提供了拼写检查功能、用户输入的自动补全建议功能、同义词近义词处理功能、短语查询功能、以及用于处理类似”buying a house“和”purchase a home“这样的语言变异的文本分析功能。
此外Solr也提供了强大的地理位置查询功能。在图1.1中,符合查询条件的房屋列表在地图上按照与指定坐标点中心的经纬度距离的远近显示出来。依靠Solr的地理位置支持,你可以根据地理位置的距离来进行查询,甚至可以依据地理位置的远近对文档结果进行排序。对于地理位置查询来说,快速地返回搜索结果,以及允许用户通过在地图上缩放或移动地图上的位置来进行新的查询,这些功能都很重要。
一旦用户发起了一个查询,其查询结果就可以依靠Solr的分类检索功能来按照结果文档集的不同特性进行分类显示,这样更便于用户浏览搜索返回的结果。分类检索是一种将结果集按特性分类显示的方法,可以帮助用户进一步的细化查询已获得更加符合自己需求的信息。在图1.1中,查询结果按照房屋特征,房型和目录类型进行了分类显示。
现在我们对于房地产查询应用应该支持哪些功能有了一个基本的了解,接下来我们来看看如何利用Solr来实现这些功能特性。首先我们需要弄清楚Solr是怎么在索引中的房屋列表和用户的查询之间进行匹配的,这一原理也是所有搜索应用的基础。
1.1.1 信息检索引擎
Solr是在Apache 下大名鼎鼎的Java开源信息检索库Lucene的基础之上开发出来的。在第三章中会详细讨论什么是信息检索。现在我们先看看一篇关于现代搜索引擎概念的权威学术论文是如何定义信息检索的,从中我们可以了解到一些关键的概念:
信息检索(IR)是指从海量的数据集合(通常存储在计算机系统中)中,根据某种非结构化的本质属性(通常是文本内容)查找出满足信息需求的材料(通常是文档) 的过程。 ---摘自信息检索简介,曼宁出版社2008年出版
在我们的房地产搜索应用中,用户的主要信息需求是根据地段、房型、房屋功能特性、还有价格这些因素来查找要购买的房子。我们的索引包含了全美所有的房源,绝对算的上是“海量“数据了。 简而言之,Solr利用Lucene提供的核心架构,对文档建立索引,处理查询请求,实现文档的搜索功能。
Lucene底层用JAVA实现倒排索引的建立和管理。倒排索引即倒排表,是用于匹配文本查询的特殊数据结构。图1.2展示了我们的房地产搜索应用中所用的到的Lucene 倒排索引的简要示意图。
在第三章中你将详细地学习到倒排索引是如何工作的。但是现在看懂图1.2中的内容就足够了。这里展现的是一条新的文档记录(图中的第44号记录)加入到索引文件中的过程,以及文档是如何通过倒排索引进行查询匹配的过程。
你也许在想,这不是利用关系型数据库中的SQL语句也能做到吗?对于这个简单的例子来说是这样的。但是Lucene索引查询和数据库查询的一个关键区别是:在Lucene中,查询结果是按照与查询的匹配程度排序的,而数据库查询的结果则只能根据数据表中的某一列属性进行排序。换句话说,依据相关性对结果进行排序是信息检索的一个关键特性,也是区别于其他查询的重要特征。
-建立全网数据的倒排索引
你也许会感觉到惊讶,因为像Google那样的搜索引擎也是利用倒排索引来查询网页的。事实上,建立全网数据的倒排索引的需求,直接导致了MapReduce技术的产生。
MApReduce是一个编程模型,通过Map和reduce两个阶段,将大规模的数据处理操作分配到商用机服务器集群上去,实现分布式运行。Google利用MapReduce技术来建立其巨大的倒排索引,用以支撑网络查询的需求。在使用MapReduce技术时,先在Map阶段生成一系列的数据段并在所有数据段出现的地方标上该数据段唯一的文档ID。在Reduce阶段,所有数据段会做排序,拥有相同文档ID的数据段会被发送到同一个reducer进行处理,这样reducer会加和所有拥有同一文档ID的数据段,为之建立倒排索引。
Apache的Hadoop项目就提供了一个开源的Mapreduce实现,并且Apache Nutch开源项目就是用Hadoop来为全网数据的查询建立Lucene倒排索引。关于Haddop和Nutch的讨论超出了本书的范围,不过我们建议读者不妨去研究一下这些开源项目,会对你建立大规模的搜索索引有帮助的。
现在我们知道了Lucene为搜索提供了核心的架构,那么让我们看看Solr在Lucene之上又附加了哪些价值。我们从使用Solr灵活的schema.xml配置文件来管理索引建立的方式开始。
1.1.2 灵活的Schema管理
虽然Lucene提供了建立文档索引和执行查询的核心架构, 但它并没有提供一个方便的接口来设置索引应该如何建立。要使用Lucene,你需要写一些JAVA代码来定义值域,还要定义如何分析这些值域。而Solr则提供了简单的声明方式来定义索引的结构,你也可以按照需求来指定如何分析索引中的值域。这一切都可以通过一个名叫schema.xml的XML配置文件来完成。Solr在其底层实现中将schema.xml中的配置翻译成Lucene的index。这种方式节省了你编程的时间,也使得你的索引结构更加可读。另外一方面,Solr建立的索引与编程实现的Lucene索引是百分之一百兼容的。
此外Solr在核心的Lucene索引功能之上还添加了其他一些不错的功能。具体来说,Solr提供了Copy Fields和Dynamic Fields两种新的值域类型。Copy Fields提供了一种方法,可以将一个或多个值域中的原始文本内容赋值到另一个新的field值域中。Dynamic Fields则允许你无须在schema.xml里显式的声明,就可以将同一值域类型赋予多个不同的值域。这在为拥有多个值域的文档建立模型时非常有用。我们将在第五章和第六章中深入介绍schema.xml文件。
在我们的房地产搜索应用中,你可能会惊讶于我们没对Solr的示例schema.xml做任何修改就直接使用了。这其实恰好展示了Solr的schema配置是多么的灵活,应为Solr的示例schem是为产品搜索设计的,但是我们的房地产搜索应用拿过来一样可以直接使用。
到目前为止,我们知道了Lucene提供了强大的搜索库,用以支持文档索引的建立,执行查询,以及对结果进行排序。还有,利用schema.xml,你可以灵活的定义索引结构,只需要修改XML配置即可,不需要针对LuceneAPI进行编程。 接下来你需要能够通过网络来获取这些服务。所以在下一节,我们就来学习Solr作为Java web应用是如何运行的,以及她是如何通过XML,JSON,HTTP等标准技术来与其他系统集成在一起的。
1.1.3 Java web应用
Solr作为一个Java web应用,既可以运行在任意一个现代JAVA Servlet引擎之上,比如Jetty或是Tomcat,也可以运行在JBoss或是Oracle AS之类的完整的J2EE应用服务器上。图1.3展示了Solr服务器的主要软件模块。
图1.3可能在第一眼看上去时显得内容有点多。我们可以花点时间先过一遍,先熟悉熟悉名词和术语。如果有看不懂的术语或是概念也不用担心,等你读完本书的时候,图1.3中的所有概念和术语你都会有很深的理解。
正如我们在本章开头介绍中所提到的那样, Solr的设计者们指出Solr非常适合集成到现有的系统中,作为现有系统的一个有力补充。事实上,你很难找出一个Solr无法集成进去的系统。正如我们将在第二章里看到的那样,你在下载Solr之后只需要花上几分钟,就可以启动一个示例的Solr系统了。
为了达到易于集成的目标,Solr的核心服务需要能够被不同的应用和编程语言访问。Solr提供简单的类REST服务,支持XML,JSON,HTTP等标准。顺便说一句,我们并不使用RESTFul一词来描述Solr基于HTTP的 API,因为它 并不严格遵守所有的REST(Representatonal state transfer)原则。例如,在Solr中会用到HTTP POST来删除文档,而不是用HTTP DELETE。
类REST的接口对于基本功能来说已经足够好用了,但是开发者们经常会希望能够用自己熟悉的编程语言来编写一些调用网络服务和处理返回的模版化工具。好消息是针对许多流行的编程语言,Solr都提供了相应的库,包括Python, JAVA, .NET, 还有Ruby等等。
1.1.4 同一服务器上建立多份索引
现代软件应用架构的一个显著特点就是面对快速变化的需求的灵活性。Solr在这方面有个很有用的特性,就是你不必只通过一份单一的索引来完成Solr中所有的任务。Solr支持在单一的Solr 引擎上运行多个Solr 核心。在图1.3中, 我们描述了多个solr核心在同一个Java web应用环境中作为不同的层同时运行的场景。
每一个核心都有一个独立的索引和配置,在一个Solr实例中可以存在多个Solr 核心。这样你只需要一个Solr服务器就可以管理多个核心, 可以方便的实现服务器资源共享,以及及监控维护服务的共享。Solr有专门的API用于创建和管理多个Core。
Solr多核心支持功能的一个应用是数据分区,比如用一个core来负责最近更新的文档,而用另外的core来处理之前生成的文档,这个功能被称为按时间顺序分片。
在我们的房地产搜索应用中,我们也可以使用多个core来分别处理不同的类型的房屋资源,每一类用一个单独的索引文件来管理。比如说针对农村用地的房地产信息来说,买一块农业用地的流程和买一套商品房的流程是不同的,我们完全可以用一个单独的索引来管理农业用地的相关信息,将其保存在一个单独的core里。
1.1.5 可扩展性(通过插件扩展功能)
图1.3展示了Solr种最主要的三个子系统:文档管理,查询处理,和文本分析。当然,这些子系统是对Solr中复杂的子系统所做的宏观抽象,我们会在稍后的章节中一一研究这些子系统。这其中的每一个都是由一系列功能模块的流水线串成的,你可以在流水线中串入新的功能模块。这意味着如果你想给solr加入新的功能的话,根本不需要重写整个查询处理引擎,只需要在合适的位置串入自己的新功能模块即可。这样一来Solr的核心功能模块扩展和定制起来都很方便,可以完全按照你的特定应用需求进行定制。
1.1.6 可伸缩性
Lucene是一个查询速度非常快的搜索库,而Solr完全发挥出了Lucene的强劲性能。
但是抛开Lucene的性能不谈,作为一个服务器来说,由于CPU和I/O的限制,同一时刻能够响应的用户数和请求数都是有限制的。
Solr实现可伸缩性的第一张牌是灵活的cache管理功能。该功能可以避免服务器重复进行耗费资源的操作。具体来说就是Solr预先设置了一些cache来节省开销很大的重复计算,比如Solr会缓存查询过滤器的计算结果。我们会在第四章学习Solr的缓存管理功能。
缓存的作用是有限的,为了处理更多的文档和获得更高的查询吞吐能力,你需要能够通过扩展服务器来横向扩展系统的性能。现在我们来研究一下Solr扩展时最常见的两个方面。第一个是查询的吞吐能力扩展,也就是你的引擎每秒钟可以处理的最大查询数是多少。虽然Lucene可以非常快的处理每一个查询请求,单台服务能够同时并发处理的请求出还是会限制整体的查询吞吐能力。如果需要得到更高的查询吞吐能力,你需要增加查询服务器和索引的拷贝数量,以便让更多的服务器来同时处理更多的请求。这意味着如果你的索引复制到了三台服务器上,那么你每秒钟大约可以处理原来三倍的请求数量,因为每台服务器现在的负荷是总的查询量的三分之一。在实际应用中很少能够获得如此完美的现行扩展能力,所以使用三台服务器可能大约能达到原来2.5倍左右的性能。
另一个扩展维度是被索引的文档数。如果你正在处理海量的文档, 那么当单个Solr实例中索引的文件数量多到一定程度的时候,查询性能的瓶颈也会出现。解决的方案是可以把索引文件切分成一个个被称为“分片”的小块,然后把查询请求分布到这些分片上进行操作。
使用虚拟化的商用硬件进行扩展
现代计算机技术的一个趋势就是构建可以在虚拟化的商用硬件上进行横向扩展的软件架构。简单来说,就是可以通过添加普通的商用机服务器就可以处理更多的流量。类似于Amazon EC2这样的云计算服务提供商通过使用虚拟化的商用硬件来满足这种趋势的需求。虽然Solr可以再虚拟化硬件上运行,但是需要注意的是Solr对于I/O和内存很敏感。因此,如果在你的企业中搜索性能被放到了最高优先级来考虑,那你应该考虑在配备有高性能磁盘(比如SSD固态硬盘)的高端硬件上去部署Solr。部署Solr时硬件方面需要考虑的问题将会在第13章中进行讨论。
可伸缩性很重要,但是出错后的自动恢复能力在现代系统中也很重要。在下一节中,我们来讨论一下Solr是如何处理软件和硬件中的错误的。
转载请注明原文出处http://my.oschina.net/fengnote
1.1.7 容错性
除了可伸缩性,我们还需要考虑如果当server中的一个或多个出了问题时应该怎么处理。尤其是你准备把Solr部署到虚拟化的商用硬件上时更要考虑这个问题。最低的要求是你至少要打算去处理这些错误。即便是使用高端的硬件配上最优秀的架构,错误还是会发生的。
我们假定你的系统中一共有4个分片的情况。如果2号分片所在的服务器断电了,那么此时Solr就不能继续正常的建立文档索引了,也不能响应查询服务了。所以这个时候可以说,你的搜索引擎就算“挂掉了”。要避免这种情况,你可以给每一个分片做备份。回到我们的这个例子中,当2号分片挂掉时,Solr会把所有指向2号分片的索引建立请求和查询请求重定向到它的备份哪儿,备份这个时候并没有挂掉,还能正常工作, 所以整个搜索服务还在。出错所产生后索引服务和查询服务仍然可以工作,不过可能不会像之前那么快了,因为少了一台服务器来处理请求。我们会在第16章中更详细的讨论各种故障情况。
到此为止,你已经看到了Solr具有一个设计良好地现代软件架构,可以很好地做横向扩展以及处理容错。虽然这些在你决定使用solr之后都是必须要考虑的重要因素,但是你可能还是没有很坚定Solr到底是不是你的正确选择。在下一节中,我们会站在公司不同角色的角度来看看Solr到底能够给自己带来什么好处,包括软件架构师,系统管理员,和公司的CEO。
1.2 为什么选用Solr?
在本节中,我们希望可以提供一些关键信息来帮助于你判断Solr是否是贵公司技术方案的正确选择。我们先从Solr吸引软件架构师的方面说起。
2.1 软件架构师眼中的Solr
在评估一项新技术时,软件架构师必须要考虑一系列的因素,其中就包括系统的稳定性,可伸缩性,还有容错性。Solr在这三方面的得分都很不错。
说到稳定性,Solr是一个由活跃的开源社区和经验丰富的代码提交者共同维护的一项成熟技术。Solr和Lucene的新用户们通常会惊讶于项目的发布方式,可能他们以前都是等待某个项目的官方Release版,没听说过这种从分支上直接pull下来的方式。不管你的公司是否接受这种方式,我们并不是建议你这么做,我们想表明的是,Lucene和Solr项目中自动测试模块的测试深度和宽度是值得信任的。简单来说,如果你从分支上拿到了一个nightly build,如果所有的自动测试都能通过,那你就可以放心的肯定所有的核心功能都是ok的了。
我们在1.2.6节中已经接触到了Solr实现可伸缩性扩展的方法,在1.2.7节中也讨论了容错性的问题。作为一个架构师,你可能最好奇的是Solr的可伸缩性功能和容错性功能的局限到底在哪里。首先,你需要知道在Solr4中,分片功能和复制备份功能都被重写了,在鲁棒性和易于管理方面都有很大提高。新的扩展方式被称为SolrCloud。其底层实现上,SolrCloud使用了Apache ZooKeeper来管理Solr集群上的配置同步,并监控集群的运行状态。这里列出了一些Solr全新的SolrCloud功能的亮点:
转载请注明原文出处http://my.oschina.net/fengnote
·中心化的配置
·分布式的索引,避免单点失败(SPoF)
·自动容错,自动产生新的主分片
·任意节点均可触发覆盖整个集群所有分片的分布式全查询,且已经集成了自动容错和负载均衡
但是这并不是说Solr的可伸缩性就没有提高的空间了。SolrCloud在两方面还有待提高。首先,不是所有功能都能工作在分布式模式下。比如 joins连接功能。其次,一旦索引建立,索引的分片数目就不能再动态调整,要想改变分片数的话只能重新对所有文档建立索引。我们在第16章会详细讨论SolrCloud的方方面面,但是我们希望确保软件架构师们能够意识到Solr的可伸缩性过去几年中已经走过了很长的路,而且今后还将继续不断地改进下去。
2.2 系统管理员眼中的Solr
作为一名系统管理员,在考虑开始使用像Solr这样的一种新技术时,最优先考虑的是新技术是否能够很好地和已有系统进行配合。对于Solr来说对这个问题可以很轻松的回答YES。Solr 完全是基于JAVA开发的,可以在任意一个装有J2SE 6.x/7.x JVM虚拟机的操作系统上运行。而且Solr还自带了Oracle提供的开源Java Servlet引擎Jetty,拿来就能用。另一方面,Solr是一个标准的Java Web应用,可以很方便的在JBoss或是Oracle AS之类的Java web应用服务器上进行部署。
对Solr的所有操作都可以通过HTTP请求来完成, 并且Solr在设计时就考虑到了同Squid或是Varnish这样的HTTP反向代理协同工作。Solr同时也支持JMX,所以你可以把Solr挂载到你喜欢的监控程序(比如Nagios)之下进行监控。
最后,Solr提供了一个不错的管理控制台, 可以用于检查配置,查看统计信息,发起测试查询,以及监控SolrCloud的健康情况等等。图1.4展示了Solr4 管理控制台的一个截屏,我们会在第二章中详细的学习管理控制台的使用。
2.2.1 公司CEO眼中的Solr
尽管CEO之类的人物是不太可能看这本书的,我们还是要写几点关键的,以便于万一CEO在大厅里叫住你聊聊的时候你可以拿这几点去忽悠他。首先,管理层的人喜欢听到他们今天对技术做出的一笔投资将会在今后很长一段时间内都产生效益。具体到Solr,你可以强调一下许多公司至今还在靠着Solr 1.4运行公司的产品,这可是2009年发布的老版本,这说明Solr是有着成功的商用案例的,并且一直持续在改进。
此外,CEO们喜欢可控可预测的技术。正如你在接下来的章节里所要看到的那样,Solr很好用,你可以在几分钟之内就搭起一个简单的Solr服务。另一个疑问是如果万一负责Solr的那个员工跳槽或是跑路了,我们公司的业务会受到影响吗?不会因此整个服务当掉把?Solr的技术确实比较复杂,但是其开源社区非常的活跃,这意味着你只要上去求助基本上都能及时得到帮助。而且,你是直接可以看到源码的呀,有的时候你发现一个地方写的有问题那你可以直接自己fix掉就行了。另外也有许多商业化的服务商可以帮你规划,实现和维护你的Solr系统,其中很多服务商还提供Solr相关的培训课程。
接下来这一点可能CFO更关心,就是使用Solr的投资花费问题。投资使用Solr其实花不了多少钱。我们不用知道你的运营环境的规模大小就可以很自信的说,你可以在几分钟之内就搭起一个简单的Solr服务,并且很快就可以建立文档的索引。现在搭在云端的一个服务器可以在亚秒级(译者注:即不到一秒的时间之内)就处理完上百万的文档请求。