sphinx+MySQL+sphinxse+mmseg

Sphinx+MySQL5.1x+SphinxSE+mmseg中文分詞

搜索引擎架構(gòu)搭建手記

什么是Sphinx

Sphinx是一個(gè)全文檢索引擎,一般而言,Sphinx是一個(gè)獨(dú)立的搜索引擎,意圖為其他應(yīng)用提供高速、低空間占用、高結(jié)果相關(guān)度的全文搜索功能。Sphinx可以非常容易的與SQL數(shù)據(jù)庫和腳本語言集成。當(dāng)前系統(tǒng)內(nèi)置MySQL和PostgreSQL數(shù)據(jù)庫數(shù)據(jù)源的支持,也支持從標(biāo)準(zhǔn)輸入讀取特定格式的XML數(shù)據(jù)。通過修改源代碼,用戶可以自行增加新的數(shù)據(jù)源(例如:其他類型的DBMS的原生支持)。

Sphinx的特性

 高速的建立索引(在當(dāng)代CPU上,峰值性能可達(dá)到10 MB/秒);

 高性能的搜索(在2–4GB的文本數(shù)據(jù)上,平均每次檢索響應(yīng)時(shí)間小于0.1秒);

 可處理海量數(shù)據(jù)(目前已知可以處理超過100 GB的文本數(shù)據(jù),在單一CPU的系統(tǒng)上可處理100 M文檔);

 提供了優(yōu)秀的相關(guān)度算法,基于短語相似度和統(tǒng)計(jì)(BM25)的復(fù)合Ranking方法;支持分布式搜索;

provides documentexceprts generation;

 可作為MySQL的存儲(chǔ)引擎提供搜索服務(wù);

 支持布爾、短語、詞語相似度等多種檢索模式;

 文檔支持多個(gè)全文檢索字段(最大不超過32個(gè));

 文檔支持多個(gè)額外的屬性信息(例如:分組信息,時(shí)間戳等);

 停止詞查詢;

 支持單一字節(jié)編碼和UTF-8編碼;

 原生的MySQL支持(同時(shí)支持MyISAM和InnoDB);

原生的PostgreSQL支持.

安裝

本文以CentOS5.5+mysql-5.1.55+sphinx-0.9.9(coreseek-3.2.14.tar.gz)為例介紹

Sphinx+MySQL5.1x+SphinxSE存儲(chǔ)引擎+mmseg中文分詞搜索引擎架構(gòu)搭建過程。

1.安裝MySQL+SphinxSE,進(jìn)入軟件包目錄

tar zxvfmysql-5.1.55.tar.gz

tar zxvfsphinx-0.9.9.tar.gz

cp -rsphinx-0.9.9/mysqlse/ mysql-5.1.55/storage/sphinxà把sphinx的源代碼復(fù)制到mysql源碼中

cdmysql-5.1.55

./BUILD/autorun.sh

./configure

--prefix=/usr/local/webserver/mysql/ --enable-assembler

--with-extra-charsets=complex --enable-thread-safe-client --with-big-tables

--with-readline --with-ssl --with-embedded-server --enable-local-infile

--with-plugins=partition,innobase,myisammrg,sphinx

make

make install

#/usr/sbin/groupadd mysql

#/usr/sbin/useradd -g mysql mysql

# chmod +w/usr/local/webserver/mysql

# chown -Rmysql:mysql /usr/local/webserver/mysql

①、創(chuàng)建MySQL數(shù)據(jù)庫存放目錄

#---------------------------------+

# mkdir -p /data0/mysql/3306/data/

# chown -Rmysql:mysql /data0/mysql/

#---------------------------------+

②、以mysql用戶帳號(hào)的身份建立數(shù)據(jù)表:

#---------------------------------+

#/usr/local/webserver/mysql/bin/mysql_install_db--basedir=/usr/local/webserver/mysql --datadir=/data0/mysql/3306/data--user=mysql

#---------------------------------+

③、創(chuàng)建my.cnf配置文件:

#--------------------------------+

# vi /data0/mysql/3306/my.cnf

#--------------------------------+

my.cnf輸入以下內(nèi)容:

[client]

default-character-set= utf8

port = 3306

socket =/tmp/mysql.sock

[mysql]

no-auto-rehash

[mysqld]

user = mysql

port = 3306

socket =/tmp/mysql.sock

basedir =/usr/local/webserver/mysql

datadir =/data0/mysql/3306/data

open_files_limit= 10240

back_log = 600

max_connections= 3000

max_connect_errors= 6000

table_cache =614

external=locking= FALSE

max_allowed_packet= 32M

sort_buffer_size= 2M

join_buffer_size= 2M

thread_cache_size= 300

thread_concurrency= 8

query_cache_size= 32M

query_cache_limit= 2M

query_cache_min_res_unit= 2k

default-storage-engine= MyISAM

default_table_type= MyISAM

thread_stack =192K

transaction_isolation= READ-COMMITTED

tmp_table_size= 246M

max_heap_table_size= 246M

long_query_time= 1

log_long_format

log-bin = /data0/mysql/3306/binlog

binlog_cache_size = 4M

binlog_format= MIXED

max_binlog_cache_size= 8M

max_binlog_size= 512M

expire_logs_days= 7

key_buffer_size= 256M

read_buffer_size= 1M

read_rnd_buffer_size= 16M

bulk_insert_buffer_size= 64M

myisam_sort_buffer_size= 128M

myisam_max_sort_file_size= 10G

myisam_repair_threads= 1

myisam_recover

skip-name-resolve

master-connect-retry= 10

slave-skip-errors= 1032,1062,126,1114,1146,1048,1396

server-id = 1

[mysqldump]

quick

max_allowed_packet= 32M

#--------------------------------開啟MYSQL:---------------+

/usr/local/webserver/mysql/bin/mysqld_safe--defaults-file=/data0/mysql/3306/my.cnf 2>&1 > /dev/null &

#-----------------------------------------------------------+

#--------------------------------關(guān)閉MYSQL:---------------+

/usr/local/webserver/mysql/bin/mysqladmin-u root -p -S /tmp/mysql.sock shutdown

#-----------------------------------------------------------+

⑦、通過命令行登錄管理MySQL服務(wù)器(提示輸入密碼時(shí)直接回車):

#----------------------------------------------------------------+

#/usr/local/webserver/mysql/bin/mysql -u root -p -S /tmp/mysql.sock

#----------------------------------------------------------------+

。

安裝完成啟動(dòng)MySQL后查看sphinx存儲(chǔ)引擎是否安裝成功

在mysql命令行下執(zhí)行

show engines;

如果出現(xiàn)如下圖紅色方框內(nèi)的信息說明SphinxSE已經(jīng)安裝成功!

安裝Sphinx全文檢索服務(wù)器

Sphinx默認(rèn)不支持中文索引及檢索,以前用Coreseek的補(bǔ)丁來解決,目前Coreseek不單獨(dú)提供補(bǔ)丁文件,而基于sphinx開發(fā)了Coreseek全文檢索服務(wù)器,Coreseek應(yīng)該是現(xiàn)在用的最多的sphinx中文全文檢索,它提供了為Sphinx設(shè)計(jì)的中文分詞包LibMMSeg包含mmseg中文分詞,其實(shí)coreseek-3.2.14.tar.gz中已經(jīng)包含了sphinx,前面安裝SphinxSE時(shí)也可以使用這個(gè)壓縮包里的mysqlse。

我們來看一下的安裝過程:

安裝autoconf

Bzip2 –dautoconf-2.65.tar.bz2

tar xvfautoconf-2.65.tar

cdautoconf-2.65

./configure--prefix=/usr

make

make install

cd ..

安裝Coreseek

tar zxvfcoreseek-3.2.14.tar.gz

cdcoreseek-3.2.14

cdmmseg-3.2.14/

./bootstrap

./configure--prefix=/usr/local/mmseg3

make

make install

cd../csft-3.2.14/

shbuildconf.sh

./configure--prefix=/usr/local/coreseek --without-python --without-unixodbc --with-mmseg--with-mmseg-includes=/usr/local/mmseg3/include/mmseg/--with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql=/usr/local/webserver/mysql--host=arm

make

make install

ln -s/usr/local/webserver/mysql/lib/mysql/libmysqlclient.so.16 /usr/lib

cd/usr/local/coreseek/etc

進(jìn)入配置目錄通過命令ls可以看到3個(gè)文件

example.sqlsphinx.conf.distsphinx-min.conf.dist

其中example.sql是示例sql腳本我們將其導(dǎo)入到數(shù)據(jù)庫中的test數(shù)據(jù)庫中作為測試數(shù)據(jù)(會(huì)創(chuàng)建兩張表documents和tags)

vi sphinx.conf

輸入以下內(nèi)容

#定義一個(gè)數(shù)據(jù)庫源,名字為src1

source src1

{

type=mysql

sql_host=localhost

sql_user=root

sql_pass=

sql_db= test

sql_port=3306# optional, default is 3306

sql_sock= /tmp/mysql.sock

sql_query_pre= SET NAMES utf8

sql_query=\

SELECT id,title,content FROM songs

sql_query_info= SELECT * FROM songs WHERE id=$id

}

#定義建立索引項(xiàng)

index test1

{

source=src1

path=/usr/local/coreseek/var/data/test1

charset_type= zh_cn.utf-8

charset_dictpath= /usr/local/mmseg3/etc/

}

#建索引程序的設(shè)置

indexer

{

#建索引時(shí)所用的內(nèi)存限制

mem_limit=32M

}

#提供服務(wù)的進(jìn)程配置

searchd

{

port=9312

log=/usr/local/coreseek/var/log/searchd.log

query_log=/usr/local/coreseek/var/log/query.log

read_timeout=5

max_children=30

pid_file=/usr/local/coreseek/var/log/searchd.pid

max_matches=1000

seamless_rotate= 1

preopen_indexes= 0

unlink_old=1

}

說明:

代碼段source src1{***}代表數(shù)據(jù)源里面主要包含了數(shù)據(jù)庫的配置信息,src1表示數(shù)據(jù)源名字,可以隨便寫。

代碼段index test1{***}代表為哪個(gè)數(shù)據(jù)源創(chuàng)建索引,與source ***是成對(duì)出現(xiàn)的,其中的source參數(shù)的值必須是某一個(gè)數(shù)據(jù)源的名字。

其他參數(shù)可以查看手冊,這里不再贅述。

生成索引

/usr/local/coreseek/bin/indexer-c /usr/local/coreseek/etc/sphinx.conf --all

其中參數(shù)--all表示生成所有索引

當(dāng)然也可以是索引的名字例如:/usr/local/coreseek/bin/indexer-c /usr/local/coreseek/etc/sphinx.conf test1

執(zhí)行后可以在/usr/local/coreseek/var/data目錄中看到多出一些文件,是以索引名為文件名的不同的擴(kuò)展名的文件

在不啟動(dòng)sphinx的情況下即可測試命令:

/usr/local/coreseek/bin/search -c/usr/local/coreseek/etc/sphinx.conf number

可以看到將內(nèi)容中含有number數(shù)據(jù)的數(shù)據(jù)查詢出來。

/usr/local/coreseek/bin/search

-c /usr/local/coreseek/etc/sphinx.conf研究生創(chuàng)業(yè)

可以看到我們輸入的查詢文字已經(jīng)被拆分成了兩個(gè)詞,只是因?yàn)槲覀兊臏y試數(shù)據(jù)中沒有中文數(shù)據(jù)查詢結(jié)果為空。我們插入幾條新數(shù)據(jù)。

INSERT INTO`test`.`documents` (

`id` ,

`group_id` ,

`group_id2` ,

`date_added` ,

`title` ,

`content`

)

VALUES (

NULL , '2',

'3', '2011-02-01 00:37:12', '研究生的故事', '研究生自主創(chuàng)業(yè)'

), (

NULL , '1',

'1', '2011-01-28 00:38:22', '研究', '為了創(chuàng)業(yè)而研究生命科學(xué)'

);

我們再來看以下數(shù)據(jù)庫中的主要數(shù)據(jù)

插入新數(shù)據(jù)后需要重新生成索引

/usr/local/coreseek/bin/indexer-c /usr/local/coreseek/etc/sphinx.conf test1

然后執(zhí)行查詢測試/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf研究生創(chuàng)業(yè)

我們搜索的詞語是“研究生創(chuàng)業(yè)”,可以看到詞語被拆分成了研究生和創(chuàng)業(yè)兩個(gè)詞,雖然有兩條記錄都包含“創(chuàng)業(yè)和”研究生”這幾個(gè)字但是“研究生命科學(xué)”中的“研究生”三個(gè)字雖然是緊挨著的但是不是一個(gè)詞語,結(jié)果是只匹配一條“研究生自主創(chuàng)業(yè)”,我們在搜索“研究”這個(gè)詞語

/usr/local/coreseek/bin/search

-c /usr/local/coreseek/etc/sphinx.conf研究

同樣匹配一條記錄,而“研究生的故事”和“研究生自主創(chuàng)業(yè)”的詞語卻沒有被查詢出來,可以看出sphinx與分詞技術(shù)結(jié)合可以匹配出相關(guān)度更高的結(jié)果。

當(dāng)然我們的目的不僅限與命令行下的測試,我們可以通過搜索API調(diào)用來執(zhí)行搜索,搜索API支持PHP、Python、Perl、Rudy和Java。如果從PHP腳本檢索需要先啟動(dòng)守護(hù)進(jìn)程searchd,PHP腳本需要連接到searchd上進(jìn)行檢索:

/usr/local/coreseek/bin/searchd

-c /usr/local/coreseek/etc/sphinx.conf

在解壓后的sphinx-0.9.9/api目錄下的sphinxapi.php就是sphinx官方為我們提供的API文件(其實(shí)也可以使用PHP的sphinx擴(kuò)展),只需將其包含進(jìn)自己的PHP腳本文件就可以了。

示例代碼:


include('sphinxapi.php');

$cl=newSphinxClient();

//設(shè)置sphinx服務(wù)器地址與端口,如果是本機(jī)則可以為localhost

$cl->SetServer("192.168.16.6",9312);

//以下設(shè)置用于返回?cái)?shù)組形式的結(jié)果

$cl->SetArrayResult (true);

//$cl->SetMatchMode( SPH_MATCH_ANY);//匹配模式

//$cl->SetFilter( 'group_id', array( 2 ) );

$result=$cl->Query('研究生創(chuàng)業(yè)','test1');//參數(shù) 關(guān)鍵字索引名

if($result===false) {

echo"Query failed: ".$cl->GetLastError() .".\n";

}

else{

if($cl->GetLastWarning() ) {

echo"WARNING: ".$cl->GetLastWarning() ."";

}

echo'<pre>';

print_r($result);

}

?>

執(zhí)行后的結(jié)果:

Array

(

[error] =>

[warning] =>

[status] => 0

[fields] => Array

(

[0] => title

[1] => content

)

[attrs] => Array

(

[group_id] => 1

[date_added] => 2

)

[matches] => Array

(

[5] => Array

(

[weight] => 2

[attrs] => Array

(

[group_id] => 2

[date_added] => 1296491832

)

)

)

[total] => 1

[total_found] => 1

[time] => 0.078

[words] => Array

(

[研究生] =>Array

(

[docs] => 1

[hits] => 2

)

[創(chuàng)業(yè)] =>Array

(

[docs] => 2

[hits] => 2

)

)

)

