• 【PHP高效搜索专题(1)】sphinx&Coreseek的介绍与安装


    我们已经知道mysql中带有"%keyword%"条件的sql是不走索引的,而不走索引的sql在大数据量+大并发量的时候,不仅效率极慢还很有可能让数据库崩溃.那我们如何通过某些关键字来搜索我们想要的文章呢? 虽然mysql的MYISAM提供全文索引,但是只支持中文,并且性能却不敢让人恭维,因此采用Sphinx来做mysql的全文索引工具是一个很好的选择.

    简介

    Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。意图为其他应用提供高速、低空间占用、高结果 相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从标准输入读取特定格式的XML数据.

    1. 高速的建立索引(在当代CPU上,峰值性能可达到10 MB/秒);
    2. 高性能的搜索(在2 – 4GB 的文本数据上,平均每次检索响应时间小于0.1秒);
    3. 可处理海量数据(目前已知可以处理超过100 GB的文本数据, 在单一CPU的系统上可 处理100 M 文档);
    4. 提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;
    5. 支持分布式搜索;
    6. 支持短语搜索
    7. 提供文档摘要生成
    8. 可作为MySQL的存储引擎提供搜索服务;
    9. 支持布尔、短语、词语相似度等多种检索模式;
    10. 文档支持多个全文检索字段(最大不超过32个);
    11. 文档支持多个额外的属性信息(例如:分组信息,时间戳等);
    12. 支持断词;

    sphinx的安装与使用

    安装
    wget http://sphinxsearch.com/files/sphinx-2.2.9-release.tar.gz
    tar zxvf sphinx-2.2.9-release.tar.gz
    cd sphinx-2.2.9-release
    ./configure --prefix=/usr/local/sphinx/ --with-mysql=/usr/bin/mysql/
    make && make install
    

    --prefix:指定 sphinx 的安装路径
    --with-mysql:指定 mysql 安装路径,注意这里的安装路径一般是指通过编译安装的mysql路径,如果你是通过yum来安装的mysql的话,此项可以不用加

    make的时候,有可能会报错,不要管,继续等待.如果最终失败的话,再make clean之后,删除目录,重新configure.
    注意,此时的sphinx还不能支持中文

    安装成功后,按道理应该有三个工具

    ls /usr/local/sphinx/bin
    indexer 创建索引命令
    searchd 启动进程命令
    search  命令行搜索命令
    

    其中search命令已经在新版本的sphinx取消了,可以用api文件来进行测试;

    配置与使用
    cd /usr/local/sphinx/etc
    ls
    example.sql # 示例sql  
    sphinx.conf.dist # 完整版配置项 
    sphinx-min.conf.dist # 精简版配置项
    
    cp sphinx.conf.dist sphinx.conf 
    vim sphinx.conf # 配置数据库连接信息,打开utf8字符集注释(sql_query_pre = SET NAMES utf8),然后可以把以上的示例sql导入数据库里面做测试;
    
    cd /usr/local/sphinx/bin
     ./indexer --all # 创建索引,如果后面又新增加了数据,还要重新或增量建立sql;
    
    ./search this #搜索test库中有this的;注意,在新版本的sphinx里面该命令已经被取消了,但可以通过api文件来测试
    
    $ cd sphinx/api 
    $ php test.php test
    

    如果执行indexer命令报错

    ERROR: index 'test1stemmed': sql_connect: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
    

    则可能是因为mysql.sock的位置问题,在本机中,该位置是/tmp/mysql.sock(与安装mysql时设置有关),在sphinx.conf中取消这一行的注释即可(去掉前面的#号):

    #sql_sock                = /tmp/mysql.sock
    

    然而以上的所有步骤都没有什么卵用,因为sphinx是不支持中文的,所以我们可以选择使用基于sphinx的coreseek,也可以选择其他更方便的扩展,本文就先结束coreseek

    coreseek

    安装
    安装mmseg
    wget http://www.coreseek.cn/uploads/csft/4.0/coreseek-4.1-beta.tar.gz
    tar zxvf coreseek-4.1-beta.tar.gz
    cd coreseek-4.1-beta
    ls
    csft-4.1  #sphinx中文扩展
    mmseg-3.2.14 #中文词库
    testpack 
    
    #先安装mmseg中文分词系统
    cd mmseg-3.2.14/
    ./configure --prefix=/usr/local/mmseg 
    

    如果报错 annot find input file: src/Makefile.in
    就依次执行:

    aclocal   #是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac” ,如果执行此句还是错误的话就 yum -y install libtool  
    libtoolize --force 
    automake --add-missing
    autoconf
    autoheader
    make clean
    
    #然后再从新编译一下
    ./configure --prefix=/usr/local/mmseg 
    make && make intall
    

    测试

    $ /usr/local/mmseg/bin/mmseg -d /usr/local/mmseg/etc /usr/src/coreseek-4.1-beta/mmseg-3.2.14/src/t1.txt
    中文/x 分/x 词/x 测试/x
    中国人/x 上海市/x
    
    $ ./mmseg -d ../etc test.txt
    小/x 白兔/x 白/x 又/x 白/x 两/x 只/x 耳朵/x 竖/x 起来/x
    爱/x 吃/x 萝卜/x 爱/x 吃/x 菜/x
    
    安装csft-4.1
    cd /usr/src/coreseek-4.1-beta/csft-4.1
    sh buildconf.sh # 如果不报错就代表没问题,如果输出的warning信息可以忽略,如果出现error则需要解决  
    
    ./configure --prefix=/usr/local/coreseek --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg/lib/ --with-mysql
    make && make install
    
    配置

    配置文件

    • 名为main的主数据源:source main{}
    • 继承名为main的增量数据源:source delta:main{}
    • 名为main的主索引:index main{}
    • 继承名为main的增量索引:index delta:main{}
    • 分布式索引:index dist1{}
    • 索引器:indexer{}
    • 服务进程:searchd{}

    增量配置肯定是要做的,所以先准备一个计数器

    -- 只记录一行数据
    CREATE TABLE sph_counter  
    (  
    counter_id INTEGER PRIMARY KEY NOT NULL,  
    max_doc_id INTEGER NOT NULL  
    );  
    
    #MySQL数据源配置,详情请查看:http://www.coreseek.cn/products-install/mysql/
    
    cd /etc
    cp sphinx.conf.dist csft.conf #复制为csft名后就可以自动读取
    
    #主数据源
    source main
    {
        type                    = mysql
        sql_host                = localhost
        sql_user                = root
        sql_pass                = 123456
        sql_db                  = test
        sql_port                = 3306
        sql_query_pre           = SET NAMES utf8 
        sql_query_pre           = REPLACE INTO sph_counter SELECT 1,MAX(id) FROM hr_spider_company;#通过replace into语句记录每次建立数据源最后一条数据id;
        
        sql_query               = SELECT * FROM hr_spider_company WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) 
        
         sql_attr_uint            = id                        #从SQL读取到的值必须为整数                                                      
         sql_attr_uint            = from_id                #从SQL读取到的值必须为整数,不支持全文检索  
         sql_attr_uint            = link_id                #从SQL读取到的值必须为整数,不支持全文检索  
         sql_attr_uint            = add_time                #从SQL读取到的值必须为整数,不支持全文检索  
         sql_field_string         = link_url                 #字符串字段(可全文搜索,可返回原始文本信息)  
         sql_field_string          = company_name          #字符串字段(可全文搜索,可返回原始文本信息)  
         sql_field_string          = type_name             #字符串字段(可全文搜索,可返回原始文本信息)  
         sql_field_string          = trade_name             #字符串字段(可全文搜索,可返回原始文本信息)  
         sql_field_string          = email                 #字符串字段(可全文搜索,可返回原始文本信息)  
         sql_field_string          = description             #字符串字段(可全文搜索,可返回原始文本信息)     sql_attr_timestamp      = date_added  #从SQL读取到的值必须为时间戳,作为时间属性
    
        sql_query_info_pre      = SET NAMES utf8  #命令行查询时,设置正确的字符集
        sql_query_info          = SELECT id,from_id,link_id,company_name,type_name,trade_name,address,description, FROM_UNIXTIME(add_time) AS add_time  FROM hr_spider_company  WHERE id=$id                     #用于PHP-CLI命令行查询时,从数据库读取原始数据信息 
    
        #区段查询 每次查询一段数据来建立索引
        #sql_query_range = SELECT MIN(id),MAX(id) FROM documents
        #sql_range_step  = 1000
        #sql_query = SELECT * FROM documents WHERE id>=$start AND id<=$end    
    }
    
    #主数据索引
    index main
    {
      source      = main  #对应的source名称
      path      = /usr/local/coreseek/var/data/main #主数据索引存储路径及其名称
      docinfo     = extern
      charset_type    = zh_cn.utf-8
      min_word_len = 1 #索引词最小长度 
      min_prefix_len = 0 #最小索引前缀长度 
      min_infix_len = 1 #最小索引中缀长度
      ngram_len = 1 #对于非字母型数据的长度切割(for CJK indexing) 
      charset_dictpath = /usr/local/mmseg/etc/ #分词的词典路径,BSD、Linux环境下设置,/符号结尾
      html_strip    = 0 #是否去除用户输入查询内容的html标签
    }
    
    #增量数据源
    source delta : main  
    {  
        sql_query_pre           = SET NAMES utf8  
        sql_query               = SELECT * FROM hr_spider_company WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
        sql_query_post_index    = REPLACE INTO sph_counter SELECT 1,MAX(id) FROM hr_spider_company
    } 
    
    #增量数据索引
    index delta : main  
    {  
        source          = delta  
        path            = /usr/local/coreseek/var/data/delta 
    }
    
    
    source src1throttled : src1
    {
      sql_ranged_throttle = 100
    }
    
    #全局index定义
    indexer
    {
        mem_limit            = 128M  #内存大小限制 默认是 32M, 最大 2047M, 推荐为 256M 到 1024M之间 
    }
    
    #searchd服务定义
    searchd
    {
        # 监测端口及形式,一下几种均可,默认为本机9312端口 
        # listen = 127.0.0.1 
        # listen = 192.168.0.1:9312 
        # listen = 9312 
        # listen = /var/run/searchd.sock
    
        listen                  = 9312 
        read_timeout            = 5  # 读取超时时间 
        max_children            = 30 # searche进程的最大运行数 
        max_matches             = 1000 # 最大的查询结果返回数 
        seamless_rotate         = 1 # 是否支持无缝切换(做增量索引时需要) 
        preopen_indexes         = 0 # 在启动运行时是否提前加载所有索引文件 
        unlink_old              = 1 # 是否释放旧的索引文件
        pid_file = /usr/local/coreseek/var/log/searchd.pid 
        log = /usr/local/coreseek/var/log/searchd.log  # search进程的日志路径 
        query_log = /usr/local/coreseek/var/log/query.log  # 查询日志地址 
        binlog_path     =                                              #关闭binlog日志
    }
    
    测试
    cd  /usr/local/coreseek/bin
    ./search 淘宝
    
    使用 sphinx 需要做以下几件事

    1.有数据;
    2.建立 sphinx 配置文件;
    3.生成索引;
    4.启动 searchd 服务进程,默认是9312
    5.用 PHP 去连接 sphinx 服务

    #启动服务,监听9312端口
    cd /usr/local/coreseek/bin/
    ./searchd
    #./searchd -c /usr/local/coreseek/etc/csft_mysql.conf  #如果配置文件不是默认的csft.conf的话
    
    # 执行索引(查询、测试前必须执行一次)
    ./indexer -c /usr/local/coreseek/etc/csft_mysql.conf --all --rotate  
    
    # 执行增量索引
    /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf delta --rotate 
    
    # 合并索引
    /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --merge main delta --rotate --merge-dst-range deleted 0 0  #为了防止多个关键字指向同一个文档加上--merge-dst-range deleted 0 0
    
    # 后台服务测试
    /usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/csft_mysql.conf  aaa  
    
    #关闭后台服务
    /usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft_mysql.conf --stop 
    

    searchd 命令参数介绍:

    • -c 指定配置文件
    • --stop 停止服务
    • --pidfile 用来显式指定一个 PID 文件
    • -p 指定端口

    自动化建立索引

    # 每分钟进行一次增量索引
    */1 * * * * /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf delta --rotate 
    
    # 每五分钟合并一次索引
    */5 * * * * /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --merge main delta --rotate --merge-dst-range deleted 0 0  
    
    # 每天晚上的一点三十分建一次完整的索引
    30 1 * * *  /bin/sh /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft_mysql.conf --all --rotate 
    

    参考

    Sphinx中文指南

    sphinx全文检索之PHP使用教程

    coreseek-4.1 参考手册

    coreseek-4.1的一些配置说明(左侧边栏)

    Sphinx PHP扩展(类)使用说明

    sphinx中文版Coreseek中文检索引擎安装和使用方法(Linux)

  • 相关阅读:
    DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作
    DevExpress ASP.NET 使用经验谈(4)-CriteriaOperator的使用
    DevExpress ASP.NET 使用经验谈(3)-XPO对象的使用(使用指定数据连接)
    DevExpress ASP.NET 使用经验谈(2)-XPO对象的使用(使用默认数据连接)
    DevExpress ASP.NET 使用经验谈(1)-XPO模型的创建
    C#堆栈原理(我有两个例子测试你到底会不会)
    C# static 干货全解析
    C# 链接 SQLite问题汇总
    EFCore AsNoTracking方法不能使用的问题;EFCore 如何取消跟踪
    2019-1-3 每日一记
  • 原文地址:https://www.cnblogs.com/nixi8/p/4746179.html
Copyright © 2020-2023  润新知