一. 概述

  大量的数据存储在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 --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 --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了,启动命令如下:

  C:\Users\gmuser\Desktop\mongo_connector>python mongo_connector.py -m localhost:27001 -t http://localhost:8080/solr/core0 -o oplog_progress.txt -n test.test -u _id -d ./doc_managers/solr_doc_manager.py

  

  -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] (源) Solr与MongoDB集成,实时增量索引的更多相关文章

  1. Solr与MongoDB集成,实时增量索引

    Solr与MongoDB集成,实时增量索引 一. 概述 大量的数据存储在MongoDB上,需要快速搜索出目标内容,于是搭建Solr服务. 另外一点,用Solr索引数据后,可以把数据用在不同的项目当中, ...

  2. solr源码分析之数据导入DataImporter追溯。

    若要搜索的信息都是被存储在数据库里面的,但是solr不能直接搜数据库,所以只有借助Solr组件将要搜索的信息在搜索服务器上进行索引,然后在客户端供客户使用. 1. SolrDispatchFilter ...

  3. solr之定时增量索引实现

    solr本身就提供了一个工具库实现定时增量索引,但是我在使用的过程中发现会出现一些问题,目前遇到两点: 1.启动时总是报如下异常: ? 1 The web application [solr] reg ...

  4. solr源码分析之solrclound

    一.简介 SolrCloud是Solr4.0版本以后基于Solr和Zookeeper的分布式搜索方案.SolrCloud是Solr的基于Zookeeper一种部署方式.Solr可以以多种方式部署,例如 ...

  5. solr与.net系列课程(六)solr定时增量索引与安全

     solr与.net系列课程(六)solr定时增量索引与安全 solr增量索引的方式,就是一个Http请求,但是这样的请求显然不能满足要求,我们需要的是一个自动的增量索引,solr官方提供了一个定时器 ...

  6. solr搜索引擎配置使用mongodb作为数据源

    环境说明: 操作系统:由于是使用的docker直接拉取的镜像部署的,系统是LINUX环境 mongodb: 4.0.3 solr: 7.5.0 python: 3.5 配置mongodb 1.拉取mo ...

  7. solr源码分析之searchComponent

    上文solr源码分析之数据导入DataImporter追溯中提到了solr的工作流程,其核心是各种handler. handler定义了各种search Component, @Override pu ...

  8. solr源码解读(转)

    solr源码解读(转)原文地址:http://blog.csdn.net/duck_genuine/article/details/6962624 配置 solr 对一个搜索请求的的流程 在solrc ...

  9. ant编译solr源码生成eclipse项目,解决一直resolve,一直[ivy:retrieve]的问题

    这两天在学习solr,结果刚到编译solr源码就卡住了,足足卡了两天,网上找各种解决办法都是简单带过,说是缺少jar包,下载下来放到对应位置就好了....对应位置???咋不说这个问题用相应方法解决即可 ...

随机推荐

  1. 日期格式代码出现两次的错误 ORA-01810

    错误的原因是使用了两次MM . 一.Oracle中使用to_date()时格式化日期需要注意格式码 如:select to_date('2005-01-01 11:11:21','yyyy-MM-dd ...

  2. 十分钟介绍mobx与react

    原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...

  3. 三分钟学会用 js + css3 打造酷炫3D相册

    之前发过该文,后来不知怎么回事不见了,现在重新发一下. 中秋主题的3D旋转相册 如图,这是通过Javascript和css3来实现的.整个案例只有不到80行代码,我希望通过这个案例,让正处于迷茫期的j ...

  4. Android数据加密之Base64编码算法

    前言: 前面学习总结了平时开发中遇见的各种数据加密方式,最终都会对加密后的二进制数据进行Base64编码,起到一种二次加密的效果,其实呢Base64从严格意义上来说的话不是一种加密算法,而是一种编码算 ...

  5. 浅谈web攻防

    CSRF 跨站请求伪造(Cross-Site Request Forgery) -原理- 从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤: 1.登录受信任网站A,并在本地生成Coo ...

  6. 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包

            微信支付教程系列之现金红包           最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...

  7. UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

    在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...

  8. 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇

    最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...

  9. 学习笔记 :DrawText

    最近在做一个TStringGrid的自绘处理,在画文字处理上遇到了高度的计算问题.后来经过一段时间还是找到了一些方法: 1.使用TLabel 这个方法是有点绕路的,方法倒是简单,就是使用AutoSiz ...

  10. 1、利用蓝牙定位及姿态识别实现一个智能篮球场套件(一)——用重写CC2541透传模块做成智能手环

    一.预言 要实现一个智能篮球场套件,需要设计一个佩戴在篮球运动员手臂上的可以检测投篮.记步的手环,以及一套可以根据RSSI定位运动员的蓝牙定位装置.下面是大致需要的步骤: 首先,需要用CC2541透传 ...