sphinx全文索引教程 .

110 篇文章 1 订阅
85 篇文章 0 订阅
一、首先需要在服务器上安装sphinx
在Windows上安装sphinx
    1.下载支持mysql的包   http://www.sphinxsearch.com/downloads/sphinx-0.9.9-win32.zip
    2.解压缩 sphinx-0.9.9-win32.zip 到 D:\sphinx
    3.安装sphinx服务,在命令行执行命令
 

D:\sphinx\searchd --install --config d:\sphinx\sphinx.conf --servicename SphinxSearch


    英文参照:http://www.sphinxsearch.com/docs ... #installing-windows

在Linux服务器上安装sphinx
   1.下载源码包 http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz

 

$ tar xzvf sphinx-0.9.8.tar.gz
                $ cd sphinx
                $ 
./configure --prefix=/usr/local/sphinx --with-mysql=/usr/local/mysql
                $ make
                $ make install

 常见问题1

 


                
/usr/local/sphinx-0.9.9/src/sphinx.cpp:20060: undefined reference to `libiconv_open'
                /usr/local/sphinx-0.9.9/src/sphinx.cpp:20078: undefined reference to `
libiconv'
                /usr/local/sphinx-0.9.9/src/sphinx.cpp:20084: undefined reference to `libiconv_close'

                collect2
: ld returned 1 exit status
                make
[2]: *** [indexer] Error 1
                make
[2]: Leaving directory `/home/jling/sphinx-0.9.9/src'
                make[1]: *** [all] Error 2
                make[1]: Leaving directory `
/home/jling/sphinx-0.9.9/src'
                make: *** [all-recursive] Error 1

解决办法:打开configure文件,找到“#define USE_LIBICONV 1”,将注释去掉,并将1改成0。


常见问题2

 


                error 
while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or directory


解决办法:

 


                
64位系统ln -/usr/local/webserver/mysql/lib/mysql/libmysqlclient.so.16.0.0 /usr/lib64/libmysqlclient.so.16
                
32位系统ln -/usr/local/webserver/mysql/lib/mysql/libmysqlclient.so.16.0.0 /usr/lib/libmysqlclient.so.16

 

sphinx.conf样例  

 

source main
                
{
                 type     
= mysql    #数据库类型
                 sql_host    
= 10.228.134.211 #数据库ip
                 sql_user    
= admin    #数据库用户名
                 sql_pass    
= admin    #数据库密码
                 sql_db     
= phpcms_v9   #数据库名
                 sql_port    
= 3306    # 数据库端口

  sql_query_pre = SET NAMES utf8
                 sql_query_pre 
= REPLACE INTO v9_sphinx_counter SELECT 1, MAX(searchid) FROM v9_search
                 sql_query 
= SELECT searchid, adddate, siteid, typeid, id, data FROM v9_search \
                    WHERE searchid
>=$start AND searchid<=$end
                 sql_query_range  
= SELECT 1,max_doc_id FROM v9_sphinx_counter WHERE counter_id=1
                 sql_range_step 
= 5000

  #字符串属性设置、需要过滤、排序的时候用到
                 sql_attr_uint  
= typeid
                 sql_attr_uint  
= siteid
                 sql_attr_uint  
= id
                 sql_attr_timestamp  
= adddate
                 sql_query_info  
= SELECT * FROM v9_search WHERE searchid=$id
                
}

 source delta
                
{
                 type     
= mysql    #数据库类型
                 sql_host    
= 10.228.134.211 #数据库ip
                 sql_user    
= admin    #数据库用户名
                 sql_pass    
= admin    #数据库密码
                 sql_db     
= phpcms_v9   #数据库名
                 sql_port    
= 3306    # 数据库端口

     sql_query_pre = SET NAMES utf8
                    sql_query 
= SELECT searchid, adddate, siteid, typeid, id, data FROM v9_search \
                  WHERE searchid 
>( SELECT max_doc_id FROM v9_sphinx_counter WHERE counter_id=1 )
                 sql_query_post 
= REPLACE INTO v9_sphinx_counter SELECT 1, MAX(searchid) FROM v9_search
                 
#字符串属性设置、需要过滤、排序的时候用到
                 sql_attr_uint  
= typeid
                 sql_attr_uint  
= siteid
                 sql_attr_uint  
= id
                 sql_attr_timestamp  
= adddate
                 sql_query_info  
= SELECT * FROM v9_search WHERE searchid=$id
                
}

 #主索引
                index main
                
{
                 source 
= main
                 
# 放索引的目录
                 path 
= D:\sphinx\data\main
                 
# 编码
                 charset_type 
= utf-8
                 
# 指定utf-8的编码表
                 charset_table 
= 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
                 
# 简单分词,只支持0和1,如果要搜索中文,请指定为1
                 ngram_len 
= 1
                 
# 需要分词的字符,如果要搜索中文,去掉前面的注释
                 ngram_chars   
= U+3000..U+2FA1F
                
}

 #增量索引
                index delta
                
{
                    source 
= delta
                    path 
= D:\sphinx\data\delta
                 
# 编码
                 charset_type 
= utf-8
                 
# 指定utf-8的编码表
                 charset_table 
= 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
                 
# 简单分词,只支持0和1,如果要搜索中文,请指定为1
                 ngram_len 
= 1
                 
# 需要分词的字符,如果要搜索中文,去掉前面的注释
                 ngram_chars   
= U+3000..U+2FA1F
                
}
                 

 indexer
                
{
                 mem_limit    
= 128M
                
}

 searchd
                
{
                 port     
= 9312
                 log      
= D:\sphinx\data\phpcms\searchd.log
                 query_log    
= D:\sphinx\data\phpcms\query.log
                 read_timeout   
= 5
                 max_children   
= 30
                 pid_file    
= D:\sphinx\data\phpcms\searchd.pid
                 max_matches    
= 2000
                 seamless_rotate   
= 0
                 preopen_indexes   
= 0
                 unlink_old    
= 1
                
}

 

附件:设置计划任务更新索引
1.windows下
需要设置计划任务
#凌晨4点合并索引,执行merge.bat
#其余时间每分钟更新索引,执行delta.bat
 
merge.bat  


       


                
@ECHO off

                D
:\sphinx\bin\indexer.exe --config D:\sphinx\sphinx.conf --merge main delta --rotate

                echo indexing
, window will close when complete

                 

 

delta.bat

 


                
@ECHO off
                D
:\sphinx\bin\indexer.exe --config D:\sphinx\sphinx.conf delta --rotate
                echo indexing
, window will close when complete


2.linux下编辑定时任务 crontab -e

 


                
#凌晨4点合并索引,其余时间每分钟更新索引
                
* 0-3 * * * /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/sphinx.conf delta --rotate
                
* 6-23 * * * /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/sphinx.conf delta --rotate
                
0 4 * * * /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/sphinx.conf --merge main delta --rotate


各种路径、权限需要应用所在服务器一致,如:
sphinx.conf 中需要配置
sql_host 数据库主机地址
sql_user 数据库用户名
sql_pass 数据库密码
sql_db 数据库名
sql_port 数据库端口
phpcms表前缀样例中为phpcms_
索引路径 D:\sphinx\data\delta

phpcmsv9_withsphinx.zip





一.sphinx增量索引的设置
   数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到。全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少。例如。原来的数据有几百万条,而新增的只是几千条。这样就可以使用“主索引+增量索引”的模式来实现近乎实时更新的功能。
 

    这个模式实现的基本原理是设置两个数据源和两个索引,为那些基本不更新的数据建立主索引,而对于那些新 增的数据建立增量索引。主索引的更新频率可以设置的长一些(例如设置在每天的午夜进行),而增量索引的更新频率,我们可以将时间设置的很短(几分钟左 右),这样在用户搜索的时候,我们可以同时查询这两个索引的数据。

    使用“主索引+增量索引”方法有个简单的实现,在数据库中增加一个计数表,记录每次重新构建主索引时,被索引表的最后一个数据id,这样在增量索引时只需要索引这个id以后的数据即可,每次重新构建主索引时都更新这个表。

    测试条件:以默认的sphinx.conf配置为例,数据库表的数据也以 example.sql为例。

1.先在mysql中插入一个计数表和两个索引表

CREATE TABLE sph_counter(    counter_id INTEGER PRIMARY KEY NOT NULL,    max_doc_id INTEGER NOT NULL);

2.修改sphinx.conf

source main_src{

       type                = mysql

       sql_host            = localhost

       sql_user            = yourusername

       sql_pass            = yourpassword

       sql_db              = test   //你所用的数据库

       sql_port            = 3306 //所用端口,默认是3306

       sql_query_pre       = SET NAMES utf8

       sql_query_pre       = SET SESSION query_cache_type=OFF       #下面的语句是更新sph_counter表中的 max_doc_id。       sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents

       sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title,\

                 content FROM documents \

               WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) 

}

// 注意:delta_src 中的sql_query_pre的个数需和main_src 对应,否则可能搜索不出相应结果

source delta_src: main_src{

         sql_ranged_throttle = 100

         sql_query_pre       = SET NAMES utf8

         sql_query_pre       = SET SESSION query_cache_type=OFF

         sql_query      = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content FROM documents\

            WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )

}

index main //主索引{

       source           = main_src

       path             = /path/to/main

       # example:   /usr/local/sphinx/var/data/main      .............

       charset_type     = utf-8    #这个是支持中文必须要设置的

       chinese_dictionary =/usr/local/sphinx/etc/xdict       #..........其它可以默认

}

//delta可全部复制主索引,然后更改source 和path如下
 

index delta: main //增量索引{

         source = delta_src

         path     = /path/to/delta

         # example:  /usr/local/sphinx/var/data/delta…    

}

其它的配置可都用默认的,如果你设置了分布式检索的索引,那么更改下对应的索引名称即可。

3.重新建立索引:
如果sphinx正在运行,那么首先停止运行,然后,根据sphinx.conf配置文件来建立所有索引,最后,启动服务
 

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

P.S /usr/local/sphinx/bin/indexer -c  /usr/local/sphinx/etc/sphinx.conf --all --rotate

    这样就不需要停searchd,索引后也不再需要重启searchd了。

如果想测试增量索引是否成功,往数据库表中插入数据,查找是否能够检索到,这个时候检索应该为空,然后,单独重建 delta索引
/usr/local/sphinx/bin/indexer -c /usr/lcoal/sphinx/etc/sphinx.conf delta
查看是否将新的记录进行了索引。如果成功,此时,再用 /usr/local/sphing/bin/search 工具来检索,能够看到,在main索引中检索到的结果为0,而在delta中检索到结果。当然,前提条件是,检索的词,只在后来插入的数据中存在。

接下来的问题是如何让增量索引与主索引合并

4.索引合并
合并两个已有索引 有时比 重新索引所有数据有效,虽然,索引合并时,待合并的两个索引都会被读入内存一次,合并后的内容需写入磁盘一次,即,合并100GB和1GB的两个所以,将导致202GB的IO操作
命令原型:  indexer --merge DSTINDEX  SRCINDEX [--rotate]   将SRCINDEX合并到 DSTINDEX ,所以只有DSTINDEX会改变,如果两个索引都正在提供服务,那么 -- rotate 参数是必须的。例如:将delta合并到main中。
indexer --merge main delta    

5.索引自动更新
需要使用到脚本。
建立两个脚本:build_main_index.sh 和 build_delta_index.sh.

build_main_index.sh:
#!/bin/sh
# 停止正在运行的searchd
/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/mersphinx.conf  --stop >> /usr/local/sphinx/var/log/sphinx/searchd.log
#建立主索引
/usr/local/sphinx/bin/indexer -c  /usr/local/sphinx/etc/mersphinx.conf main >> /usr/local/sphinx/var/log/sphinx/mainindex.log
#启动searchd守护程序
/usr/local/sphinx/bin/searchd >> /usr/local/sphinx/var/log/sphinx/searchd.log

build_delta_index.sh

#!/bin/sh
#停止sphinx服务,将输出重定向
/usr/local/sphinx/bin/searchd –stop >> /usr/local/sphinx/var/log/sphinx/searchd.log
#重新建立索引delta ,将输出重定向
/usr/local/sphinx/bin/indexer delta –c /usr/local/sphinx/etc/sphinx.conf>>/usr/lcoal/sphinx/var/log/sphinx/deltaindex.log
#将delta合并到main中
/usr/local/sphinx/bin/indexer –merge main delta –c /usr/local/sphinx/etc/sphinx.conf >> /usr/lcoal/sphinx/var/log/sphinx/deltaindex.log
#启动服务
/usr/local/sphinx/bin/searchd >> /usr/local/sphinx/var/log/sphinx/searchd.log


脚本写好后,需要编译 chmod +x filename 这样才能运行。即
chmod +x build_main_index.sh
chmod +x build_delta_index.sh

最后,我们需要脚本能够自动运行,以实现,delta索引每5分钟重新建立,和main索引只在午夜2:30时重新建立。

使用crontab 命令 这有俩个地方可作参考 crontab  crontab文件
crontab -e 来编辑 crontab文件,如果之前没有使用,会是一个空的文件。写下下面两条语句
*/30 * * * *  /bin/sh /usr/local/sphinx/etc/build_delta_index.sh > /dev/null 2>&1
30 2 * * * /bin/sh /usr/local/sphinx/etc/build_main_index.sh > /dev/null 2>&1

第一条是表示每30分钟运行 /usr/local/sphinx/etc/下的build_delta_index.sh 脚本,输出重定向。
第二条是表示 每天的 凌晨2:30分运行 /usr/local/sphinx/etc下的build_main_inde.sh 脚本,输出重定向。
关于前面的 5个值的设置,在上面的crontab文件中有详细的描述。关于重定向的解释,请看最上面的Crontab笔记 ,也有crontab的介绍。

保存好后:重新启动服务
 

[root@test1 init.d]# service crond stop
[root@test1 init.d]# service crond start
或者
/etc/init.d/crontab   start

到现在为止,如果脚本写的没有问题,那么build_delta_index.sh将每30分钟运行一次,而build_main_index.sh将在凌晨2:30分才运行。

要验证的话,在脚本中,有将输出重定向到相关的文件,可以查看下文件中的记录是否增多,也可以看下 /usr/local/sphinx/var/log下的 searchd.log 中,每次重建索引都会有记录。

总结
1.索引合并问题,前面已经解释过,两个索引合并时,都要读入,然后还要写一次硬盘,IO操作量很大。而在php API调用时,Query($query,$index)中$index可以设置多个索引名,如Query($query,"main;delta"),也就没有必要一定将两个索引合并,或者,合并的次数不用那么多。
2.还有一个是没有尝试过的,把增量索引存放到共享内存中(/dev/shm)以提高索引性能,减少系统负荷。关于PHP API
如何能够顺利通过PHP页面来进行检索。
首先,在服务器上searchd 必须是运行的。
然后,根据test.php来修改下。
运行,连接时会出现一个很大的问题 errno =13 permission deny. 最后,查到一个英文的网页,是因为SElinux的原因,关于SELinux在网上能搜到。没有很好的解决办法,只能把SELinux设置为不用。使用的命令有下面两个: setenforce 在 /usr/bin 下
setenforce 1 设置SELinux 成为enforcing模式
setenforce 0 设置SELinux 成为permissive模式
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值