在matches中的就是查詢結(jié)果,我們注意到sphinx是將記錄中的主鍵ID值返回而不是返回所有數(shù)據(jù),上面的例子中的鍵名5就是記錄的ID(如果在查詢前執(zhí)行$cl->SetArrayResult

( true );則數(shù)組結(jié)構(gòu)會(huì)有些許差異)。至此搜索服務(wù)器已經(jīng)為我們完成了大部分工作,接下來我們通過主鍵ID值來查詢我們想要的數(shù)據(jù)就可以了。

Sphinx存儲(chǔ)引擎的使用

SphinxSE是一個(gè)可以編譯進(jìn)MySQL 5.x版本的MySQL存儲(chǔ)引擎,它利用了該版本MySQL的插件式體系結(jié)構(gòu)。盡管被稱作“存儲(chǔ)引擎”,SphinxSE自身其實(shí)并不存儲(chǔ)任何數(shù)據(jù)。它其實(shí)是一個(gè)允許MySQL服務(wù)器與searchd交互并獲取搜索結(jié)果的嵌入式客戶端。所有的索引和搜索都發(fā)生在MySQL之外。

SphinxSE的適用于:

 使將MySQL FTS應(yīng)用程序移植到Sphinx

 使沒有Sphinx API的那些語言也可以使用Sphinx

 當(dāng)需要在MySQL端對(duì)Sphinx結(jié)果集做額外處理(例如對(duì)原始文檔表做JOIN,MySQL端的額外過濾等等)時(shí)提供優(yōu)化。

要通過SphinxSE搜索,需要建立特殊的ENGINE=SPHINX的“搜索表”,然后使用SELECT語句從中檢索,把全文查詢放在WHERE子句中。

創(chuàng)建一張表t1

CREATE TABLEt1

(

idINTEGER UNSIGNED NOT NULL,

weightINTEGER NOT NULL,

queryVARCHAR(3072) NOT NULL,

group_idINTEGER,

INDEX(query)

)ENGINE=SPHINX CONNECTION="sphinx://localhost:9312/test1";

搜索表前三列的類型必須是INTEGER,INTEGER和VARCHAR,這三列分別對(duì)應(yīng)文檔ID,匹配權(quán)值和搜索查詢。查詢列必須被索引,其他列必須無索引。列的名字會(huì)被忽略,所以可以任意命名,參數(shù)CONNECTION來指定用這個(gè)表搜索時(shí)的默認(rèn)搜索主機(jī)、端口號(hào)和索引,語法格式:CONNECTION="sphinx://HOST:PORT/INDEXNAME"。

執(zhí)行SQL語句select d.id,d.title,d.content from t1 join documents as d on t1.id

= d.id and t1.query = '研究生創(chuàng)業(yè)';

+----+--------------------+-----------------------+

| id |title| content|

+----+--------------------+-----------------------+

|5 |研究生的故事|研究生自主創(chuàng)業(yè)|

+----+--------------------+-----------------------+

1 row in set(0.04 sec)

結(jié)果返回了我們想要的數(shù)據(jù),可見利用SphinxSE可以僅僅在SQL語句上做很小的改動(dòng)即可很方便的實(shí)現(xiàn)全文檢索!

主索引+增量索引

前提:數(shù)據(jù)不會(huì)被改變

第一步:建表:(用來存索引過的最大的記錄id)

Create table a

{

Id int unsigned not nullprimary key,

Max_idint unsigned,

}

第二步:修改配置文件為:見sphinx配置文件.doc

第三步:先執(zhí)行./bin/indexer–c ./etc/sphinx.conf –test1生成所有的索引-〉一個(gè)數(shù)據(jù)源的主查詢,只有第一次執(zhí)行

第四步:定期執(zhí)行:./bin/indexer–c./etc/sphinx.conf delta --rotateà生成增量的索引文件

第五步:合并到主索引中./bin/indexer –merge test1 delta –c ./etc/sphinx.conf --rotate

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容