2010年7月15日 星期四

【轉貼】开源搜索引擎sphinx探秘

开源搜索引擎sphinx探秘

Sphinx是一个开源的搜索引擎,最近对它进 行了一些研究.
安装就不说了,比较简单.
1 工具列表
安装完毕后,在bin下有如下工具可供使用:
         indexer--用来创建全文索引的东西,可以用crontab来定期重建索引
         search--命令行工具,用来一次性搜索
         searchd--后台运行的服务,可以为web应用程序提供服务
         sphinxapi:—api集合,可以通过应用程序来调用sphinx,比如php
         spelldump
         indextool--分析和调试索引的工具






2 文档精华
官方文档:http://www.sphinxsearch.com/docs/manual-0.9.9.html
写的很详细,下面是我摘录的一些:
(1)   产生索引的数据可以来自多种数据源:可以是数据库,可以是普通的文本文件,可以是html文件,邮件夹等.对于sphinx引擎,sql数据比较特殊:每 一行被视为一个文件,而行的字段被视为域.
(2)   针对每种不同的查询,可以建立不同的多个索引:searchd可以为各种索引服务,但是客户端在查询的时候,可以指定用哪个索引来实现查询
(3)   对于每一个索引,都可以有若干的数据源,搜索引擎会按照数据源定义的顺序来排序.而对外部看来,就好像是从同一个数据源获取的数据
(4)   目前sphinx只支持一种索引的类型,它建立索引和查找数据的速度相当快,缺点是更新索引的速度比较慢,以至于更新某个索引项还不如重建整个索引来得 快.未来的版本可能会支持更多的索引类型,包括可以适时更新的索引
(5)   对数据源的限制,最重要的一点就是:文档id必须是整型的唯一的非零的
3 mysql作为数据源建立index的过程
在mysql数据库作为数据源的情况下,建立索引的过程一般如下:
         (1)连接数据库
         (2) 执行前语句(pre-query):一般会有set names等语句,指定字符集等
         (3)main query---sphinx是根据main query来返回数据,并建立索引
         (4)清理现场语句(post-query):比如set names
         (5)主动断开与数据库的连接
         (6)建立索引等
         (7)重新连接数据库
         (8)post-index—执行最后的清理语句
         (9)关闭连接
上面的过程中,两次连接数据库,是因为建立索引的时间较长,可能导致连接数据库的会话超时,所以在索引建立完成后需要再次连接数据库执行一些清理工作

4 优化策略举例
4.1 对搜索结果进行分组,减轻mysql服务器本身的压力
从理论上来说,可以通过搜索,得到结果后,用sql语句来进行group,但是这会极大的影响数据库的效率.sphinx提供了一种更好的方法,它可以对 搜索引擎的结果进行分组,而不用对mysql数据库进行group查询,这在返回大结果集的时候对效率有很大提升

4.2 分布式的搜索引擎,解决单个索引数据量太大的难题
Partitioning is done manually. You should:
         setup several instances of Sphinx programs (indexer and searchd) on different servers;
         make the instances index (and search) different parts of data
         configure a special distributed index on some of the searchd instances;
         and query this index.

4.3 准适时的索引重建策略,提高重建和查询的效率
适时的索引更新:当已有的索引很大而且相对稳定,但是新增的索引比较频繁但是数量很少的时候,可以采用main+delta的方式来建立索引.经过一段时 间后,可以采用indexer --merge DSTINDEX SRCINDEX [--rotate]的index merge的方法,把delta更新到原来的索引中.如此周期性的”重建索引.这种准适时的方法比适时的建立索引更快,而且对应用几乎是透明的.

5 sphinx支持mysql协议
Sphinx支持mysql的协议,可以通过mysql的客户端工具mysql直接连接sphinx,然后用SphinxQL来执行查询,你甚至不需要有 mysqld服务器在运行,方法如下:
在searchd的配置文件中加入listen = 9315:mysql41,然后重启searchd.连接searchd服务器:
./mysql -P 9315 -u root -p --protocol=tcp(一定要指明是 tcp协议哈,否则-P参数没有任何意义),登陆进去,执行status,可以看到:
Server version:         0.9.9-release (r2117)
Protocol version:       10
Connection:             localhost via TCP/IP
Client characterset:    utf8
Server characterset:    utf8
TCP port:            9315
执行查询:

SELECT * FROM test1 WHERE MATCH('test');
+------+--------+----------+------------+

| id   | weight | group_id | date_added |
+------+--------+----------+------------+
|    1 |   2421 |        1 | 1267439989 |
|    2 |   2421 |        1 | 1267439989 |
|    4 |   1442 |        2 | 1267439989 |
+------+--------+----------+------------+
3 rows in set (0.01 sec),呵呵,so cool.

特别注意:Specifically "localhost" will force it to use UNIX socket (this is the default and generally recommended mode) and "127.0.0.1" will force TCP/IP usage.
6 sphinx与mysql的无缝结合
当然,你还可以选择安装MySQL storage engine (SphinxSE),从官方打个补丁,然后源代码安装即可.
./configure --with-sphinx-storage-engine
make && make install

沒有留言:

張貼留言