以前在IBM做后端开发时,也接触过关于缓存技术,当时给了n多文档来学习,后面由于其他紧急的项目,一直没有着手去仔细研究这个技术,即时后来做Commerce的时候,后台用了n多缓存技术,需要build index,甚至在category里面都用了缓存,其实一直不明白,为什么那么简单的数据都需要做缓存技术,在技术角度来说,肯定是能实现的,当category比较稳定的状态,确实用起来会比较快吧,其实,当数据小的时候,或者当没有大数据类型 text的时候,未必哪种技术就更优秀呢。

记录一下,之前我接触过的里面,是会用到kafka去做index的更新。

先说用搜索引擎的原因:笔者做在公司 网站www.baicaio.com后台记录20万条以上,且有不断增长的趋势,而由于历史原因,之前编辑的文章,对标题,标签,文章内容(text) 没有做很好的规范,且用户真正想搜索的东西,可能会在文章内容里面。搜索时会比较慢,给用户体验不好,为了让体验好起来,我们之前只搜索标题,标签,虽然如此,但针对 keyword1_keyword2 这种,最后都会转换成 column1 like "%keyword1%keyword2%" or column1 like "%keyword2%keyword1%" or column2 like "%keyword1%keyword2%" or column2 like "%keyword2%keyword1%", 这个sql语句的效率可想而知。

解决方案:创建自己的搜索引擎

实践过程:我们准备试试xunsearch,因为它免费,服务器linux,前端php,于我们而言,很完美的适配,这可能就是为什么说php是世界上最好的语言的原因了吧。:)

1.download and unzip

wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2
tar -xjf xunsearch-full-latest.tar.bz2 2.install
cd xunsearch-full-1.3.0/
sh setup.sh
//run setup.sh的时候出现乱码,解决方案,把setup里面的中文echo去掉,再运行就好了. 3.启动服务
bin/xs-ctl.sh -b local start    // 监听在本地回环地址 127.0.0.1 上
bin/xs-ctl.sh -b inet start // 监听在所有本地 IP 地址上
bin/xs-ctl.sh -b a.b.c.d start // 监听在指定 IP 上
bin/xs-ctl.sh -b unix start // 分别监听在 tmp/indexd.sock 和 tmp/searchd.sock 4.创建项目配置文件 $prefix/sdk/php/app/baicai.ini
这里要引用官方的文档,里面说得最详细,摘出来给不喜欢看文档的朋友们,当然,如果你只是想做下试验,这些细节确实没必要看:
  1. 服务器连接参数

    服务端连接参数的格式包含 3 种格式:

    1. 端口号(数字),连接 localhost 的该端口号 (例:8383)
    2. 地址:端口号,冒号连接地址(域名、IP地址)和端口 (例:127.0.0.1:8383)
    3. 文件路径,本机的 unix socket 连接路径 (例:/tmp/index.sock)
    ; 索引服务端配置,默认值为 8383
    server.index = 8383
    ; 搜索服务端配置,默认值为 8384
    server.search = 8384

    Note: 自 1.4.7 起,服务端地址可以使用 ; 分隔指定多个。 索引更新将同步到所有服务端,而搜索则随机从中挑选一个可用的服务端以达到均横效果。

3. 项目字段设计

