前言:康盛创想的Discuz!从创立之初即以提高产品效率为突破口,随着编译模板,语法生成内核,数据缓存和自动更新机制等独创或独有技术的应用,和坚固的数据结构及最少化数据库查询设计,使得 Discuz! 可以在极为繁忙的服务器环境下快速高效稳定运行。

由于Discuz!产品依赖MySQL数据库性能,在全文检索方面如果仅仅依靠MySQL的LIKE %关键词% 语句无法取得理想的成绩。本文阐述经过Discuz!生产环境考验的构建在Sphinx基础上的千万级Discuz!数据全文检索解决方案。

出自俄罗斯的开源全文搜索引擎软件Sphinx在单一索引达到4千万条记录情况下的查询速度仍为0.x秒甚至0.0x秒级别。Sphinx创建索引的速度约五分钟处理百万条记录,对于每分钟的增量索引重建只需要几十秒,每日的增量索引合并到主索引也只需一分钟左右。此构架基础上的Discuz!高负载站点,已成功解决搜索速度慢、经常锁表、无法分布式搜索等问题。

千万级Discuz!数据全文检索方案(Sphinx)适用于繁忙的站点并且论坛访问者有大量的搜索需求,本方案主要解决搜索缓慢问题。

本文环境以CentOS 5为基准。初始化一次全部索引,按系统计划任务crontab定时方式,每5分钟重建一次增量索引(增量索引不与主索引合并),每日凌晨3:30建立一次昨日比较的增量索引(合并到主索引中)。主索引建立在磁盘目录/data/sphdata,增量索引建立在内存/dev/shm/中避免大量的I/O操作,由于帖子编辑限制,全部索引每两个月重建一次。

 

Sphinx快速介绍

Sphinx是独立的搜索服务端,不依赖MySQL,当Sphinx和MySQL结合部署时,Sphinx的数据来源为MySQL。服务器安装Sphinx,由sphinx.conf配置文件指定Sphinx的数据源,如何读取MySQL的数据内容,设置Sphinx对MySQL数据库的哪个表哪些字段建立索引,索引的返回数据必须是数值型。 

例如一个配置段设置Sphinx对cdb_threads表的subject和author字段建立索引,搜索结果可以返回tid和uid。另一个配置段设置Sphinx对cdb_posts表的subject和message字段索引,搜索结果返回tid和pid。

Sphinx建立的索引只是查询MySQL数据库获取数据内容,将索引存放在Sphinx的数据文件和内存中,一般不对MySQL数据库进行修改操作。 

因为Sphinx独立运行,使用SELECT FROM cdb_threads WHERE subject LIKE '%关键词%' LIMIT 0, 10;  类似的SQL语句将无法利用Sphinx搜索,即使服务器端已经部署Sphinx也不会对该查询语句有任何优化作用。 

 

正确使用Sphinx搜索数据的操作方式主要有三种:

1、命令行的search工具:/usr/local/webserver/sphinx/bin/search –i threads test

2、php的api接口查询:原理是直接用fsockopen连接端口,传递数据取得返回结果。 Sphinx官方已经提供php的api接口,可以include api查询(本方案以该查询方法为主),也可以将其源代码编译成php扩展而无需include。

3、在mysql中将Sphinx安装为SphinxSE存储引擎,通过SphinxSE方式调用Sphinx。 

 

因Sphinx搜索结果只返回INT类型数据,部署Sphinx搜索的核心是由搜索入口(search.php)提交的关键词到Sphinx中搜索,Sphinx返回对应的tid、pid等信息,再依据tid、pid到cdb_threads或者cdb_posts中搜索,得到结果集展示在页面上。

Sphinx的搜索速度非常快,而tid/pid都是主键查询,总体来说虽然用了多次查询,但是速度仍然非常快。

 

一、 Sphinx全文检索方案构架图

 

二、 Sphinx中文分词

