一、Sphinx是什麼?
Sphinx是由俄羅斯人Andrew Aksyonoff開發的一個全文檢索引擎。意圖爲其他應用提供高速、低空間佔用、高結果 相關度的全文搜索功能。Sphinx可以非常容易的與SQL數據庫和腳本語言集成。當前系統內置MySQL和PostgreSQL 數據庫數據源的支持,也支持從標準輸入讀取特定格式 的XML數據。通過修改源代碼,用戶可以自行增加新的數據源
二、安裝
1、下載所需的安裝包
# wget https://sphinx-for-chinese.googlecode.com/files/sphinx-for-chinese-2.1.0-dev-r3361.tar.bz2
2、安裝 sphinx
# cd sphinx-for-chinese-2.1.0-dev-r3361
# ./configure --prefix=/usr/local/sphinx
# make
# sudo make install
如果顯示bin,etc和var三個目錄表示安裝成功
3、創建test數據庫,並創建sphinx用戶(可忽略)
mysql> create database test;
mysql>create user 'sphinx'@'localhost' identified by 'sphinx';
mysql>grant all privileges on test.* to 'sphinx'@'localhost';
4、指定sphinx配置文件
# cd /usr/local/sphinx/etc
# sudo cp sphinx.conf.dist sphinx.conf
5、編輯配置文件
sql_host = localhost
sql_user = sphinx
sql_pass = sphinx
sql_db = test
sql_port = 3306 # optional, default is 3306
到這裏爲止,sphinx已經可以使用了,但還不能支持中文切詞,以下是加入中文切詞的步驟
三、配置中文詞庫:
1、去官網下載並解壓字典文件 xdict_1.1.tar.gz
2、將解壓好的 xdict.txt 拷貝到 /usr/local/sphinx/bin 下並生成字典
# sudo /usr/local/sphinx/bin/mkdict xdict.txt xdict
3、將生成的字典 xdict 拷貝到 /usr/local/sphinx/etc目錄下
# sudo cp -p xdict ../etc/
4、配置中文切詞 打開 sphinx.conf文件,找到 'charset_type = sbcs' 字樣,將其改爲:
# charset_type = utf-8 #字符集編碼
# chinese_dictionary = /usr/local/sphinx/etc/xdict #指定分詞庫 sphinx-for-chines特有的選項
四、實現一個分佈式索引的搜索服務:
A、searchd多處理模式(MPM)有:
# none: 所有請求都將被串行處理
# fork: 創建一個新的子進程來處理每個傳入請求
# prefork: searchd會在啓動時,預先fork一個工作進程數,再將傳入的請求傳遞給子進程處理
# threads: 將創建一個新的線程來處理每個傳入請求
B、以一個論壇爲例(論壇的帖子表被分割爲post、post_1、post_2),當搜索時由bbs.conf接受搜索關鍵詞,並將接受的關鍵詞轉發給三個子進程(bbs_9310.conf、bbs_9311.conf、bbs_9312.conf)的搜索服務上;
1、bbs.conf配置如下:
index bbs_thread_distributed {
# 索引類型。可用的值包括plain(普通本地索引)、distributed(分佈式)或rt(實時索引)。可選選項,默認值爲plain(索引爲普通本地索引)
type = distributed
# 聲明搜索分佈式索引時要搜索的遠程代理
agent = 127.0.0.1:9310:bbs_main_0
agent = 127.0.0.1:9311:bbs_main_1
agent = 127.0.0.1:9312:bbs_main_2
# 設置文檔的字符集
charset_type = utf-8
# 遠程代理的連接超時時間,單位爲毫秒。可選選項,默認爲1000(即1秒)
agent_connect_timeout = 1000
# 遠程代理查詢超時時間,以毫秒爲單位。可選選項,默認爲3000
agent_query_timeout = 3000
}
searchd {
listen = 127.0.0.1:9300
# 搜索系統日誌
log= /home/logs/sphinx/9300.searchd.log
# 搜索查詢日誌
query_log = /home/logs/sphinx/9300.query.log
# 子進程的最大數量(或者說,並行執行的搜索的數目)。可選項,默認爲0,不限制
max_children = 30
# PID文件會在啓動時重建, 必選項
pid_file = /home/sphinx/9300.searchd.pid
# 最大返回匹配數
max_matches = 10000
# 防止 searchd 輪換在需要預取大量數據的索引時停止響應。可選選項,默認爲1(啓用無縫(seamless)輪換)
seamless_rotate = 1
# 索引輪換成功之後,是否刪除以.old爲擴展名的索引拷貝。可選選項,默認爲1
unlink_old = 1
。。。。。。
# 多處理模式(MPM)。 可選項;可用值爲none、fork、prefork,以及threads。 默認在Unix類系統爲form,Windows系統爲threads
workers = prefork # for RT to work
}
2、各子進程配置如下(bbs_9310.conf爲例):
#主索引源
source bbs_main_0 {
type = mysql # 數據庫類型
sql_host = 127.0.0.1
sql_user = spinx
sql_pass = 123456
sql_db = discuz_x2
sql_port = 3306
sql_query_pre = SET NAMES utf8
}
source main : bbs_main_0 {
sql_query = SELECT p.tid as id, p.tid, p.pid, p.subject, p.message, p.dateline, p.attachment, t.views, t.replies FROM pre_forum_post p left join pre_forum_thread t on p.tid=t.tid where p.`first`=1 and p.`invisible`=0
#返回值
sql_attr_uint = tid
sql_attr_string = subject
sql_attr_uint = replies
sql_attr_uint = views
sql_attr_timestamp = dateline
}
index bbs_main_0 {
source= main # 向本地索引增加文檔源, 可以出現多次,必須選項
path = /home/sphinx/data/bbs_post/bbs_main_0
min_word_len = 2 # 最小索引詞長度,可選選項,默認爲1(索引任何詞)
charset_type = utf-8 #字符集編碼
chinese_dictionary = /usr/local/sphinx-for-chinese/var/xdict #指定分詞庫 sphinx-for-chines特有的選項
html_strip = 1 # 是否從輸入全文數據中去除HTML標記。可選標記,默認爲0。已知值包括0(禁用)和1(啓用)
.........
}
indexer {
mem_limit = 256M
}
searchd {
# 指定searchd監聽的IP地址和端口
listen = 127.0.0.1:9310
# 搜索系統日誌
log= /home/logs/sphinx/9310.searchd.log
# 搜索查詢日誌
query_log = /home/logs/sphinx/9310.query.log
# PID文件會在啓動時重建, 必選項
pid_file = /home/sphinx/9310.searchd.pid
.......
workers = threads
}
(備註:以上配置項中部分默認配置省略掉,可參考文檔配置)
五、其它:
1、關於sphinx的返回值的問題?
用sphinx服務提供api的時候,在返回值的問題上正統的做法是,根據搜索的比如帖子的tid、pid再拿着這些去再做一次查詢獲取想要的返回參數封裝成返回值,如果是一個不需要提供高效的實時索引的服務的時候感覺這種做法會影響api的性能,如果在searchd的時候就能返回需要返回的參數不就省去了一次連接查詢。但是如果用這種冗餘數據的方法來做,如果用戶對帖子標題做了修改這時數據不一致也麻煩~~~~