每个搜索项目均可以简单地理解为单表检索,凡是涉及关联表的, 请将关联记录转换为搜索项目的新字段并设置对应的分词规则。字段设计很重要, 请仔细根据需求创建,字段名建议和您的实际数据库字段一致。

  1. 定义字段

    每个字段用一个区段配置来表示,中括号内的名字即为字段名。每个项目包含若干个字段, 具体由项目搜索需求决定,并不需要一味的与实际源数据库 (如 MYSQL) 一致, 而只需要设计搜索功能所涉及的字段即可。

    [field_name]
    
  2. 字段选项

    每个字段根据实际情况指定字段选项,所有选项均有默认值,所以即便不指定任何选项而只有中括号定义的字段, 那也是一个合法的字段,字段选项包括以下几种:

    type 字段类型

    • string 字符型,适用多数情况,也是默认值
    • numeric 数值型,包含整型和浮点数,仅当字段需用于以排序或区间检索时才设为该类型,否则请使用 string 即可
    • date 日期型,形式为 YYYYmmdd 这样固定的 8 字节,如果没有区间检索或排序需求不建议使用
    • id 主键型,确保每条数据具备唯一值,是索引更新和删除的凭据,每个搜索项目必须有且仅有一个 id 字段,该字段的值不区分大小写
    • title 标题型,标题或名称字段,至多有一个该类型的字段
    • body 内容型,主内容字段, 即本搜索项目中内容最长的字段,至多只有一个该类型字段,本字段不支持字段检索
    type = string
    

    index 索引方式

    xunsearch 的索引有 2 种模式:其一是不标明字段的检索,称之为“混合区检索”;其二是标明特定字段的“字段检索”。 例如:搜索 XXX YYY 表示在混合区检索,返回的结果可能是 title 也有可能是 body 字段符合匹配; 而搜索 title:XXX 则表示仅检索 title 匹配 XXX 的数据。每个字段可以指定的索引方式的值如下:

    • none 不做索引,所有的搜索匹配均与本字段无关,这个字段只用于排序或搜索结果展示用到。
    • self 字段索引,可以在搜索时用 field:XXX 来检索本字段
    • mixed 混合区索引,不标明字段的默认搜索也可以检索本字段
    • both 相当于 self + mixed,两种情况均索引

    通常情况默认值为 none ,但 id 型字段默认是 self ,title 型字段是 both ,body 型字段则固定为 mixed 。

    index = none
    

    tokenizer 分词器

    默认为 default 采用内置的功能强大的 scws 分词,适合绝大多数字符串字段。也可以指定自定义分词器, 格式为 name 或 name(arg) 两种形式,其中 name 是分词器名称,arg 则是传递给分词器构造函数的参数。 自定义分词器需要在 lib/ 目录下编写名为 XSTokenizerName 的分词类并实现接口 XSTokenizer, 内置支持的分词器有以下几种:

    • full 表示本字段的值整体作为一个检索词,像各种 ID 都适合这种情况
    • none 表示本字段没有任何词汇用于索引
    • split([ ]) 表示根据参数分割内容,默认参数为空格,若参数以 / 开头并以 / 结尾则 内部调用 preg_split(arg, ..) 来分割取词,以支持正则或其它特殊字符分割
    • xlen([2]) 表示根据指定参数长度分段取词,如 ABCDEF => AB + CD + EF
    • xstep([2]) 表示根据指定参数步长逐段取词,如 ABCDEF => AB + ABCD + ABCDEF
    • scws([3]) 表示采用指定参数为复合等级的 scws 分词,(若无特殊复合需求,无需指定)
    tokenizer = default
    

    Note: 小括号内的值表示参数,中括号表示省略后的默认值,实际编写请勿照抄中括号!!!

    cutlen 搜索结果摘要截取长度

    默认值为 0 表示不截取。主要是针对某些内容特别长的字段在返回结果时自动剪取包含关键词的一小段文字。 典型的是 body 型字段默认为 300 。长度单位是字节,通常 UTF-8 编码的一个汉字为 3 个字节。

    cutlen = 0
    

    weight 混合区检索时的概率权重

    在混合检索时,可以对标题和内容等不同字段进行权重计算,如果你不想该字段参与计算权重可设为 0 。 通常默认值为 1 ,但 title 型默认为 5 而 body 型则固定为 1 。

    weight = 1
    

    phrase 是否支持精确检索

    即当给搜索语句加上引号时,则要求匹配的结果必须严格按照搜索词的顺序匹配,此外还支持用 NEAR 之类的语法来做精确检索,具体参见:搜索技巧 。通常默认值为 no 但是 title 和 body 型字段默认则为 yes 。值得注意的是该功能仅支持默认分词器,如非必要请勿开启此项, 因为这会增加索引数据的大小。

    phrase = no
    

    non_bool 强制指定是否为布尔索引

    布尔索引不参与权重排名计算,默认情况下所有自定义分词器的字段均为布尔索引。因此, 当您使用自定义分词器却又想让本字段参与权重计算的话,请将本项设为 yes。

    non_bool = yes
    
4. 配置示例文件

