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了,啟動命令如下:

  C:\Users\gmuser\Desktop\mongo_connector>python mongo_connector.py -m localhost:2 7001 -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怎么實現,那它就是怎么做的了。

  有些地方還是要根據我們項目進行一些修改的。

 

 

 
 
分類:  MongoDBSolr


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM