基于Solr的分布式实时搜索模型研究与实现*

2011-06-11 11:03傅巍玮李仁发刘钰峰黄松立
电信科学 2011年11期
关键词:磁盘搜索引擎日志

傅巍玮,李仁发,刘钰峰,黄松立

(1.湖南大学嵌入式系统及网络实验室 长沙410082;2.淘宝(中国)有限责任公司 杭州315100)

1 引言

互联网信息技术的高速发展使人们更加关注如何以最快的时间获取实效数据,并从中挖掘到有价值的信息。获取实时资讯的方法有两种。一是建立实时数据库[1],保证数据的强一致性(ACID)和高可用性,但其在分布式环境下的扩展能力较为有限;二是建立实时搜索引擎,不仅有理论价值,同时有重大的应用价值[2]。传统的信息搜索技术发展非常成熟,但是在查询精度和不同查询需求上存在许多不足[3],不能满足信息的实时搜索需求。实时搜索是传统搜索引擎的扩展和延伸,可以分为通用实时搜索引擎[4]和垂直实时搜索引擎[5]。垂直搜索引擎针对某一领域行业的搜索,特点是专、精、深,实时搜索的研究大多集中于垂直搜索领域,如在图片搜索[6]和物联网领域的应用[7]。实时搜索已成为当前搜索引擎领域的热点问题,其核心概括为实时数据获取和实时索引构建两方面。相比传统搜索研究,垂直搜索数据来源相对简单,因此垂直实时搜索的难点问题是分布式环境下的实时索引构建。实时索引构建主要指的是在大规模高并发的分布式环境下,即时提交实时数据构建索引,保证实时数据即时展示以及分布式数据的一致性和容灾[8]。

针对这一难点问题,本文在分布式搜索技术[9]基础上提出一种基于Solr[10]的分布式实时检索模型,模型的创新之处如下。

·引入自定义多维度的分组规则构建分布式索引数据。可根据实际需求对索引进行多维度的切分,将大型索引切分成独立的集群组,搜索时通过相应的路由规则定位至索引信息所在的m×n分布式集群组,减少索引搜索时间,提高搜索性能。

·提出一种新的实时搜索模型,采用内存与磁盘索引相结合的多索引机制。通过全量的方式定期建立主磁盘索引,保证数据的完整性。实时信息以增量方式先写入内存,内存索引超出设定阈值后复制写入磁盘,形成从磁盘索引,不与主索引合并,减少索引合并时间开销。同时查询内存和磁盘索引,提升搜索响应时间。

·解决分布式环境下的索引数据容灾问题。引入CommitLog日志机制,持久化索引元数据,改进Solr的Master/Slave(主备)模型,保证数据的一致性和可用性。

2 分布式实时搜索系统模型

分布式实时搜索模型由3部分组成,如图1所示。

·搜索功能实现:搜索请求分为查询、更新、添加、删除4种,分别定位到分布式集群的一组或者多组服务器。

·分布式m×n系统模型构建:分布式集群组采用m×n模型,每一组集群内采用Master/Slave模型保证单组数据的一致性和搜索服务的可用性。

·索引数据构建:索引构建采用主磁盘索引+内存索引+从磁盘索引相结合的模型,保证最新的数据即时展现,实现搜索的实时性。实时索引的请求先写CommitLog日志,保证实时索引的数据容灾性。

3 分布式实时搜索模型的详细设计

3.1 分布式m×n系统模型构建

分布式系统是解决目前大规模海量数据和高并发请求的最有效方式。本系统采用分布式m×n的部署模型切分海量数据建立索引,实现高并发搜索请求量的随机软负载均衡,提升搜索系统性能。在索引量和搜索请求增加的情况下,动态添加行列的机器数量保证存储负载和搜索性能。其中,n列指系统划分为搜索服务器集群的个数,m行指单个搜索服务器集群包含搜索服务器的台数,m≥1且n≥1。m×n模型建立过程如下。

(1)自定义切分规则

根据系统需求,设定自定义的索引切分规则进行Group Filter分组路由,例如分组规则用生成的索引Docment文档的Field域userId取模进行分组。分组规则不仅可以是单维,也可以是多维,即在m×n二维分组的基础上进行扩展,多维数组与一维数组存储机制一致,如先按userId取模分组后,再以用户所在的省份进行分组。

