Solr与MongoDB集成,实时增量索引
Solr与MongoDB集成,实时增量索引
一. 概述
大量的数据存储在MongoDB上,需要快速搜索出目标内容,于是搭建Solr服务。
另外一点,用Solr索引数据后,可以把数据用在不同的项目当中,直接向Solr服务发送请求,返回xml、json等形式的内容,使得对数据的使用更灵活。
对于MongoDB与Solr的描述不在这里阐释了,本文旨在给大家提供整个Solr与MongoDB接合的方法,实现实时的增量索引。
MongoDB的官网:http://www.mongodb.org/
Solr项目的主页:http://lucene.apache.org/solr/
二. 寻找解决方案
既然有了目标是讲Solr跟MongoDB接到一起,那么就开始想想解决的方案。
网上搜了一些资料之后,汇总了下面三个方案:
1. 使用Solr的DataImport功能(Data Import)
我们先来看看Solr Wiki上对于DataImport功能的描述http://wiki.apache.org/solr/DataImportHandler
Most applications store data in relational databases or XML files and searching over such data is a common use-case.The DataImportHandler is a Solr contrib that provides a configuration driven way to import this data into Solr in both "full builds" and using incremental delta imports.
对于存储在关系型数据库及XML上的数据,Solr提供了DataImportHandler去实现全量和增量索引。
啥?人家没说支持NoSQL啊,不信,我看清楚一点。
Wiki中的内容只给出了Usage with RDBMS 和 Usage with XML/HTTP Datasource,貌似Solr目前是不支持对于NoSQL的DataImport的。
有兴趣的朋友可以尝试给Solr添加一个Mongo的DataImportHandler,可能还要写底层的Mongo驱动,工程量可能很大。
关键是这个方案不可控,成本可能会很大,因此我就不采取这种方式了。
在这里给大家分享一篇文章,Solr与MySQL集成指南
确实DataImport这个功能还是比较强大的,而且对MySQL也支持得很好,本人尝试一下将Solr跟MySQL集成起来,配置过程也很简单。
不过MySQL不是本文的重点,跑题了,因此只是尝试了一下,没有深入。
2. 使用脚本语言读取MongoDB中的数据(Script Update)
说白了就是读取整个Collection中的数据,遍历。
这种方案是最直观的,但不优雅,复用性、可维护性低,
最严重的问题在于性能,当数量级在百万以下,那还是可以接受的,一旦数据继续增长,那性能问题就凸显出来了。
然而要是你还想用这种方案,那这里还有一个需要考虑的问题,你是打算每次遍历的时候对Solr进行全量还是增量索引呢?
全量的话就直接overwrite,事情也好办;增量的话,Mongo中删除了的数据你咋整呢?
总而言之,不推荐这种方案,它的复杂度问题很明显,无论是时间上还是空间上。
3. 使用MongoDB的oplog功能(Oplog Update)
MongoDB支持集群,集群中的实例进行通信,很自然地想到它们会记录log,在MongoDB中称之为oplog(operation log),类似与MySQL的binlog。
我们可以看看MongoDB官网上对oplog的描述 http://docs.mongodb.org/manual/reference/program/mongooplog/
如果现在你还想用上面方案2的话,那oplog的存在必然是对你的工作带来极大便利的。
其一,oplog是实时记录的,配合tailable cursor,可以实现实时的更新Solr索引,见http://derickrethans.nl/mongodb-and-solr.html
其二,实现优雅,增量的新增删除的判断时间复杂度变为O(1)
看到这里,你想用oplog来实现Solr与MongoDB的集成,那需要理清下面几个问题:
(1)mongooplog如何开启,怎么配置才适合
(2)Mongo Tailable Cursor是怎么一回事
(3)使用什么语言,选择合适的Solr Client
(4)服务器宕机恢复后的处理
三. 最终方案,mongo-connector
当我性高彩烈地动手实现方案3的时候,我看到了这个http://blog.mongodb.org/post/29127828146/introducing-mongo-connector
竟然找到了一个mongo-solr的connector,当时那个心情真叫欣喜若狂啊。
它完全就是方案3的实现啊!提到的问题它都解决了,而且使用Python正好适合这个项目,一切来得太突然。
Git地址:https://github.com/10gen-labs/mongo-connector
但是配置的过程都搞了我很久,后文将整个过程记录下来
四. 项目环境及工具版本
在本地测试,服务器:Windows7 32-bit
MongoDB:mongodb-win32-i386-2.4.5
Tomcat 6
Python:2.7.4
Solr:4.5.1
mongo-connector:没有提供版本号
Python pysolr模块
Python pymongo模块
Python lxml模块:lxml-3.2.3.win32-py2.7
可能还需要一些模块,但由于我在之前已经安装了,没有列举出来。如果运行的过程中报module not found,就去安装吧~
五. Solr端准备
这里默认你已经部署Solr成功,详细的部署过程自行Google。
这里主要是讲述与本次测试相关的配置。
使用的是solr example中的multicore例子,以其中的core0为例子
schema.xml文件如下:修改_id与Mongo对应,只留下一个name字段,为String类型

