sphinx增量索引和主索引来实现索引的实时更新

来源:互联网 发布:销售客户软件 编辑:程序博客网 时间:2024/06/06 07:11
tips:
Sphinx查询中Attribute(属性)的概念,而且Sphinx在启动Searchd的时候会将所有属性加载到内存中.所以如果数量巨大时可能会 FATAL: out of memory (unable to allocate 1494868092 bytes),此时应该分批创建索引再合并。

sphinx增量索引和主索引来实现索引的实时更新


项目中文章的信息内容因为持续有新增,而文章总量的基数又比较大,所以做搜索的时候,用了主索引+增量索引这种方式来实现索引的实时更新。

实现原理:

1. 新建一张表,记录一下上一次已经创建好索引的最后一条记录的ID
 2. 当索引时,然后从数据库中取出所有ID大于上面那个sphinx中的那个ID的数据, 这些就是新的数据,然后创建一个小的索引文件
 3. 把上边我们创建的增量索引文件合并到主索引文件上去
 4. 把最后一条记录的ID更新到第一步创建的表中

值得注意的两点:

1)当合并索引的时候,只是把增量的索引合并进主索引中,增量索引本身并不会变化,也不会被删除;

2)当重建主索引的时候,增量索引就会被删除;

具体操作实现流程:

1. 新建一张表,用于存储已经建过索引的最大的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

-----------------------------------------------

以ID作为增量和生成主索引的分割点的时候,如果使用索引合并来做的话,那么只能索引到新增的数据,而
更新的数据则无法被索引,所以做个记录更新时间的字段与ID做联合主键,以这个更新时间来做分割点


--------------------------------------------------------------------------------------



2. 配置索引文件


#主索引数据源定义
source article_main
{
    type                    = mysql
    sql_host                =xxx.xxx.xxx.xx
    sql_user                =
    sql_pass                =
    sql_db                  =

    sql_port                = 3306
    sql_query_pre           = SET NAMES utf8
    sql_query_pre           = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents

 
   sql_query_range               =
   sql_range_step                = 10000
   sql_query                               = \
                SELECT *\
                FROM documents WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1);

    sql_attr_timestamp        = pubtime  #从SQL读取到的值必须为整数,作为时间属性

    sql_query_info_pre      = SET NAMES utf8                                        #命令行查询时,设置正确的字符集
    sql_query_info            = SELECT * FROM documents WHERE id=$id #命令行查询时,从数据库读取原始数据信息
}


 #增量数据源
     29 source delta : src1
     30
     31 {
     32
     33 sql_query_pre = SET NAMES utf8
     34
     35 sql_query_pre = SET SESSION query_cache_type=OFF
     36
     37 sql_query = SELECT * FROM documents WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )

    #如果只做索引合并不做主索引的定时生成,那么这里必须还要再更新完增量索引后将sph_counter的max_doc_id 修改,不然每当再次生成增量索引时
    
    sql_query_post =  REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents;
     38
     39 sql_query_info_pre      = SET NAMES utf8                                        #命令行查询时,设置正确的字符集
     40
     41 sql_query_info          = SELECT * FROM documents WHERE id=$id
     42
     43 }



   46 #定义索引
     47 index test1
     48 {
     49         #索引数据源
     50         source                  = src1
     51         #数据地址
     52         path                    = /usr/local/csft4/var/data/test1
     53         docinfo                 = extern
     54         charset_type            = zh_cn.utf-8
     55         #中文分词配置
     56         #BSD、Linux环境下设置,/符号结尾
     57         charset_dictpath = /usr/local/mmseg4/etc/
     58 }
     59
     60


     61 # 增量索引
     62 index delta : test1
     63 {
     64     source = delta
     65     path = /usr/local/csft4/var/data/delta
     66     docinfo            = extern
     67     mlock            = 0
     68     morphology        = none
     69     min_word_len        = 1
     70     html_strip                = 0
     71
     72     charset_dictpath = /usr/local/mmseg4/etc/ #BSD、Linux环境下设置,/符号结尾
     73     charset_type        = zh_cn.utf-8
     74 }



