抛弃mysql模糊查询,使用sphinx做专业索引

Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,提供比数据库本身更专业的搜索功能特别为MySQL也设计了一个存储引擎插件,从此抛弃模糊查询吧。

Sphinx 单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建100万条记录的索引只要 3、4分钟,创建1000万条记录的索引可以在50分钟内完成,而重建一次只包含最新10万条记录的增量索引只需几十秒。

一、安装

环境:centos6.5

yum install sphinx -y

默认配置路径 /etc/sphinx/ ,在该路径下,有配置文件sphinx.conf,看看我的配置

# 数据源,这里配置的是mysql
source src1
{
    type            = mysql

    sql_host        = localhost
    sql_user        = root
    sql_pass        =
    sql_db          = beego_blog
    sql_port        = 3306  # optional, default is 3306

    # 创建索引时候,从数据库查询数据的SQL
    sql_query       = \
        SELECT id, userid, UNIX_TIMESTAMP(posttime) AS posttime, title, content, tags \
        FROM tb_post

    sql_attr_uint       = userid
    sql_attr_timestamp  = posttime

    sql_query_info      = SELECT * FROM tb_post WHERE id=$id
}

# 索引1
index test1
{
    # 指定数据源
    source          = src1
    # 索引文件路径
    path            = /var/lib/sphinx/test1
    # 储文档信息的方式 extern
    docinfo         = extern
    charset_type    = sbcs
}

# 索引2
index testrt
{
    type            = rt
    rt_mem_limit    = 32M

    path            = /var/lib/sphinx/testrt
    charset_type    = utf-8

    rt_field        = title
    rt_field        = content
    rt_attr_uint    = userid
}


indexer
{
    mem_limit       = 32M
}


searchd
{
    listen          = 0.0.0.0:9312 # 索引对外提供服务的地址
    listen          = 9306:mysql41
    log             = /var/log/sphinx/searchd.log
    query_log       = /var/log/sphinx/query.log
    read_timeout    = 5
    max_children    = 30
    pid_file        = /var/run/sphinx/searchd.pid
    max_matches     = 1000
    seamless_rotate = 1
    preopen_indexes = 1
    unlink_old      = 1
    workers         = threads # for RT to work
    binlog_path     = /var/lib/sphinx
}


生成索引,这里我们用上文配置的索引名称test1来从mysql获取数据。因此,我们先在myslq中,创建表和数据