其它的配置不需要修改
把它放到Tomcat中运行吧,检查是否已经配置成功
六. MongoDB端准备
看到mongo-connector项目中的说明,
Since the connector does real time syncing, it is necessary to have MongoDB running, although the connector will work with both sharded and non sharded configurations. It requires a replica set setup.
就算我们开启了oplog也不行,还需要在Mongo中启动一个replica set
1. 配置replica set
(1)
我的MONGO_HOME为 D:\mongodb
目录树如下:
-rs (d)
|----db (d) mongo数据文件文件存放的目录
|----rs1 (d) rs1实例数据文件存放的目录
|----rs2 (d) rs2实例数据文件存放的目录
|----log (d) log文件存放的目录
|----rs1.log (f) rs1实例的log文件
|----rs2.log (f) rs2实例的log文件
|----mongod-rs1.bat rs1实例的启动脚本
|----mongod-rs2.bat rs2实例的启动脚本
mongod-rs1.bat内容如下:
D:\mongodb\bin\mongod --port 27001 --oplogSize 100 --dbpath db\rs1 --logpath log\rs1.log --replSet rs/127.0.0.1:27002 --journal
pause
mongod-rs2.bat内容如下:
D:\mongodb\bin\mongod --port 27002 --oplogSize 100 --dbpath db\rs2 --logpath log\rs2.log --replSet rs/127.0.0.1:27001 --journal
pause
(2)执行两个脚本,启动两个mongod实例
(3)但这时它们还没组成一个replica set,还需要进行配置,开启mongo,连上localhost:27001,也就是实例rs1




至此,配置完成。
七. mongo-connector准备
如果是在mongo example中的multicore默认的配置上修改的话,访问http://localhost:8080/solr/core0/admin/luke?show=Schema&wt=json
应该是能看到JSON形式的core0的schema
打开mongo_connector/doc_managers/solr_doc_manager.py
进行如下修改:1.从util引入verify_url;2. ADMIN_URL修改为获取Solr核core0的JSON形式schema的URL的后半部分,因为要根据schema中的fields进行索引

在Solr多核的情况下启动mongo-connector,会报出Solr URL访问错误,它期望你传入http://localhost:8080/solr,
但http://localhost:8080/solr/core0才是实际起作用的,因此我们需要传入这个作为BASE_URL
解决办法如下:屏蔽掉url检查就行了

接下来就是启动mongo-connector了,启动命令如下:

-m Mongod实例的访问路径
-t Solr的BASE_URL
-o 记录oplog处理时间戳的文件
-n mongo命名空间,是监听哪个database哪个collection的设置,以逗号分隔多个命名空间,这里是监听test库中的test集合
-d 就是处理doc的py文件
启动结果如下:说明你的配置已经成功了

八. 测试增量索引
先看看Solr中core0的状态:现在是没有记录的,Num Docs为0

往MongoDB中插入一条数据:需要包含name字段,还记得我们上面的schema.xml吗?

查看mongo-connector的输出:update了一条记录

看看Solr现在的状态:我们看到了刚才插入的

尝试删除掉刚才那条记录,connector输出如下:多了一条update的记录,这次是<delete>

再看看Solr的状态:刚才那条记录没了,删除成功!