indexer
     77 {
     78         mem_limit               =64M
     79 }
     80
     81



     82 searchd
     83 {
     84         listen                  = 9312
     85         listen                  = 9306:mysql41
     86         log                     = /usr/local/csft4/logs/searchd.log
     87         query_log               = /usr/local/csft4/logs/query.log
     88         read_timeout            = 5
     89         max_children            = 30
     90         pid_file                = /usr/local/csft4/pids/searchd.pid
     91         max_matches             = 1000
     92         seamless_rotate         = 1
     93         preopen_indexes         = 1
     94         unlink_old              = 1
     95         workers                 = threads # for RT to work
     96 }




 文件配置完毕后,重新启动searchd服务来加载新的配置文件:


./searchd -c /usr/local/csft4/etc/csft.conf --stop

注意csft.conf配置文件里面的注释只能使用#号,否则会报parse语法错误。

两外sql语句中where条件最好同主语句写在同一行。


关闭后再次打开searchd服务

/usr/local/csft4/bin/searchd -c /usr/local/csft4/etc/csft.conf

新建主索引 :

sudo /usr/local/csft4/bin/indexer -c /usr/local/csft4/etc/csft.conf test1 --rotate


插入一些数据后测试新建增量索引:

sudo /usr/local/csft4/bin/indexer -c /usr/local/csft4/etc/csft.conf delta --rotate


-rotate参数可以在不停searchd的情况下索引,不然的话会有类似如下的提示:

FATAL: failed to lock /usr/local/coreseek/var/data/hx_9enjoy_delta.spl: Resource temporarily unavailable, will not index. Try --rotate option.
ERROR: index 'delta' is already locked; lock: failed to lock /usr/local/coreseek/var/data/cncn_article_delta.spl: Resource temporarily unavailable


需要注意的是如果在searchd为开启状态下使用--rotate生成索引文件名则生成的文件会带有new这个字符串:

delta.new.spa  delta.new.sph  delta.new.spk  delta.new.spp  test1.new.spa  test1.new.sph  test1.new.spk  test1.new.spp
delta.new.spd  delta.new.spi  delta.new.spm  delta.new.sps  test1.new.spd  test1.new.spi  test1.new.spm  test1.new.sps




如果sphinx在运行中,要indexer时,需要加上--rotate参数,这样索引完就直接生效了。
原因是sphinx的searchd在启动时会创建一个 .spl 锁文件,并在关闭时会删除它。在indexer创建索引时如果发现有 .spl文件,则不会创建新索引,因为这时已经标志sphinx正在运行中,除非使用 –rotate。

rotate运行机制

->indexer完成索引  
->发送SIGHUP 给searchd(同时在终端输出索引已经完成)
->searchd接到中断信号->等待所有子进程退出
->重命名 当前索引为旧索引为 .old
->重命名 .new 索引文件作为当前索引
->尝试加载当前索引文件->如果加载失败,searchd会把.old文件回滚为当前文件,并把刚建立的新索引重命名为 .new
->加载成的话:完成无缝切换

------------------------------------------

手动重启的两种办法:
1.
关闭searchd :killall -9 searchd
重启 searchd :searchd -c ../sphinx.conf

2.
关闭:searchd --stop
启动:searchd



经过实验发现,如果是生成增量索引,即使searchd在开启状态也能生成。



而在没有生成索引时开启searchd服务则会提示:
[root@localhost bin]# /usr/local/csft4/bin/searchd -c /usr/local/csft4/etc/csft.conf
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)

using config file '/usr/local/csft4/etc/csft.conf'...
WARNING: compat_sphinxql_magics=1 is deprecated; please update your application and config
 listening on all interfaces, port=9312
listening on all interfaces, port=9306
 precaching index 'test1'
WARNING: index 'test1': preload: failed to open /usr/local/csft4/var/data/test1.sph: No such file or directory; NOT SERVING
precaching index 'delta'
WARNING: index 'delta': preload: failed to open /usr/local/csft4/var/data/delta.sph: No such file or directory; NOT SERVING
FATAL: no valid indexes to serve


——————————————————————————————————————————————————————————————————

对索引的操作命令:

重建主索引和增量索引:

  1. /usr/local/coreseek/bin/indexer--config /usr/local/coreseek/etc/csft.conf -rotate index_main  
  2. /usr/local/coreseek/bin/indexer--config /usr/local/coreseek/etc/csft.conf -rotate index_add  

合并建主索引和增量索引:

  1. indexer --config /usr/local/coreseek/etc/csft.conf --merge index_main index_add --merge-dst-range deleted 0 0 -rotate  


重建整个索引:

/usr/local/coreseek/bin/indexer --config /usr/local/coreseek/etc/csft.conf  --all--rotate












阅读全文
0 0
原创粉丝点击