CREATE TABLE `tb_post` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `userid` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题',
  `content` mediumtext NOT NULL COMMENT '内容',
  `tags` varchar(100) NOT NULL DEFAULT '' COMMENT '标签',
  `posttime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '发布时间',
  PRIMARY KEY (`id`)
);
INSERT INTO `tb_post` VALUES ('1', '1', 'epoll边沿触发漏报消息包问题', '开发一个即时通讯后台,底层的网络收发使用 epoll + main loop实现网络事件', ',技术,', '2016-08-05 11:50:02');
INSERT INTO `tb_post` VALUES ('2', '1', 'epoll 边沿触发和水平触发区别实战讲解', 'epoll,看结果发现只接入了两条,还有3条没接入。说明高并发时,会出现客户端连接不上的问题。', ',技术,', '2016-08-05 22:03:23');
INSERT INTO `tb_post` VALUES ('3', '1', '快速排序算法', '快速排序算法是一个挺经典的算法,值得我们学习', ',技术,', '2016-08-05 23:08:00');

创建索引

[root@centos6 data]# indexer test1
Sphinx 2.0.8-id64-release (r3831)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/etc/sphinx/sphinx.conf'...
indexing index 'test1'...
collected 37 docs, 0.8 MB
sorted 0.1 Mhits, 100.0% done
total 37 docs, 833156 bytes
total 0.082 sec, 10061176 bytes/sec, 446.81 docs/sec
total 3 reads, 0.000 sec, 57.7 kb/call avg, 0.0 msec/call avg
total 9 writes, 0.000 sec, 40.2 kb/call avg, 0.0 msec/call avg

可以看索引了37条文档,我们可以在命令行测试下效果


[root@centos6 libertyblog]# search epoll|more
Sphinx 2.0.8-id64-release (r3831)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/etc/sphinx/sphinx.conf'...
index 'test1': query 'epoll ': returned 2 matches of 2 total in 0.000 sec

displaying matches:
1. document=59, weight=2831, userid=1, posttime=Fri Aug  5 22:03:23 2016
        id=59
        userid=1
        title=epoll ???????????????
        content=开发一个即时通讯后台,底层的网络收发使用 epoll + main loop实现网络事件
......

结果匹配到了两条数据,篇幅有限,就不全列出来了。数据 1. document=59, weight=2831 表示该索引文档编号59,权重2831。以上是命令行操作,如果我们要对外提供服务,还需要启动searchd服务进程

[root@centos6 data]# service searchd start
正在启动 searchd:Sphinx 2.0.8-id64-release (r3831)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/etc/sphinx/sphinx.conf'...
WARNING: compat_sphinxql_magics=1 is deprecated; please update your application and config
listening on 127.0.0.1:9312
listening on all interfaces, port=9306
precaching index 'test1'
precaching index 'testrt'                                   
precached 2 indexes in 0.002 sec
                                                           [确定]

启动成功,绑定了端口9312,我们查看下状态

[root@centos6 data]# searchd --status
Sphinx 2.0.8-id64-release (r3831)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/etc/sphinx/sphinx.conf'...

searchd status
--------------
uptime: 252 
connections: 1 
maxed_out: 0 
command_search: 0 
command_excerpt: 0 
command_update: 0 
command_keywords: 0 
command_persist: 0 
command_status: 1 
command_flushattrs: 0 
agent_connect: 0 
agent_retry: 0 
queries: 0 
dist_queries: 0 
query_wall: 0.000 
query_cpu: OFF 
dist_wall: 0.000 
dist_local: 0.000 
dist_wait: 0.000 
query_reads: OFF 
query_readkb: OFF 
query_readtime: OFF 
avg_query_wall: 0.000 
avg_query_cpu: OFF 
avg_dist_wall: 0.000 
avg_dist_local: 0.000 
avg_dist_wait: 0.000 
avg_query_reads: OFF 
avg_query_readkb: OFF 
avg_query_readtime: OFF 

现在我们用一个第三方客户端访问该服务(golang语言开发)

package main

import (
    "github.com/yunge/sphinx"
    "log"
)

func main() {
    SphinxClient := sphinx.NewClient().SetServer("localhost", 0).SetConnectTimeout(5000)
    if err := SphinxClient.Error(); err != nil {
        log.Fatal(err)
        return
    }

    // 查询,第一个参数是我们要查询的关键字,第二个是索引名称test1,第三个是备注
    res, err := SphinxClient.Query("epoll", "test1", "search article!")
    if err != nil {
        log.Fatal(err)
        return
    }
    var article_ids string
    for _, match := range res.Matches {
        article_ids += fmt.Sprintf("%d,", match.DocId)
    }

    log.Println(article_ids)
    SphinxClient.Close()
}

打印结果,是 { 1 2 } ,这两个id,没有id为3的,说明索引查找是准确的,因为3里面没有epoll这个单词,而1和2里面都有epoll。至此,我们的测试完成,可以把此功能和自己网站的搜索框对接,以前都是用模糊查询的方式,在数据库中 like '%' 某某,这样效率其实很低,数据多的时候要等半天,现在用第三方索引来实现,速度快好几个量级。

如果有新的数据插入,或者更新数据,是需要做 增量索引 的,很简单

[root@centos6 data]# indexer --rotate test1
Sphinx 2.0.8-id64-release (r3831)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/etc/sphinx/sphinx.conf'...
indexing index 'test1'...
collected 37 docs, 0.8 MB
sorted 0.1 Mhits, 100.0% done
total 37 docs, 833156 bytes
total 0.081 sec, 10184036 bytes/sec, 452.26 docs/sec
total 3 reads, 0.000 sec, 57.7 kb/call avg, 0.0 msec/call avg
total 9 writes, 0.000 sec, 40.2 kb/call avg, 0.1 msec/call avg
rotating indices: successfully sent SIGHUP to searchd (pid=12074).

最好把增量索引的操作放到crontab中,定时做增量,以保持索引最新。以下是每天2点做一次增量索引

0 2 * * * indexer --rotate test1

创建于 2015-08-10 杭州,更新于 2016-08-19 杭州

该文章在以下平台同步

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容