九. 一些说明
mongo-connector会在oplog_progress.txt中记录时间戳,可以在服务器宕机恢复后索引Mongo oplog新增的数据,记录如下:
["Collection(Database(MongoClient([u'127.0.0.1:27001', u'127.0.0.1:27002']), u'local'), u'oplog.rs')", 5941530871067574273]
mongo-connector的代码并不复杂,想想上面上面方案3怎么实现,那它就是怎么做的了。
有些地方还是要根据我们项目进行一些修改的。
Solr与MongoDB集成,实时增量索引的更多相关文章
- [Solr] (源) Solr与MongoDB集成,实时增量索引
一. 概述 大量的数据存储在MongoDB上,需要快速搜索出目标内容,于是搭建Solr服务. 另外一点,用Solr索引数据后,可以把数据用在不同的项目当中,直接向Solr服务发送请求,返回xml.js ...
- sphinx通过增量索引实现近实时更新
一.sphinx增量索引实现近实时更新设置 数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到.全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少. 例如.原来的数据 ...
- Lucene.net 实现近实时搜索(NRT)和增量索引
Lucene做站内搜索的时候经常会遇到实时搜索的应用场景,比如用户搜索的功能.实现实时搜索,最普通的做法是,添加新的document之后,调用 IndexWriter 的 Commit 方法把内存中的 ...
- sphinx 增量索引 实现近实时更新
一.sphinx增量索引的设置 数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到.全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少.例如.原来的数据有几百万条 ...
- solr与.net系列课程(六)solr定时增量索引与安全
solr与.net系列课程(六)solr定时增量索引与安全 solr增量索引的方式,就是一个Http请求,但是这样的请求显然不能满足要求,我们需要的是一个自动的增量索引,solr官方提供了一个定时器 ...
- sphinx续5-主索引增量索引和实时索引
原文件地址:http://blog.itpub.net/29806344/viewspace-1400942/ 在数据库数据非常庞大的时候,而且实时有新的数据插入,如果我们不更新索引,新的数据就sea ...
- Coreseek:部门查询和增量索引代替实时索引
1.行业调查 索引系统需要通过主查询来获取所有的文档信息,一个简单的实现是整个表的数据到内存,但是这可能会导致整个表被锁定,并且使其它操作被阻止(例如:在MyISAM格款式上INSERT操作).同时, ...
- solr之定时增量索引实现
solr本身就提供了一个工具库实现定时增量索引,但是我在使用的过程中发现会出现一些问题,目前遇到两点: 1.启动时总是报如下异常: ? 1 The web application [solr] reg ...
- sphinx增量索引和主索引来实现索引的实时更新
项目中文章的信息内容因为持续有新增,而文章总量的基数又比较大,所以做搜索的时候,用了主索引+增量索引这种方式来实现索引的实时更新. 实现原理: 1. 新建一张表,记录一下上一次已经创建好索引的最后一条 ...
随机推荐
- ABP日志管理
ABP日志管理 基于DDD的现代ASP.NET开发框架--ABP系列之8.ABP日志管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP ...
- linux_增加用户组_删除用户
添加账号组 /usr/sbin/groupadd iknow 添加账号 /usr/sbin/useradd -g iknow -d /home/iknow/ iknow 更改密码 passwd 选项 ...
- 【高德API】如何利用MapKit开发全英文检索的iOS地图
原文:[高德API]如何利用MapKit开发全英文检索的iOS地图 制作全英文地图的展示并不困难,但是要制作全英文的数据检索列表,全英文的信息窗口,你就没办法了吧.告诉你,我有妙招!使用iOS自带的M ...
- 【百度地图API】如何制作泡泡放大镜?
原文:[百度地图API]如何制作泡泡放大镜? 任务描述: 我不喜欢API提供的缩放控件耶…… 我能不能使用其他方式放大地图勒? 当然阔以啦! 现在就来教大家如何动手制作一个可爱的泡泡放大镜! 使用它, ...
- ASP.NET 5:依赖注入
ASP.NET 5:依赖注入 1.背景 如果某个具体的(或类)对象被客户程序所依赖,通常把它们抽象成抽象类或接口.简单说,客户程序摆脱所依赖的具体类型,称之为面向接口编程. 那么问题来了?如何选择客户 ...
- hdoj 4324 Triangle LOVE 【拓扑】
Triangle LOVE Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...
- SQL编程之生日问题
在学习MySQL的时候,一个较为经典的SQL编程题目就是生日问题,已知某个用户的出生日期和当前日期,计算他近期的生日. 一般须要考虑两个问题 闰年2月是29天 今年的生日是否过完 比如:某人的生日是1 ...
- 解决IIS7运行ASP提示错误:An error occurred on the server when processing the URL. Please contact the system administrator
原文:解决IIS7运行ASP提示错误:An error occurred on the server when processing the URL. Please contact the syste ...
- InstallShield集成安装MSDE2000最小版本(二) fishout特许授权发布
原文:InstallShield集成安装MSDE2000最小版本(二) fishout特许授权发布 原帖地址:http://blog.csdn.net/fishout/archive/2009/10/ ...
- canvas绘制自定义的曲线,以椭圆为例,通俗易懂,童叟无欺
本篇文章,将讲述如何通过自定义的曲线函数,使用canvas的方式进行曲线的绘制. 为了通俗易懂,将以大家熟悉的椭圆曲线为例,进行椭圆的绘制.至于其他比较复杂的曲线,用户只需通过数学方式建立起曲线函数, ...