(2)确定m×n行列值

m和n的行列值取决于两个因素。

·搜索服务器单机负载能力。单机的索引数据容量由磁盘容量决定。建立新索引的过程中涉及索引的合并,旧的索引继续提供索引服务,此时的磁盘空间为:一份新索引+一份正提供服务的索引+索引合并所需磁盘空间,磁盘容量至少为索引数据的3倍。单机能承受的搜索请求量通过压力测试获取。当机器负载(load)值等于搜索服务器的CPU核数时,服务器所能承受的TPS(每秒请求数)为压力测试的峰值,如对于4核的服务器,通常在load=4时的TPS为其单机所能承受的最高值。

·分布式系统索引总量和搜索请求总量。索引总量用S表示,单机承载索引量用T表示,搜索请求总量用Q表示,单机承载搜索请求量用R表示,X表示机器增量,在搜索的热点数据相应组添加服务器,保证可用性,则m、n可用下式计算:

(3)建立分布式集群

根据索引切分规则和m、n的行列数,建立分布式搜索服务器集群。所有搜索服务器均提供搜索服务,搜索请求随机发送到组内的任一服务器。在同一组搜索服务集群中,每一台搜索服务器分别向组内其他服务器发布感知服务,确保两两感知。单组集群内部,设定一台Master服务器,其他均为Slave服务器。Master服务器负责主索引的建立和写CommitLog日志文件,Slave服务器从Master服务器中同步主索引,同步CommitLog日志建立内存索引。通过Master/Slave模型保证单组的索引数据容灾性,在组内某一搜索服务器宕机的情况下保证搜索服务的可用性。

3.2 实时索引构建

索引分为3个部分:主磁盘索引、内存索引、从磁盘索引。磁盘+内存的索引结构保证新增索引即时展现。写内存索引前先写CommitLog日志,持久化索引数据,保证内存索引数据不丢失。内存索引到达阈值后刷入从磁盘索引,保证可用性。索引的构建采用全量dump+实时增量dump的模型构建。全量dump采用时间周期任务定期执行,实时增量dump由实时调用接口生成,下面是实时索引构建的详细设计。

(1)主磁盘索引构建

·搜索服务器定时触发全量dump程序。系统从数据源获取索引数据,数据源可以是网络爬虫抓取的信息、各种存储系统(数据库、文件、nosql系统等)。索引建立采用迭代器模型,利用Data Provider接口,首先利用has Next()判断下一条语句是否存在,存在则用next()方法取下一条数据,构建并返回一条Map记录,直至has Next()方法返回为false,结束整个迭代过程。Map记录对应一篇索引文档,Map的键值对对应于文档的域和域值。利用封装好的Map对象构建Solr的Add Update Command对象,最后调用 Solr的 Update Handle.add Doc()方法添加文档至索引。

·时间点设置:主索引构建过程开始时,记录一个时间点checkPoint。主索引建立完成后,提供搜索的服务将从旧索引替换到新索引,但是新索引建立过程中,会有增量的实时索引产生,因此需要补全在全量执行期间的增量数据,通过时间点机制从后补全实时索引。

·Slave服务器构建主索引:Master服务的主索引构建完成后,通知Slave服务器进行主索引的拷贝,并将checkPoint传递给Slave服务器,Slave服务器完成索引的构建工作后通知Master服务器,新的索引向外提供搜索服务。

(2)实时索引构建

实时索引构建包含内存索引构建和从磁盘索引构建2部分,实现过程如下。

·实时更新请求。实时请求可以来自于数据源(与主索引相同),也可以来自客户端的实时接口调用。以实时接口调用为例,客户端调用Real-time Bean类的实时方法发送请求。实时请求方法分为Add(添加)、Update(更 新)、Delete(删 除)、mAdd(批 量 添 加 )、mUpdate(批量更新)、mDelete(批量删除)。服务器端接收实时请求,将实时请求封装为Document Request对象添加到CommitLog日志文件中。

·CommitLog日志建立。所有的实时请求都会写入Master服务器的CommitLog日志中,持久化索引请求。搜索服务器启动时创建实时索引的构建进程Real-time Job,不断轮循CommitLog日志,一旦有新的记录产生即进行写索引操作,根据请求类型的不同,分别调用Solr的Update Handler的相应方法建立内存索引。

