推广 热搜: 服务  数据分析系统  搜索  获取  冬季  软件  计划  数据分析  关键词  好友 

万字详解PHP+Sphinx中文亿级数据全文检索实战(实测亿级数据0.1秒搜索耗时)

   日期:2024-11-07     作者:izped    caijiyuan   评论:0    移动:http://changmeillh.kub2b.com/news/73.html
核心提示:Sphinx查询性能非常厉害,亿级数据下输入关键字,大部分能在0.01~0.1秒,少部分再5秒之内查出数据。官方文档:http://sphinxsear

Sphinx查询性能非常厉害,亿级数据下输入关键字,大部分能在0.01~0.1秒,少部分再5秒之内查出数据。

万字详解PHP+Sphinx中文亿级数据全文检索实战(实测亿级数据0.1秒搜索耗时)

  • 官方文档:http://sphinxsearch.com/docs/sphinx3.html
  • 极简概括:
    由C++编写的高性能全文搜索引擎的开源组件,C/S架构,跨平台(支持Linux、Windows、MacOS),支持分布式部署,并可直接适配MySQL。
  • 解决问题:
    因为MySQL的 like %keyword% 不走索引,且全文索引不支持中文,所以需要借助其它组件。适用于不经常更新的数据的全文搜索。
  • 同类产品:
    ElasticSearch、Solr、Lucene、Algolia、XunSearch。
  • 使用思路:
    发送给Sphinx关键字,然后Sphinx返回id给PHP,PHP再调用MySQL根据id查询。也就是帮着MySQL找id的,MySQL走主键索引,查询性能很高。
  • API支持:
    Sphinx附带了三种不同的API,SphinxAPI、SphinxSE和SphinxQL。SphinxAPI是一个可用于Java、PHP、Python、Perl、C和其他语言的原生库。SphinxSE是MySQL的一个可插拔存储引擎,支持将大量结果集直接发送到MySQL服务器进行后期处理。SphinxQL允许应用程序使用标准MySQL客户端库和查询语法查询Sphinx。
  • SQL扩展
    Sphinx不仅限于关键字搜索。在全文搜索结果集之上,您可以计算任意算术表达式、添加WHERe条件、排序依据、分组依据、使用最小值/最大值/AVG值/总和、聚合等。本质上,支持成熟的SQL SELECt。
    1. 决策分析:
      亿级的数据量,还都得是中文,如果是52个大小写字母和10个数字可以随机,中文随机效果差,最好是有能阅读通畅的数据源,而不是随机汉字数据源。
    2. 尝试寻找:
      尝试看了txt版的《三国演义》,发现行数太少,所以转变思维,更大的数据量,只能是长篇小说,翻看了最长的小说,也才22万行,1行小说对应1条MySQL数据,数据量还是太少,虽然循环小说内容插入也行,但还是差点意思。
    3. 资源整合:
      程序员天天玩的就是数据,这点小事难不倒我,去网盘找txt小说资源合集https://www.aliyundrive.com/s/LBBg4ZvWip2/folder/63a138e95845afd3baa947db96342937033c254f
      找到了如下35000本txt的小说。
    4. 数据合并:
      下载了几千个txt小说,需要用命令把这些合并成一个文件,使用方便PHP程序逐行读取。整合后的单个txt文件9.57个G。
    5. 数据入库:
      大数据文件一次加载会把内存撑爆,所以需要使用去逐行读取文件。
      1. 性能调优:
        MyISAM引擎:
        insert 发现1秒才1400行的插入速度,不行得调整。

        优化后,每秒2万的插入速度。

        如果是InnoDB引擎
        可以调整redo log 刷盘策略,。
        并添加缓冲池。
        ,就行了。

      2. 数量检查:
        两万年后,用一看,数据量109 450 000,搞定。

      3. 性能测试:
        SELECT count(*) FROM articles where content like '%晴空万里%',找出来了1931个,花了242秒。

      4. 装好之后配置它,汉字是提示,记得运行环境要删掉

        开启服务

        PHP SphinxClient手册:http://docs.php.net/manual/tw/class.sphinxclient.php

        这是二次改过的test_coreseek.php,对于新手有很友好的提示。

      5. 官方文档:https://sphinxsearch.com/docs/current.html#matching-modes
      6. 调用方法:
      7. 分词举例:假设关键字“白色衣服”,词语被分成了“白色”和“衣服”。
      8. 匹配模式 一句话概括 会被匹配 不会被匹配 SPH_MATCH_ALL 同时包含这些分词时会被匹配 白色的绳子晾着他的衣服 他的衣服 SPH_MATCH_ANY 匹配任意一个分词就行 白色的纸 白云 SPH_MATCH_PHRASE 相当于like '%关键词%' 白色衣服 SPH_MATCH_EXTENDED 支持Sphinx的表达式 SPH_MATCH_EXTENDED2 SPH_MATCH_EXTENDED的别名 SPH_MATCH_BOOLEAN 支持布尔方式搜索 SPH_MATCH_FULLSCAN 强制使用全扫描模式

        详解:SPH_MATCH_FULLSCAN
        SPH_MATCH_FULLSCAN,强制使用全扫描模式。注意,任何查询项都将被忽略,这样过滤器、过滤器范围和分组仍然会被应用,但不会进行文本匹配。
        当满足以下条件时,将自动激活SPH_MATCH_FULLSCAN模式来代替指定的匹配模式:
        查询字符串为空(即:它的长度是0)。
        Docinfo存储设置为extern。
        在完全扫描模式下,所有索引的文档都被认为是匹配的。这样的查询仍然会应用过滤器、排序和分组,但不会执行任何全文搜索。这对于统一全文和非全文搜索代码或卸载SQL服务器很有用(在某些情况下,Sphinx扫描比类似的MySQL查询执行得更好)。

      9. 服务器配置:CentOS7.6 16核4G内存

      10. 实测亿级数据下搜索晴空万里只花费0.011秒,上文提到MySQL则需要242秒,性能差了22000倍。或许是受或分词器影响,Sphinx查询出来1898条,MySQL查询数据为1931条

      11. 多次测试:在109450000条数据中,从不同角度测试Sphinx SPH_MATCH_PHRASE匹配模式,相当于mysql where field like '%关键字%':

      12. 搜索关键字 Sphinx搜索耗时(秒) MySQL搜索耗时(秒) Sphinx搜索数量 MySQL搜索数量 数字 123 0.005 305.142 3121 8143 中文单字 虹 0.013 223.184 67802 103272 英文单字母 A 0.031 339.576 136428 1017983 单中文标点 。 4.471 125.106 67088012 67096182 单英文标点 . 251.171 6697242 可打印特殊字符 ☺ 355.469 中文词语(易分词) 黑色衣服 0.066 346.442 1039 1062 中文词语(不易分词) 夏威夷 0.011 127.054 3636 3664 中文词语(热门) 你好 0.022 126.979 102826 137717 中文词语(冷门) 旖旎 345.493 4452 4528 英文单词 good 137.562 553 1036 中文短语 他不禁一脸茫然 1.742 218.272 英文短语 I am very happy 0.015 355.235 长文本 陈大人不急着回答,他先从柜台下面又抽出了一份文案,翻了好一阵之后才回答道:“瞧,果然如此,如今广州这边官职该放得都放出去了,只剩下消防营山字营的一个哨官之职。不出所料的话,督抚大人准会委你这个职务。 0.131 129.204

        压测方式 :ab -c 1 -n 10~1000 192.168.3.180/test_coreseek.php

        中文定值关键字为华盛顿,英文定值关键字为XYZ,30位随机中文或英文字符,由代码生成。

        请求量 (搜索次数) 耗时(秒) 0.256 1.435 11.604 0.517 2.305 17.197 0.327 0.747 8.510 0.077 0.766 9.428

        对于update很多数据,sphinx不会自动更新索引,所以可以选择在公司业务空闲时间重建索引。
        对于insert,可以使用增量索引,创建一个表用于存储已经新增sphinx索引记录的最大值。

      13. 对于Sphinx:当需要新增增量索引时,读取这个表中的数据,获取到这个值,使其创建索引的起始点,为max_id字段的值。
      14. 对于max_id字段的业务作用:可以封装一个方法,可以让这个值载入Redis,redis有值就读取,无值就查询然后载入Redis。
      15. 对于业务代码:例如100万行数据创建了Sphinx索引,然后又新增了1000条,这1000条数据没有sphinx索引,可以在业务代码中使用mysql union或者其它方式,让这1000条数据,做查询。
        伪代码如下:
      16. 这块需要承接上文。

        这个也好办,直接在csft.conf配置文件内source段和index段复制粘贴,根据上文的两段文章,该创建索引的创建索引,该重启的重启。
        不需要引入多个文件,就和MySQL一样,只需要一个/etc/my.cnf就行了,相加配置,接着往下续就行了。

        新创建索引后不会生效,需要关闭searchd进程后重新启动。

        方案1:
        使用composer安装新的包,PHP8.0及以上不会报错。
        记得要搜索sphinx client或sphinxapi,不要搜素sphinx,这会把SphinxQL的解决方案也给搜出来。
        用这个包就行,composer require nilportugues/sphinx-search
        用法与自带的完全一致,而且遇到PHP8不报错。

        方案2:
        使用原生自带的包,PHP8.0及以上会报错。
        sphinxapi.php放置到app/Libs/Others目录下,并添加自己的命名空间AppLibsOthersSphinxApi。
        app/Libs/helper.php存放了自定义封装的方法,并使用composer dump-autoload配置,跟随框架自动加载。

    本文地址:http://sicmodule.kub2b.com/news/73.html    企库往 http://sicmodule.kub2b.com/ , 查看更多
     
     
    更多>同类最新资讯
    0相关评论

    新闻列表
    企业新闻
    推荐企业新闻
    推荐图文
    推荐最新资讯
    点击排行
    网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号