Sphinx

作者: 空留灯半盏 | 来源:发表于2018-07-10 22:30 被阅读0次

    Sphinx

    什么是Sphinx

    为什么要用Sphinx?

    原因1: MySQL不支持中文全文检索,模糊查询(like)慢

    原因2: sphinx支持中文全文检索,并且支持分词高亮

    什么是Sphinx

    就是一个软件,用来代替MySQL全文检索

    sphinx的特性

    强,快

    特性

    高速的建立索引(峰值达10M/s)

    高性能的搜索(2-4G的文件数据上,平均每次检索0.1秒左右)

    可处理海量数据 (字符串,布尔..)

    优势

    sphinx单一索引最大可包含1亿条记录,在1千万记录情况下的查询速度为0.x秒(毫秒级)

    sphinx创建索引的速度为: 创建100万条记录的索引只需3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而值包含最新10万条记录增量索引,重建一次只需十几秒

    Snipaste_2018-07-10_19-41-26.png
    sphinx执行的过程
    步骤1:通过sphinx去MySQL中获取并建立索引文件
    步骤2:通过php去sphinx中查询数据并返回ID
    步骤3:根据ID去MySQL中查询具体数据
    

    安装Sphinx

    什么是Coreseek

    Coreseek是一款中文全文检索/搜索软件,基于Sphinx研发并独立发布.专攻中文搜索和信息处理领域,使用于行业/垂直搜索,论坛/站内搜索,数据库搜索,文档/文献检索,信息检索,数据挖掘等应用场景

    简单的来说就是中文版的sphinx

    Coreseek和sphinx的关系

    sphinx默认支持英文和俄文,但是它提供了一种方法可以支持任意一种语言,但是需要自己写相关语言词库

    Coreseek是在sphinx的基本上添加了中文词库的二次开发

    简单概括: sphinx由俄国人开发,默认不支持中文,但是提供了接口,coreseek基于该接口开发

    下载地址

    Sphinx官网:http://www.sphinxsearch.com

    coreseek官网:http://www.coreseek.com

    安装Coreseek

    安装包目录文件
    coreseek-3.2.14-win32\bin\indexer.exe      创建索引
    coreseek-3.2.14-win32\bin\searchd.exe       服务器端
    coreseek-3.2.14-win32\etc\csft_mysql.conf   配置文件
    

    配置sphinx

    创建数据库

    将etc/csft_mysql.conf复制并更名为sphinx.conf

    将shpinx.conf中内容更换为一下代码

    #数据源:数据来源定义(数据库信息、数据源SQL语句)
    source music
    {
        #下面是sql数据库特有的端口,用户名,密码,数据库名等。
        type                    = mysql
    
        sql_host                = localhost
        sql_user                = root
        sql_pass                = admin
        sql_db                  = youhua3
        sql_port                = 3306
        sql_query_pre           = SET NAMES utf8
    
        #sql_query属性:取出要创建索引的数据
        #要求1:SELECT的第一个字段必须是主键、
        #要求2:第一个字段的名字(别名)必须是id
        #要求3:其他的字段就是要创建索引的字段
        #需  求:为歌曲表中的title和author和content字段创建索引
        sql_query               = SELECT id, title, author, content FROM music
    }
    
    #索引的定义(索引文件存放的位置,索引文件的名字)
    #每个index对应一个数据源,用来定义这个数据源生成的索引文件的信息
    index music
    {
        #该索引对应哪个数据源
        source            = music
        #索引文件存放的目录和名字(存到E:/sphinx/var/data/目录下,索引文件的名字是music)
        path              = E:/sphinx/var/data/music  
        docinfo           = extern
        mlock             = 0
        morphology        = none
        min_word_len      = 1
        html_strip        = 0
        
        #词库文件所在的目录
        charset_dictpath = E:/sphinx/etc/
    
    #字符集编码类型,可以为:(sbcs,utf-8,zh_cn.utf-8,zh_ch.gbk,zh_ch.big5)
        charset_type        = zh_cn.utf-8
    }
    
    #全局index定义
    indexer
    {
        #建立索引的时候,索引内存限制
        mem_limit            = 128M
    }
    
    #searchd服务定义
    searchd
    {
        listen              =   9312
        read_timeout        = 5
        max_children        = 30
        max_matches         = 1000
        seamless_rotate     = 0
        preopen_indexes     = 0
        unlink_old          = 1
        
        # 进程id文件
        pid_file = E:/sphinx/var/log/searchd_mysql.pid  
        # 系统日志存放的位置
        log = E:/sphinx/var/log/searchd_mysql.log        
        # 查询日志存放的位置
        query_log = E:/sphinx/var/log/query_mysql.log
    }
    注: 修改路径和数据库账号密码
        Findex music     创建music索引(和source一一对应,表示该索引通过哪些数据创建)
        source music1   创建music数据源
    

    创建索引

    sphinx\bin> 创建指定索引语法 : indexer.exe -c 配置路径/文件 索引名

    sphinx\bin> 创建全部索引语法 : indexer.exe -c 配置路径/文件 --all

    使用PHP API操作Sphinx

    创建Sphinx服务

    bin>创建服务 : searche.exe -c 配置路径/文件 --install

    删除服务 : sc delete 服务名

    启动服务: net start 服务名

    关闭服务: net stop 服务名

    PHP操作

    复制sphinx\api目录中的接口文件sphinxapi.php放到站点目录

    在站点目录创建test.php引入该文件

    <?php
    
    #步骤1:引入sphinx接口文件
    require './sphinxapi.php';
    
    #步骤2:实例化对象
    $sp = new SphinxClient;
    
    #步骤3:设置服务
    $sp->SetServer('localhost', 9312);
    
    #步骤4:设置匹配模式 
    
    #步骤5:设置查询条数
    $sp->SetLimits(0, 5000);
    
    #步骤6:发送查询
    $rs = $sp->query('冬天', 'music');
    
    echo '<pre>';
    print_r($rs);
    
    匹配模式

    语法: $sp -> SetMatchMode(常量)

    SPH_MATCH_ALL            匹配所有词(默认)
    SPH_MATCH_ANY            匹配一个词
    SPH_MATCH_PHRASE     匹配整一个词
    SPH_MATCH_BOOLEAN   将查询看作一个布尔表达式
    SPH_MATCH_EXTENDED  查询看做一个sphinx的表达式
    

    举例: 我喜欢PHP

    分词: 我 喜欢 PHP

    准备工作: 先停止服务-> 创建索引->启动服务

    匹配所有词(SPH_MATCH_ALL)

    说明:我 喜欢 PHP 字段都要存在, 位置不限

    <?php
    
    #步骤1:引入sphinx接口文件
    require './sphinxapi.php';
    
    #步骤2:实例化对象
    $sp = new SphinxClient;
    
    #步骤3:设置服务
    $sp->SetServer('localhost', 9312);
    
    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_ALL);
    
    #步骤5:设置查询条数
    $sp->SetLimits(0, 5000);
    
    #步骤6:发送查询
    $rs = $sp->query('我喜欢PHP', 'music');
    
    echo '<pre>';
    print_r($rs); #
    
    匹配一个词(SPH_MATCH_ANY)

    说明: 我 喜欢 PHP 只要有一个存在,就匹配

    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_ANY);
    
    匹配整个词(SPH_MATCH_PHRASE)

    说明: 我 喜欢 PHP 都必须存在 位置必须一致

    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_PHRASE);
    
    将查询看作一个布尔表达式(SPH_MATCH_BOOLEAN)
    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_BOOLEAN);
    
    查询看做一个sphinx的表达式(SPH_MATCH_EXTENDED)

    说明: 查询指定字段的内容 @字段 内容

    举例: @title 内容 @content 内容 @author 内容

    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_EXTENDED);
    #步骤5:设置查询条数
    $sp->SetLimits(0, 5000);
    
    #步骤6:发送查询
    $rs = $sp->query('@content PHP @author 校长'); #内容=PHP并作者=校长
    
    echo '<pre>';
    print_r($rs); #
    

    将Sphinx的结果转为具体信息

    步骤1:通过sphinx去mysql中获取数据并建立索引文件

    步骤2:通过php去sphinx匹配数据ID

    步骤3:根据ID去数据库中查询数据

    查询

    <?php
    #步骤1:引入sphinx接口文件
    require './sphinxapi.php';
    #步骤2:实例化对象
    $sp = new SphinxClient;
    #步骤3:设置服务
    $sp->SetServer('localhost', 9312);
    #步骤4:设置匹配模式
    $sp->SetMatchMode(SPH_MATCH_ALL);
    #步骤5:设置查询条数
    $sp->SetLimits(0, 5000);
    #步骤6:发送查询
    $rs = $sp->query('我喜欢PHP', 'music');
    
    
    //获取所有数据库数据ID
    $ids = array_keys($rs['matches']);
    $ids = implode(',', $ids);
    //获取数据 select * from 表名 where id in (1,2,4,5)
    $pdo = new PDO('mysql:dbname=youhua3', 'root', 'root');
    $pdoStatementObj = $pdo->query("select * from music where id in ($ids)");
    $musics = $pdoStatementObj->fetchAll(PDO::FETCH_ASSOC);
    //循环显示数据
    foreach ($musics as $music) {
        echo $music['id'] . '__' . $music['author'] . '<hr />';
    }
    

    高亮显示搜索词

    #将上面代码foreach改为以下代码
    foreach ($musics as $music) {
        echo $music['id'] . '<br />';
        echo str_replace('冬天', '<font color=red>冬天</font>', $music['title']) . '<br />';
        echo str_replace('冬天', '<font color=red>冬天</font>', $music['author']) . '<br />';
        echo str_replace('冬天', '<font color=red>冬天</font>', $music['content']) . '<br />';
    }
    

    增量索引(Sphinx索引更新)

    什么是增量索引
    就是更新sphinx索引文件的表现称之为增量索引
    
    为什么要学习增量索引
    因为数据库每天数据都在变化,所以需要在原索引的基础上继续增加索引
    
    使用indexer.exe生成增量索引

    创建索引语法: indexer -c 配置文件 索引名

    合并索引语法: indexer -c 配置文件 --merge 主索引名 新索引名 --rotate(强制合并)

    操作

    先创建数据表 用于记录那些数据已经被创建索引

    create table sphinx
    (
        max_id int unsigned not null default 0
    )
    #该表作用:用于记录music表哪些数据已被创建索引,哪些数据未被创建索引
    #获取未创建索引数据:select * from music where id >  sphinx表记录的数字
    
    修改配置文件(记录已创建索引的数据)

    一 打开shpinx.conf 配置文件

    二 将下述代码粘贴到sphinx.conf中

    source music
    {
        #下面是sql数据库特有的端口,用户名,密码,数据库名等。
        type                    = mysql
    
        sql_host                = localhost
        sql_user                = root
        sql_pass                = admin
        sql_db                  = youhua3
        sql_port                = 3306
        sql_query_pre           = SET NAMES utf8
    
        #sql_query属性:取出要创建索引的数据
        #要求1:SELECT的第一个字段必须是主键、
        #要求2:第一个字段的名字(别名)必须是id
        #要求3:其他的字段就是要创建索引的字段
        #需  求:为歌曲表中的title和author和content字段创建索引
        sql_query               = SELECT id, title, author, content FROM music
    
    #★ 该部分代码放到music数据源中
    #目的:记录已经创建索引的数据
    #建完索引这后 ,把最后一条记录的id存到sphinx表中
        #在主查询(sql_query)之后执行的SQL
        sql_query_post = INSERT INTO sphinx SELECT MAX(id) FROM music
    }
    
    #索引的定义(索引文件存放的位置,索引文件的名字)
    #每个index对应一个数据源,用来定义这个数据源生成的索引文件的信息
    index music
    {
        #该索引对应哪个数据源
        source            = music
        #索引文件存放的目录和名字(存到E:/sphinx/var/data/目录下,索引文件的名字是music)
        path              = E:/sphinx/var/data/music  
        docinfo           = extern
        mlock             = 0
        morphology        = none
        min_word_len      = 1
        html_strip        = 0
        
        #词库文件所在的目录
        charset_dictpath = E:/sphinx/etc/
    
    #字符集编码类型,可以为:(sbcs,utf-8,zh_cn.utf-8,zh_ch.gbk,zh_ch.big5)
        charset_type        = zh_cn.utf-8
    }
    
    #全局index定义
    indexer
    {
        #建立索引的时候,索引内存限制
        mem_limit            = 128M
    }
    
    #searchd服务定义
    searchd
    {
        listen              =   9312
        read_timeout        = 5
        max_children        = 30
        max_matches         = 1000
        seamless_rotate     = 0
        preopen_indexes     = 0
        unlink_old          = 1
        
        # 进程id文件
        pid_file = E:/sphinx/var/log/searchd_mysql.pid  
        # 系统日志存放的位置
        log = E:/sphinx/var/log/searchd_mysql.log        
        # 查询日志存放的位置
        query_log = E:/sphinx/var/log/query_mysql.log
    }
    
    修改配置文件(增加新索引)

    打开shpinx.conf文件

    将下述代码追加 (记得修改密码和路径)

    # 数据源
    source music_add
    {
        # 下面是sql数据库特有的端口,用户名,密码,数据库名等。
        type                    = mysql
    
        sql_host                = localhost
        sql_user                = root
        sql_pass                = admin
        sql_db                  = youhua3
        sql_port                = 3306
        sql_query_pre           = SET NAMES utf8
    
    
        # (SELECT MAX(max_id) FROM sphinx)  目的,规避重复创建索引
        sql_query = SELECT id, title, author,content FROM music WHERE id > (SELECT MAX(max_id) FROM sphinx)
    
    # 建完索引这后 ,把最后一条记录的id存到sphinx表中
    # 在主查询(sql_query)之后执行的SQL
    sql_query_post = UPDATE sphinx SET max_id = (SELECT MAX(id) FROM music)
    }
    
    
    # 数据索引
    index music_add
    {
        # 对应的source数据来源名称
        source            = music_add
        path              = E:/sphinx/var/data/music_add
        docinfo           = extern  
        mlock             = 0
        morphology        = none
        min_word_len      = 1
        html_strip        = 0
    
        # 词库文件所在的目录
        charset_dictpath = E:/sphinx/etc/
    
        charset_type      = zh_cn.utf-8
    }
    
    记录已创建索引的数据(初始化一把)

    停止服务->创建music索引->开启服务->查看sphinx表

    测试录入新数据自动跟新索引

    创建sphinx.bat文件 ,并输入下属内容(路径注意)

    E:\sphinx\bin\indexer -c E:\sphinx\etc\sphinx.conf music_add #用于给music表未创建索引数据增加索引
    E:\sphinx\bin\indexer -c E:\sphinx\etc\sphinx.conf --merge music music_add --rotate #将music_add索引合并到music索引中
    

    打开music表新录入数据

    双击运行sphinx.bat更新索引(注: 用管理员身份运行)

    通过PHP代码测试查询新增数据

    定时任务

    把这个sphinx.bat文件添加到windows系统上的计划任务,让系统定时执行这个文件中的两个任务

    打开控制面板 ->找到管理工具->任务计划程序->创建任务

    勾选最高权限运行 在操作中新建程序

    触发器中建立执行时间

    MySQL读写分离技术linux

    读写分离(主从复制)

    什么是主从复制,读写分离
    主从复制: 当主服务器有写入(增/删/改)语句的时候,从服务器自动获取数据并同步
    读写分离: 增/删/改 语句操作在一台服务器,select另一台服务器
    
    实现原理
    主服务器开启binlog日志(记录主服务写sql语句)
    从服务器监听日志,只要改变就同步执行
    

    bin-log 日志

    什么是bin-log日志

    即二进制日志,它记录了数据库上的所有改变并以二进制的形式保存在磁盘中
    ,它可以用来查看数据库的更变历史,数据库增量备份和恢复,MySQL的复制(主从数据库的复制)
    

    主要作用: 就是记录MySQL数据库增/删/改sql语句

    -) 实现主从复制

    -) 灾难恢复

    开启binlog日志

    打开mysql 配置文件/etc/my.conf并修改

    vi /etc/my.cnf
    在[mysqld] 下一行
    #新增  log-bin=mysql-bin
    

    重启服务

    ps -A | grep mysql  #查看
    killall mysqld  #杀死进程
    /php/server/mysql/bin/mysqld_safe --user=mysql &  #启动
    

    登录mysql查看bin-log日志是否开启

    /php/server/mysql/bin/mysql -u账号 -p密码
    show variables like 'log_bin' #查看日志是否开启
    
    查看binlog日志里的内容

    查看列表( show master logs)

    清空( reset master )

    刷新( flush logs ) 会生成一个新文件存储

    查看指定日志( show binlog events in '日志名' )

    创建d1数据库和t1表

    create database d1;
    use d1;
    create table t1 (id int);
    

    查看binlog日志中的sql语句

    show binlog events in '日志名' 
    

    具体配置

    配置主服务器
    一, 修改配置文件,开启binlog日志
    二, 修改配置文件,设置一个server-id=数字(注: 数字唯一)
    三, 重启服务
    killall mysqld
    /php/server/mysql/bin/mysqld_safe --user=mysql &  #启动
    四, 创建mysql用户
    create user 'xiaoze'@'%' IDENTIFIED BY 'admin888'; 
    grant all on *.* to 'xiaoze'@'%';
    FLUSH PRIVILEGES;
    五,关闭防火墙
    service iptables stop
    
    从服务器配置
    一 : 修改配置文件,设置一个server-id=数字 (数字唯一)
    二 : 重启服务
    三 : 通过change master 语句指定同步主位置
    四 : 重启
    验证
    

    如果通过克隆服务器会报错 应该三台服务器mysql一样

    解决: 删除mysql数据目录下auto.cnf 重启 (重启后会自动创建一个唯一的uid)

    解决auto.cnf报错.png

    TP框架里实现读写分离

    配置

    将tp5解压到站点目录下并访问

    修改tp5数据库配置文件

    'deploy' => 1,
    'rw_separate' => true,
    'hostname' => '主服务器ip,从1,从2',
    'database' => 'd8',
    'username' => 'nanoha'
    

    切换到主服务区创建d8数据库和t1表

    create database d8 charset=utf8;
    use d8;
    create table t1 (id int primary key auto_increment,name char(30));
    

    切换到所有从服务器创建nanoha用户

    create user 'xiaoze'@'%' IDENTIFIED BY 'admin888'; 
    grant all on *.* to 'xiaoze'@'%';
    FLUSH PRIVILEGES;
    

    所有从服务器关闭3306防火墙

    主服务器负责写,从服务器自动同步
    public function index()
    {
        $rs = \think\Db::table('t1)->insert([
            'name'=>'a1' 
        ]);
    }
    

    到主,从服务器查看

    验证:从服务器负责读

    给从1插入一条数据,给从2插入一条数据

    控制器读取

    $data = \think\Db::table("t1")->select();
    dump($data);
    

    刷新页面查看

    MySQL管理命令

    【mysql配置文件】
    /etc/my.cnf
    
    【开启mysql服务】
    /php/server/mysql/bin/mysqld_safe --user=mysql &
    
    【关闭mysql服务】
    ps -A | grep mysql        # 查看mysql进程
    kill -9 进程PID 进程PID   #  结束进程  关闭mysql服务  
    
    【登陆MySQL数据库】
     /php/server/mysql/bin/mysql -uroot -p 
    

    相关文章

      网友评论

        本文标题:Sphinx

        本文链接:https://www.haomeiwen.com/subject/oztcpftx.html