网上有增量索引的资料,但不完善,很多都是转载来转载去的。
Sphinx做了索引之后,并不会自动去抓取mysql新增的内容。写个脚本定期重新索引是不可能的。Sphinx本身也有增量索引功能。说白了就是回MySQL里拿新增的内容,并合并到原有的索引中。
由此可见,Sphinx还是比较适合一些大数据、只增不改的数据库。
网上有增量教程,大概就是在MySQL里建立一个辅助表,在每次Sphinx过来抓的时候mark一下,然后下一次在这个点后继续抓。但是逻辑上有问题,看文章作者似乎发现了并修改了,但还是不完善。增量索引空sql_query_pre,则将一直沿用主索引建立时记录的maxid,每次增量索引都会抓到一些重复内容。
实际上如果仅用sql_query_pre,辅助表需要ID、This_time、Last_time 三个字段,因为sql_query_pre是在增量主sql前执行,如此一来,增量主语句获取的内容将为空。【即便是官方文档,也是使用sql_query_pre,这一点另我很好奇】,增加一个缓存上次maxid的last_time字段,这样就可以在每次sql_query_pre的时候查询最新的maxid,写入this_time,并把原来的this_time移动到last_time,sql_qurey执行的时候,使用last_time中记录的maxid来获取数据。
我没有尝试使用sql_query_post,但我觉得用他更合适。这样就可以只用两个字段了。
Mysql的辅助表
1 2 3 4 5 6 |
CREATE TABLE IF NOT EXISTS `sph_counter` ( `key` int(11) NOT NULL, `last_time` int(11) NOT NULL, `this_time` int(11) NOT NULL, PRIMARY KEY (`key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
主索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
source main { type = mysql sql_host = localhost sql_user = root sql_pass = sql_db = db sql_port = 3306 sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFF sql_query_pre = REPLACE INTO sph_counter SELECT 1,0, MAX(id) FROM hashs sql_query = SELECT id,atime,title,size,hash,title as content FROM hashs WHERE id<=(SELECT this_time FROM sph_counter WHERE `key`=1) sql_attr_string = content sql_attr_string = size sql_attr_string = hash sql_attr_timestamp = atime } |
增量索引
1 2 3 4 5 6 7 8 |
source delta : main { sql_ranged_throttle = 1000 sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFF sql_query_pre = update sph_counter set last_time = this_time , this_time = (select MAX(hashs.id) from hashs) where `key` = 1 sql_query = SELECT id,atime,title,size,hash,title as content FROM hashs WHERE id>(SELECT last_time FROM sph_counter WHERE `key`=1) } |
最后是定期更新增量的shell,实测这样写法不会遗漏数据,也不会额外读取。
1 |
/usr/bin/indexer --rotate btzz_inc && /usr/bin/indexer --merge btzz btzz_inc --rotate |
不得不说Sphinx的确非常好用,即便不用分词器,就用原版的Sphinx+chartset_table,效果也会比自己做的搜索快且好的多的多。
有些网友说Sphinx只返回ID,数据还是需要去mysql拿,因此说Sphinx在数据不大的情况下可能会是累赘,看网上很多教程也是这样。
我是直接完全从Sphinx拿数据的方式,没有上千万的数据,不到一百,但觉得速度的确是有很大改善。
了解Sphinx仅第二天,可能有一些基础的东西没了解,欢迎拍砖。