sphinx通过增量索引实现近实时更新
一.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 对应,否则可能搜索不出相应结果
//delta_src继承main_src所有设置,除source外,index也可以继承,这是sphinx的继承属性
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
/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模式
本文转自:http://blog.sina.com.cn/s/blog_630153a50101lzx4.html
sphinx通过增量索引实现近实时更新的更多相关文章
- sphinx 增量索引 实现近实时更新
一.sphinx增量索引的设置 数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到.全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少.例如.原来的数据有几百万条 ...
- php定时执行sphinx的增量索引
/** * 每天定时执行的sphinx索引增量更新 * @author guo.jing * 2015-05-08 * @param $indexerArr(执行要更新的索引) */ public f ...
- sphinx(coreseek)——1、增量索引
首先介绍一下 CoreSeek/Sphinx的发布包 indexer: 用于创建全文索引; search: 一个简单的命令行(CLI) 的测试程序,用于测试全文索引; search ...
- sphinx增量索引使用
sphinx在使用过程中如果表的数据量很大,新增加的内容在sphinx索引没有重建之前都是搜索不到的. 这时可以通过建立sphinx增量索引,通过定时更新增量索引,合并主索引的方式,来实现伪实时更新. ...
- sphinx增量索引和主索引来实现索引的实时更新
项目中文章的信息内容因为持续有新增,而文章总量的基数又比较大,所以做搜索的时候,用了主索引+增量索引这种方式来实现索引的实时更新. 实现原理: 1. 新建一张表,记录一下上一次已经创建好索引的最后一条 ...
- Sphinx主索引和增量索引来实现索引实时更新的关键步骤
1.配置csft.conf文件 vim /etc/csft.conf # # Minimal Sphinx configuration sample (clean, simple, functiona ...
- Lucene.net 实现近实时搜索(NRT)和增量索引
Lucene做站内搜索的时候经常会遇到实时搜索的应用场景,比如用户搜索的功能.实现实时搜索,最普通的做法是,添加新的document之后,调用 IndexWriter 的 Commit 方法把内存中的 ...
- Sphinx 增量索引更新
是基于PHP API调用,而不是基于sphinxSE.现在看来sphinxSE比API调用更简单的多,因为之前没有想过sphinxSE,现在先把API的弄明白.涉及到的:sphinx 数据源的设置,简 ...
- 一步一步跟我学习lucene(19)---lucene增量更新和NRT(near-real-time)Query近实时查询
这两天加班,不能兼顾博客的更新.请大家见谅. 有时候我们创建完索引之后,数据源可能有更新的内容.而我们又想像数据库那样能直接体如今查询中.这里就是我们所说的增量索引.对于这种需求我们怎么来实现呢?lu ...
随机推荐
- 扼杀 304,Cache-Control: immutable
随着近些年社交网站的流行,越来越多的人学会了“刷”网页 ── 刷微博,刷朋友圈,刷新闻,刷秒杀页.这里的“刷”,就是刷新的意思,在浏览器里,你可以通过点击刷新按钮,或者用快捷键,或者移动端的下拉操作来 ...
- Bash 中的环境变量
在 Bash 里,可以通过 export 命令查看当前 Shell 进程的环境变量,这些环境变量一些是 Bash 自己创建的,还有一些是 Bash 从父进程继承来的,然而需要注意的是,父进程传给 Ba ...
- 在vs中char类型的实参与LPCWSTR类型的形参类型不兼容怎么解决?
今天在做 COS脚本解释器的时候,遇到了这个问题 先了解一下 LPCTCHAR 这个东东 LPCTSTR用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么 ...
- Redis 3.0正式版发布,正式支持Redis集群
Redis是一个开源.基于C语言.基于内存亦可持久化的高性能NoSQL数据库,同时,它还提供了多种语言的API.近日,Redis 3.0在经过6个RC版本后,其正式版终于发布了.Redis 3.0的最 ...
- IIS跳转html页面自动识别是PC端还是手机端
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Jprofile监控本地tomact
第一步:安装Jprofile后,点击jprofiler.exe 第二步:配置要监控的tomact 1.点击startcenter 2.弹出对话框,点击new session下面的new server ...
- windows2008r2的时间同步小结
一.在windows2008r2域控的环境下进行时间同步的配置(当已经拥有可以使用的ntp服务器,并知晓ip,客户端到其网络正常): 客户端的配置过程如下: 1.搜索窗口输入 gpedit.msc 打 ...
- 【转载】Linux常用命令列表
原文地址:http://www.cnblogs.com/Javame/p/3968343.html 1 目录与文件操作 1.1 ls(初级) 使用权限:所有人 功能 : 显示指定工作目录下之内容(列出 ...
- SQL SERVER 中的提示
提示是指定的强制选项或策略,由 SQL Server 查询处理器针对 SELECT.INSERT.UPDATE 或 DELETE 语句执行. 提示将覆盖查询优化器可能为查询选择的任何执行计划. 注意: ...
- JS控制按钮不能连续被点击
将下面代码拷贝进一个html文件中就可以运行查看效果. function downLoad(evt) { disabledButton(); MyPeriodicalExecuter(evt); } ...