下面是 discuz 搜索项目的配置示范文件,包含 12 个字段。其中可以看到 tid 和 fid 虽然从内容上讲它们都是数字型,但没有排序需求所以仍应为 string 类型,而 dateline 由于有排序需求,所以必须指定为 numeric 类型。

    project.name = sample
project.default_charset = GBK
;server.index = 8383
;server.search = 8384 [pid]
type = id [subject]
type = title [message]
type = body [dateline]
type = numeric [author]
index = both [authorid] [tid]
index = self
tokenizer = full [fid]
index = self
tokenizer = full [flag] 上面的规则很重要,但是对于做试验来说,不重要。如果当你真正要设计一个搜索时,你会回过头来仔细研究这个文档,来满足你的搜索需求,比如我需要对某些字段进行搜索,我会考虑多加一些self字段进来。
然后就是根据这个ini来创建自己的索引,这个过程可能需要几十秒到1分钟。
/usr/local/xunsearch/sdk/php/util/Indexer.php --rebuild --source=mysql://dbuser:dbpwd@dbhost/db_name/ --sql="select xxx from xxx where xxx" --project=baicai
在我build的时候,httpd会down掉,目前不知道原因,需要重启 做完这些之后,就相当于你的搜索库已经创建好了,你可以在/usr/local/xunsearch/data/baicai 下面看到属于你的文件:

然后我们在搜索时,需要加入这段代码:

require LIB_PATH . 'Pinlib/php/lib/XS.php';
$xs = new XS('baicai');
$search = $xs->search; // 获取搜索对象
$search->setLimit(20,20*($p-1));
$search->setSort('add_time',false);
$search->setQuery($q);
$docs = $search->search();

记得注意的是docs不能直接拿来我们的php用,我们需要再转换一次.

$item_list = Array();
foreach ($docs as $doc) {

$item['title'] = $doc->title;
$item['img'] = $doc->img;
$item['id'] = $doc->id;
$item['price'] = $doc->price;
$item['add_time'] = $doc->add_time;
$item['zan'] = $doc->zan;
$item['hits'] = $doc->hits;
$item['comments_cache'] = $doc->comments_cache;
$item['orig_id'] = $doc->orig_id;
$item['go_link'] = $doc->go_link;
array_push($item_list,$item);
}

需要把方法变成属性。

然后试试你的搜索吧,是不是快了很多呢?但是还没完。

当你对你的数据编辑之后,你会发现搜索结果没有变,这是为什么呢?

1.我们的搜索是针对自己用xunsearch build出来的文件进行搜索,数据库变了,这些文件并没有变,所以需要对文件索引进行更新,当加入一条数据,要add一个索引,当remove,需要del一个索引,当update,需要update一个索引。

if($data['status'] == '1' ){
$doc = new XSDocument;
$xu_data = M("item")->where("id=$data[id]")->find();//查询数据库
$doc->setFields($xu_data);
//更新到索引数据库中
$index->update($doc);
}
else{
$index->del($data['id']);
}

我们只需要把status=1的数据收录其中,所以会这样去写,大家可以根据自己的项目需求去灵活处理这一段逻辑。

这个索引只是针对我们的xunsearch的数据表,并不会提交到数据库中,所以大家还是要保留自己的数据库update的部分。

												

