编译安装 Sphinx
yum -y install gcc gcc-c++ automake autoconf expat expat-devel mysql-devel
cd /usr/local/src
wget -c http://sphinxsearch.com/files/sphinx-2.2.11-release.tar.gz
tar zxvf sphinx-2.2.11-release.tar.gz
cd sphinx-2.2.11-release
./configure --prefix=/usr/local/sphinx --with-mysql --with-libexpat --enable-id64
make && make install
安装依赖 libsphinxclient
cd api/libsphinxclient
./configure --prefix=/usr/local/sphinx/libsphinxclient
make && make install
安装 PHP7 的 Sphinx 扩展
cd /user/local/src
wget http://git.php.net/?p=pecl/search_engine/sphinx.git;a=snapshot;h=d958afb6c587f08eee37602dbd8518afdcd72916;sf=tgz
tar zxvf sphinx-d958afb.tar.gz
cd sphinx-d958afb
phpize
./configure --with-sphinx=/usr/local/sphinx/libsphinxclient/ --with-php-config=/usr/local/php/bin/php-config
make && make install
echo "[sphinx]" >> /usr/local/php/etc/php.ini
echo "extension = sphinx.so" >> /usr/local/php/etc/php.ini
systemctl restart nginx
/etc/init.d/php-fpm restart
创建索引测试
cd /usr/local/sphinx/etc/
cp sphinx-min.conf.dist sphinx.conf
vim sphinx.conf
source student_src
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = asdf
sql_db = laravel
sql_port = 3306
sql_sock = /tmp/mysql.sock
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type = OFF
sql_query = \
SELECT id, name, age, gender,created_at, updated_at FROM student
}
index student
{
source = student_src
path = /usr/local/sphinx/var/data/student
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
ngram_len = 1
ngram_chars = U+4E00..U+9FBF, U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF,U+2F800..U+2FA1F, U+2E80..U+2EFF, U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF,U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF,U+3130..U+318F, U+A000..U+A48F, U+A490..U+A4CF
}
indexer
{
mem_limit = 128M
}
searchd
{
listen = 9312
listen = 9306:mysql41
log = /usr/local/sphinx/var/log/searchd.log
query_log = /usr/local/sphinx/var/log/query.log
read_timeout = 5
max_children = 30
pid_file = /usr/local/sphinx/var/log/searchd.pid
seamless_rotate = 1
preopen_indexes = 1
unlink_old = 1
workers = threads
binlog_path = /usr/local/sphinx/var/data
}
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf student
vim /etc/rc.local
/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf
<?php
$keyword = 'Jerry';
$cl = new SphinxClient();
$cl->SetServer('127.0.0.1', 9312);
$index = "student";
$res = $cl->Query($keyword, $index);
$err = $cl->GetLastError();
echo "<pre>";
print_r($res);
Sphinx 增量索引和主索引来实现索引的实时更新
实现原理
-
新建一张表,记录上一次已经创建好的索引的最后一条记录的 doc_id
-
当索引时,然后从数据库中取出所有 doc_id 大于上面那个 Sphinx 中的那个 doc_id 的数据,然后创建一个小的索引文件
-
把创建的增量索引文件合并到主索引文件上去
-
把最后一条记录的 doc_id 更新到第一步创建的表中
注意点
-
当合并索引的时候,只是把增量的索引合并进主索引中,增量索引本身并不会变化,也不会被删除
-
当重建主索引的时候,增量索引就会被删除;
实现流程
- 新建一张表,用于存储已经建过索引的最大的 doc_id
CREATE TABLE `sph_counter` (
`counter_id` int(11) NOT NULL COMMENT '标识不同的数据表',
`max_doc_id` int(11) NOT NULL COMMENT '每个索引表的最大ID,会实时更新',
PRIMARY KEY (`counter_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
vim /usr/local/sphinx/etc/sphinx.conf
source student
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = asdf
sql_db = laravel
sql_port = 3306
sql_sock = /tmp/mysql.sock
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type = OFF
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM student
sql_query = \
SELECT id, name, age, gender,created_at, updated_at FROM student \
WHERE id< (SELECT max_doc_id FROM sph_counter WHERE counter_id = 1)
sql_attr_timestamp = updated_at
}
source student_delta : student
{
sql_sock = /tmp/mysql.sock
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT id, name, age, gender,created_at, updated_at FROM student \
WHERE id >= (SELECT max_doc_id FROM sph_counter WHERE counter_id = 1)
}
index student
{
source = student
path = /usr/local/sphinx/var/data/student
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
ngram_len = 1
ngram_chars = U+4E00..U+9FBF, U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF,U+2F800..U+2FA1F, U+2E80..U+2EFF, U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF,U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF,U+3130..U+318F, U+A000..U+A48F, U+A490..U+A4CF
}
index student_delta : student
{
source = student_delta
path = /usr/local/sphinx/var/data/student_delta
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
ngram_len = 1
ngram_chars = U+4E00..U+9FBF, U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF,U+2F800..U+2FA1F, U+2E80..U+2EFF, U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF,U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF,U+3130..U+318F, U+A000..U+A48F, U+A490..U+A4CF
}
indexer
{
mem_limit = 128M
}
searchd
{
listen = 9312
log = /usr/local/sphinx/var/log/searchd.log
query_log = /usr/local/sphinx/var/log/query.log
read_timeout = 5
max_children = 30
pid_file = /usr/local/sphinx/var/log/searchd.pid
seamless_rotate = 1
preopen_indexes = 1
unlink_old = 1
workers = threads
}
/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf --stop
/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all --rotate
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf student_delta --rotate
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --merge student student_delta --rotate
crontab -e
*/5 * * * /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf student_delta --rotate
5 0 * * * /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all --rotate