·从磁盘索引建立。内存索引受限于内存大小,所以需要设定阈值,防止内存索引过大撑爆内存或者影响其他应用。当内存索引达到阈值时,新开一个内存索引,新来的实时请求写入新的内存索引,同时将旧的内存索引刷新至磁盘。利用内存索引与磁盘索引结构完全相同的特性,调用Directory的copy方法直接将内存索引拷贝至磁盘,形成从磁盘索引,提升搜索性能,实现立即搜索。

·内存索引恢复机制。如果服务器宕机或者重新部署导致服务器重启,当前的内存索引会造成数据丢失。设定宕机时间恢复点记录CommitLog日志位置偏移值,新的从磁盘索引生成时,更新一次宕机时间恢复点信息。服务器重启时从最近的宕机时间恢复点开始读取CommitLog日志,恢复内存索引。通过CommitLog日志机制保证内存索引数据的容灾。

3.3 实时搜索引擎功能实现

系统一共提供4种功能,包括查询、新增、更新、删除。查询不会修改索引数据结构,其他3种操作都会造成索引数据的修改,且有相应的批量操作方法。

(1)搜索功能实现

用户发出搜索请求后,通过路由规则获取索引所在分布式搜索服务器组的集合。如果是单组搜索,需要对当前所有的索引进行搜索,包含主磁盘索引、内存索引、从磁盘索引,搜索结果过滤掉已被删除的文档。被删除文档的docId存储在delList集合中。多组则利用Solr的shard概念对多组的结果集作合并操作。Solr服务是通过HTTP的方式提供服务,索引合并也都是通过HTTP方式发出请求进行合并,本系统对此作了改进。任意选定分组集中的一组,通过TCP/IP协议进行访问,此时利用Solr提供的Embedded Solr Server获取当前组索引,并向其他组发送TCP/IP请求,获取索引数据并进行索引的merge操作,提高索引获取速度。

(2)添加、删除、更新功能实现

·添加功能实现。客户端发出Add命令,将其封装成添加请求写入CommitLog日志文件中。Index Build Job构建索引时进行判断,如为Add Document Request请求,提取索引数据信息转换为Solr的Add Update Command对象,最后调用Solr的Update Handle的Add Doc()命令,实现索引数据的添加。

·删除功能实现。客户端发出Delete命令,将其封装成删除请求 Delete Document Request写入CommitLog日志文件中。在Lucene搜索引擎中有Index Writer和Index Reader两个对象可以做删除动作,区别在于Index Writer实例中删除的内容被缓存起来,并不会马上生效。搜索引擎接收实时删除请求后,如果待删除的文档在内存中,则用Index Writer直接进行删除,否则在磁盘索引(即主索引和从索引)做标志删除,将文档保存至待删除的集合delList中。在内存索引提交时,调用Index Writer的commit()方法,再调用磁盘索引的Index Reader方法逐个删除delList集合的元素。

·更新功能实现。与Add命令相同,客户端发出Update命令会被封装为Update Document Request请求,写入CommitLog日志中。Index Build Job构建索引时,将索引数据信息转换为Add Update Command,同时设置 Allow Dups为 false,即不允许索引数据重复。此时Solr会首先判断索引是否已存在,有则删除,然后进行添加操作,完成更新。

4 实验结果

实验由10台搜索服务器组成,分为5组,每组一主一备。搜索服务器配置为Intel®Xeon®4核CPU E5520@2.27 GHz、内存4 GB、60 GB硬盘7 200转。索引总量为60 GB、单机12 GB,实验数据取平均值。

工程实现的原型系统为Xsolr,对比系统为Solr,数据集为4 000万个文档,每个文档由22个域构成,平均大小为0.03 KB,测试工具为Load Runner。实验结果分两部分,第一组实验为Xsolr与Solr系统的性能指标对比,结果见表1,第二组实验为Xsolr的数据一致性与容灾,如图2所示。

·实时响应性能。由表1可以看出,Xsolr的TPS和响应时间在4种测试条件下的性能均好于Solr。实时更新的请求响应时间均在1 s以内。因为Xsolr更新操作在内存进行,索引在内存进行建立,而且不与磁盘索引进行合并,同时搜索内存和磁盘索引,减少磁盘I/O,加速了实时索引数据展示的速度。