打过Sphinx官方补丁的Sphinx可以支持utf8、gbk等编码的汉字,按单个汉字切分,汉语搜索中应以词为依据,独立存在的单个汉字搜索几乎没有意义。本文介绍的构架方案以CoreSeek的CSFT修改版为主,由libmmseg对搜索词予以分词切分,Sphinx按切分词建立相应索引从而建立以词和短语为基准的搜索。

三、 Sphinx安装步骤

1. 安装、升级所需的程序库

yum -y install gcc gcc-c++ autoconf python python-devel libiconv

2. 创建安装文件夹并下载源代码

mkdir –p /data/software

cd /data/software

wget http://www.coreseek.cn/uploads/csft/3.1/Source/mmseg-3.1.tar.gz

wget http://www.coreseek.cn/uploads/csft/3.1/Source/csft-3.1.tar.gz

3. 安装MMseg中文分词

tar -xzf mmseg-3.1.tar.gz

cd mmseg-3.1

./configure --prefix=/usr/local/webserver/mmseg

make

make install

cd ..

4. 安装CSFT(Sphinx的CoreSeek修改版)

tar -xzf csft-3.1.tar.gz

cd csft-3.1

./configure --prefix=/usr/local/webserver/csft --with-mmseg=/usr/local/webserver/mmseg/bin/mmseg --with-mmseg-includes=/usr/local/webserver/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/webserver/mmseg/lib/ --with-mysql=/usr/local/webserver/mysql/

make

make install

cd ..

5. 编译Sphinx过程可能出现的错误

a) 无法找到mysql路径

确认 –with-mysql=之后的路径正确,是当前mysql所在路径。如果mysql是通过rpm或者yum方式安装,直接 –with-mysql 使用默认路径即可。失败尝试指定 –with-mysql-includes=路径 –with-mysql-libs=路径

b) 无法找到libiconv

libiconv通过yum方式安装的,可以直接识别。源代码编译安装的,需要建立在/usr/lib和/usr/local/lib下建立相应的软链。ln –s 源文件 目标文件。或者将libiconv的目录加入到ld.so.conf(例如libiconv安装在/usr/local/lib/目录中)

echo /usr/local/lib/ >> /etc/ld.so.conf

ldconfig

若仍提示libiconv无法找到,需要修改vi src/Makefile 文件,找 LIBS 开头的行,

LIBS -lm -lz -lexpat  -L/usr/local/lib –lpthread

修改成

LIBS -lm -lz -lexpat -liconv -L/usr/local/lib -lpthread

c) 无法找到libmysqlclient.so.15

将libmysqlclient.so.15建立软链到/usr/local/lib和/usr/lib目录下,或者加入到ld.so.conf

echo /usr/local/webserver/mysql/lib/mysql/ >> /etc/ld.so.conf

ldconfig

d) php 5.2.11版本的api BUG

当站点的php版本为5.2.11,并且通过php api方式获取Sphinx数据,数据超过1000条的情况下有BUG,无法解析正确的数据包。遇到此情况必须重新编译php版本,目前已知php 5.2.10是与Sphinx API结合非常稳定的版本。

e) 生成索引时容易发生磁盘空间不足写入失败的错误

需要注意配置文件中设置的Sphinx索引数据存放目录,确保有足够的存储空间。Sphinx的索引文件占用的空间略小于数据库数据文件本身占用的空间。

6. 安装为php扩展(可选)

cd csft-3.1/api/libsphinxclient

CXXCPP="gcc -E" ./configure --prefix=/usr/local/webserver/csft

make

make install

cd ../../

/usr/local/webserver/php/bin/phpize

./configure --with-sphinx=/usr/local/webserver/csft

make

make install

7. 安装SphinxSE存储引擎(可选)

安装SphinxSE需要重新编译MySQL,简要介绍另一种搜索方法。

cp -rf csft-3.1/mysqlse mysql-5.1.42/storage/sphinx

cd mysql-5.1.42

sh 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=sphinx

make && make install

cd ../

 

via.http://blog.sina.com.cn/s/blog_a879eea30102v1lp.html