程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> sphinx 增量索引 實現近實時更新

sphinx 增量索引 實現近實時更新

編輯:關於MYSQL數據庫
基於PHP API調用,而不是基於sphinxSE。現在看來sphinxSE比API調用更簡單的多,因為之前沒有想過sphinxSE,現在先把API的弄明白。
涉及到的:sphinx 數據源的設置,簡單shell腳本的編寫,以及簡單crontab的使用一.sphinx增量索引的設置
數據庫中的已有數據很大,又不斷有新數據加入到數據庫中,也希望能夠檢索到。全部重新建立索引很消耗資源,因為我們需要更新的數據相比較而言很少。例如。原來的數據有幾百萬條,而新增的只是幾千條。這樣就可以使用“主索引+增量索引”的模式來實現近乎實時更新的功能。

這個模式實現的基本原理是設置兩個數據源和兩個索引,為那些基本不更新的數據建立主索引,而對於那些新增的數據建立增量索引。主索引的更新頻率可以設置的長一些(例如設置在每天的午夜進行),而增量索引的更新頻率,我們可以將時間設置的很短(幾分鐘左右),這樣在用戶搜索的時候,我們可以同時查詢這兩個索引的數據。

使用“主索引+增量索引”方法有個簡單的實現,在數據庫中增加一個計數表,記錄每次重新構建主索引時,被索引表的最後一個數據id,這樣在增量索引時只需要索引這個id以後的數據即可,每次重新構建主索引時都更新這個表。

測試條件:以默認的sphinx.conf配置為例,數據庫表的數據也以 example.sql為例。