·负载分析。在系统负载接近的情况下,Xsolr的CPU更加消耗资源。因为Xsolr会建立内存索引,实验环境下占用大量内存,最高时达到1 GB。CPU使用率最高在30%左右,此时索引的更新TPS高达2 100,大量占用内存,但是机器负载仍小于4,在可接受的范围内。

·数据一致性。如图2所示,前15 s内,单机分别进行插入、更新、删除操作,Master/Slave服务器数据保持一致,有极细微区别。实时操作时,Slave不间断地从Master机器中拉取增量CommitLog日志文件,进行消费创建实时索引,保证主备服务器数据的一致性。但是由于CommitLog是顺序写入,且从Master机器拷贝文件有一定的网络开销,所以会出、现极细微的区别,在毫秒级别实现最终一致性,对系统整体服务影响极小,在可接受的范围内。

表1 Xsolr与Solr实验结果对比

·数据容灾及完整性。17 s时,Master服务器随机插入1 000条记录,此时内存索引未达到阈值,不刷入从磁盘索引。30 s时,Slave服务器恢复服务,其索引记录数与Master相同。35 s后Master服务器宕机,60 s后恢复启动,其索引记录数与Slave相同,且符合最初插入的1 000条记录数。Xsolr通过CommitLog日志持久化实时数据,设置宕机恢复点。服务器宕机恢复时,读取离Check Point最近的CommitLog日志记录偏移量,从偏移量处开始重建内存索引,保证数据的完整性,实现数据容灾。

实验结果表明,本模型满足系统的实时性需求,同时在大数据量和高并发环境下保证了数据的一致性和数据容灾,证明了系统模型的可行性。

5 结束语

本文主要研究了分布式实时搜索引擎,并基于Solr进行了实现。重点解决搜索引擎在大数据量高并发分布式环境下的实时性和数据容灾问题。模型目前还存在一些问题,如Master/Slave模型中写操作都是作用于Master服务器,其宕机会造成实时信息更新失败。下一步的工作从以下方面着手:改进当前的实时模型,实现单组搜索服务器Master/Slave去角色化,进一步提高实时模型的可用性;研究利用SSD磁盘代替普通SATA硬盘作高速存储,进一步提高实时搜索性能。

1 Nizar Idoudi,Claude Duvallet,Bruno Sadeg.How to model a real-time database.In:Proc of IEEE International Symposium on Object/Component/Service-Oriented Real-TimeDistributed Computing,2009

2 Bernard J Jansen,Zhe Liu,Courtney Weaver,et al.Real time search on theWeb:queries,topics,and economic value.Information Processing and Management,2011

3 曾春,邢春晓,周立柱.基于内容过滤的个性化搜索算法.软件学报,2003(5)

4 Daniel Peng,Frank Dabek.Large-scale incremental processing using distributed transactions and notifications.In:Proc of the 9th USENIX Conference of OSDI,2010

5 Wu Y,Shou L,Hu T,et al.Query triggered crawling strategy:build a time sensitive vertical search engine.Cyberworlds,2008

6 Jingyu Cui,Fang Wen,Xiaoou Tang.Real time Google and live image search re-ranking.In:Proc of the 16th ACM International Conference on Multimedia,2008

7 Gershenfeld N,Krikorian R,Cohen D.The Internet of things.Scientific American,2004,291(4):76~81

8 Seth Gilkn,Nancy Lynch.Brewer's conjecture and the feasibility of consistent,available,partition-tolerant Web services.Sinact News,2002,33(2)

9 姚树宇,赵少东.一种使用分布式技术的搜索引擎.计算机应用与软件,2005,22(10)

10 Apache.SOLR.http://lucene.apache.org/solr/

猜你喜欢
磁盘搜索引擎日志
一名老党员的工作日志
扶贫日志
解决Windows磁盘签名冲突
修改磁盘属性
游学日志
磁盘组群组及iSCSI Target设置
创建VSAN群集
网络搜索引擎亟待规范
基于Nutch的医疗搜索引擎的研究与开发
一种基于粗集和SVM的Web日志挖掘模型