免费大数据搜索引擎 xunsearch 实践的更多相关文章

  1. 用Python实现一个大数据搜索引擎

    用Python实现一个大数据搜索引擎 搜索是大数据领域里常见的需求.Splunk和ELK分别是该领域在非开源和开源领域里的领导者.本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家 ...

  2. 我的ElasticSearch集群部署总结--大数据搜索引擎你不得不知

    摘要:世上有三类书籍:1.介绍知识,2.阐述理论,3.工具书:世间也存在两类知识:1.技术,2.思想.以下是我在部署ElasticSearch集群时的经验总结,它们大体属于第一类知识“techknow ...

  3. 《Hadoop大数据架构与实践》学习笔记

    学习慕课网的视频:Hadoop大数据平台架构与实践--基础篇http://www.imooc.com/learn/391 一.第一章 #,Hadoop的两大核心:     #,HDFS,分布式文件系统 ...

  4. 用 Python 实现一个大数据搜索引擎

    搜索是大数据领域里常见的需求.Splunk和ELK分别是该领域在非开源和开源领域里的领导者.本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理. 布隆过滤器 ...

  5. ClickHouse在大数据领域应用实践

    一.序言 面向大数据量查询数据库,优点是在较大数据量(千万级)的前提下具有较好的查询性能. 1.应用场景 ClickHouse应用于OLAP(在线分析处理)领域,具体来说满足如下特点使用此技术比较合适 ...

  6. 大数据平台迁移实践 | Apache DolphinScheduler 在当贝大数据环境中的应用

    大家下午好,我是来自当贝网络科技大数据平台的基础开发工程师 王昱翔,感谢社区的邀请来参与这次分享,关于 Apache DolphinScheduler 在当贝网络科技大数据环境中的应用. 本次演讲主要 ...

  7. 大数据搜索引擎之elasticsearch使用篇(一)

    作者:yanzm 原文来自:https://bbs.ichunqiu.com/thread-42421-1-1.html 1.基础介绍 本期,我们将着重介绍elasticsearch的基本使用方法. ...

  8. WOT干货大放送:大数据架构发展趋势及探索实践分享

      WOT大数据处理技术分会场,PingCAP CTO黄东旭.易观智库CTO郭炜.Mob开发者服务平台技术副总监林荣波.宜信技术研发中心高级架构师王东及商助科技(99Click)顾问总监郑泉五位讲师, ...

  9. 流式大数据计算实践(1)----Hadoop单机模式

    一.前言 1.从今天开始进行流式大数据计算的实践之路,需要完成一个车辆实时热力图 2.技术选型:HBase作为数据仓库,Storm作为流式计算框架,ECharts作为热力图的展示 3.计划使用两台虚拟 ...

随机推荐

  1. 学习Opencv 2.4.9 (一)---Opencv + vs2012环境配置

    作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 首先获得最新的Opencv 2.4.9源代码:opencv源代码下载 一.Opencv环境变量配置 ...

  2. canvas鼠标点击划线

    今天学习了canvas,打算写一个鼠标划线的效果. <!DOCTYPE html> <html lang="en"> <head> <me ...

  3. C项目实践--贪吃蛇(1)

    1.功能需求分析 1.1主要功能 i.游戏欢迎界面 ii.游戏执行功能,包括计算得分 iii.游戏结束界面 1.2游戏基本规则 游戏开始时蛇的长度是4个单位,并且按照当前方向不停地移动.移动范围是CO ...

  4. ip地址的唯一性是如何保证的

    连接ISP网络时,运行商就分配了一个ip地址,所以,ip地址是运营商指定的. 账户只是控制是否可以接入而已,只要是插上网线,就已经动态分配了ip地址.

  5. ubuntu切换中英文通用方法,ubuntu中文语言

    1:点击桌面右上角的齿轮,选择“system settings”进入系统设置界面

  6. Linux MTD下获取Nand flash各个参数的过程的详细解析【转】

    本文转载自:https://www.crifan.com/files/doc/docbook/nand_get_type/release/html/nand_get_type.html 文章不错可以看 ...

  7. HDU4738 Caocao's Bridges —— 边双联通分量 + 重边

    题目链接:https://vjudge.net/problem/HDU-4738 A network administrator manages a large network. The networ ...

  8. YTU 2598: 编程题B-小平智斗自动售货机

    2598: 编程题B-小平智斗自动售货机 时间限制: 1 Sec  内存限制: 128 MB 提交: 268  解决: 69 题目描述 LYH自动售货机在销售商品时,具有自动找钱功能.但是找零的最小单 ...

  9. sphinx索引部分源码续——过程:连接到CSphSource对应的sql数据源,通过fetch row取其中一行,然后解析出field,分词,获得wordhit,最后再加入到CSphSource的Hits里

    后面就是初始化一些存储结构,其中重点说下缓存出来的几个临时文件分别的作用.结尾时tmp0的存储的是被上锁的Index,有些Index正在被查询使用 故上锁.tmp1,即对应将来生成的spp文件,存储词 ...

  10. mac终端命令加密压缩文件为zip包

    mac终端命令加密压缩文件为zip包,命令如下: zip -e ~/desktop/a.zip b.doc c.txt d.sql 注释:a.zip为加密后的文件 b.doc c.txt d.sql为 ...