1.先在MySQL中插入一個計數表和兩個索引表

  • CREATE TABLE sph_counter(
  • counter_id INTEGER PRIMARY KEY NOT NULL,
  • max_doc_id INTEGER NOT NULL
  • );

    2.修改sphinx.conf

  • source main_src
  • {
  • type = MySQL
  • sql_host = localhost
  • sql_user = yourusername
  • sql_pass = yourpassWord
  • sql_db = test //你所用的數據庫
  • sql_port = 3306 //所用端口,默認是3306
  • sql_query_pre = SET NAMES utf8
  • sql_query_pre = SET SESSION query_cache_type=OFF
  • #下面的語句是更新sph_counter表中的 max_doc_id。
  • sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents
  • sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title,\
  • content FROM documents \
  • WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
  • } // 注意:delta_src 中的sql_query_pre的個數需和main_src 對應,否則可能搜索不出相應結果
  • source delta_src: main_src
  • {
  • sql_ranged_throttle = 100
  • sql_query_pre = SET NAMES utf8
  • sql_query_pre = SET SESSION query_cache_type=OFF
  • sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content FROM documents \
  • WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
  • }
  • index main //主索引
  • {
  • source = main_src
  • path = /path/to/main # example: /usr/local/sphinx/var/data/main
  • .............
  • charset_type = utf-8 #這個是支持中文必須要設置的
  • chinese_dictionary =/usr/local/sphinx/etc/xdict
  • #..........其它可以默認
  • } //delta可全部復制主索引,然後更改source 和path如下
  • index delta: main //增量索引
  • {
  • source = delta_src
  • path = /path/to/delta # example: /usr/local/sphinx/var/data/delta
  • } 其它的配置可都用默認的,如果你設置了分布式檢索的索引,那麼更改下對應的索引名稱即可。3.重新建立索引:
    如果sphinx正在運行,那麼首先停止運行,然後,根據sphinx.conf配置文件來建立所有索引,最後,啟動服務
  • /usr/local/sphinx/bin/searchd --stop
  • /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all
  • /usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf

    P.S /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all --rotate

    這樣就不需要停searchd,索引後也不再需要重啟searchd了。

    如果想測試增量索引是否成功,往數據庫表中插入數據,查找是否能夠檢索到,這個時候檢索應該為空,然後,單獨重建 delta索引
    /usr/local/sphinx/bin/indexer -c /usr/lcoal/sphinx/etc/sphinx.conf delta
    查看是否將新的記錄進行了索引。如果成功,此時,再用 /usr/local/sphing/bin/search 工具來檢索,能夠看到,在main索引中檢索到的結果為0,而在delta中檢索到結果。當然,前提條件是,檢索的詞,只在後來插入的數據中存在。接下來的問題是如何讓增量索引與主索引合並4.索引合並
    合並兩個已有索引 有時比重新索引所有數據有效,雖然,索引合並時,待合並的兩個索引都會被讀入內存一次,合並後的內容需寫入磁盤一次,即,合並100GB和1GB的兩個所以,將導致202GB的IO操作
    命令原型: indexer --merge DSTINDEX SRCINDEX [--rotate] 將SRCINDEX合並到 DSTINDEX ,所以只有DSTINDEX會改變,如果兩個索引都正在提供服務,那麼 -- rotate 參數是必須的。例如:將delta合並到main中。
    indexer --merge main delta 5.索引自動更新 建立兩個腳本:build_main_index.sh 和 build_delta_index.sh. build_main_index.sh:
    #!/bin/sh
    # 停止正在運行的searchd
    /usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/mersphinx.conf --stop >> /usr/local/sphinx/var/log/sphinx/searchd.log /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/mersphinx.conf main >> /usr/local/sphinx/var/log/sphinx/mainindex.log
    #啟動searchd守護程序
    /usr/local/sphinx/bin/searchd >> /usr/local/sphinx/var/log/sphinx/searchd.log build_delta_index.sh

    #!/bin/sh
    #停止sphinx服務,將輸出重定向
    /usr/local/sphinx/bin/searchd –stop >> /usr/local/sphinx/var/log/sphinx/searchd.log
    #重新建立索引delta ,將輸出重定向
    /usr/local/sphinx/bin/indexer delta –c /usr/local/sphinx/etc/sphinx.conf >>/usr/lcoal/sphinx/var/log/sphinx/deltaindex.log
    #將delta合並到main中
    /usr/local/sphinx/bin/indexer –merge main delta –c /usr/local/sphinx/etc/sphinx.conf >> /usr/lcoal/sphinx/var/log/sphinx/deltaindex.log
    #啟動服務
    /usr/local/sphinx/bin/searchd >> /usr/local/sphinx/var/log/sphinx/searchd.log
    腳本寫好後,需要編譯 chmod +x filename 這樣才能運行。即
    chmod +x build_main_index.sh
    chmod +x build_delta_index.sh 最後,我們需要腳本能夠自動運行,以實現,delta索引每5分鐘重新建立,和main索引只在午夜2:30時重新建立。使用crontab 命令 這有倆個地方可作參考 crontab crontab文件
    crontab -e 來編輯 crontab文件,如果之前沒有使用,會是一個空的文件。寫下下面兩條語句
    */30 * * * * /bin/sh /usr/local/sphinx/etc/build_delta_index.sh > /dev/null 2>&1
    30 2 * * * /bin/sh /usr/local/sphinx/etc/build_main_index.sh > /dev/null 2>&1 第一條是表示每30分鐘運行 /usr/local/sphinx/etc/下的build_delta_index.sh 腳本,輸出重定向。
    第二條是表示 每天的 凌晨2:30分運行 /usr/local/sphinx/etc下的build_main_inde.sh 腳本,輸出重定向。
    關於前面的 5個值的設置,在上面的crontab文件中有詳細的描述。關於重定向的解釋,請看最上面的Crontab筆記,也有crontab的介紹。保存好後:重新啟動服務
    [root@test1 init.d]# service crond stop
    [root@test1 init.d]# service crond start /etc/init.d/crontab start 到現在為止,如果腳本寫的沒有問題,那麼build_delta_index.sh將每30分鐘運行一次,而build_main_index.sh將在凌晨2:30分才運行。要驗證的話,在腳本中,有將輸出重定向到相關的文件,可以查看下文件中的記錄是否增多,也可以看下 /usr/local/sphinx/var/log下的 searchd.log 中,每次重建索引都會有記錄。總結
    1.索引合並問題,前面已經解釋過,兩個索引合並時,都要讀入,然後還要寫一次硬盤,IO操作量很大。而在PHP API調用時,Query($query,$index)中$index可以設置多個索引名,如Query($query,"main;delta"),也就沒有必要一定將兩個索引合並,或者,合並的次數不用那麼多。
    2.還有一個是沒有嘗試過的,把增量索引存放到共享內存中(/dev/shm)以提高索引性能,減少系統負荷。關於PHP API
    如何能夠順利通過PHP頁面來進行檢索。
    首先,在服務器上searchd 必須是運行的。
    然後,根據test.PHP來修改下。
    運行,連接時會出現一個很大的問題 errno =13 permission deny. 最後,查到一個英文的網頁,是因為SElinux的原因,關於SELinux在網上能搜到。沒有很好的解決辦法,只能把SELinux設置為不用。使用的命令有下面兩個: setenforce 在 /usr/bin 下
    setenforce 1 設置SELinux 成為enforcing模式
    setenforce 0 設置SELinux 成為permissive模式
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved