[文章作者:张宴 本文版本:v1.0 最后修改:2008.12.09 转载请注明原文链接:http://blog.zyan.cc/post/385/]

  曾经在七月,写过一篇文章──《基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计》,前公司的分类信息搜索基于此架构,效果明显,甚至将很大一部分带Where条件的MySQL SQL查询,都改用了Sphinx+MySQL搜索。但是,这套架构仍存在局限:一是MySQL本身的并发能力有限,在200~300个并发连接下,查询和更新就比较慢了;二是由于MySQL表的主键与Sphinx索引的ID一一对应,从而无法跨多表建立整站查询,而且新增加类别还得修改配置文件,比较麻烦;三是因为和MySQL集成,无法发挥出Sphinx的优势。

  最近,我设计出了下列这套最新的搜索引擎架构,目前已经写出“搜索查询接口”和“索引更新接口”的beta版。经测试,在一台“奔腾四 3.6GHz 双核CPU、2GB内存”的普通PC机,7000万条索引记录的条件下,“搜索查询接口”平均查询速度为0.0XX秒(查询速度已经达到百度、谷歌、搜狗、中国雅虎等搜索引擎的水平,详见文章末尾的“附2”),并且能够支撑高达5000的并发连接;而“索引更新接口”进行数据分析、入队列、返回信息给用户的全过程,高达1500 Requests/Sec。

  “队列控制器”这一部分是核心,它要控制队列读取,更新MySQL主表与增量表,更新搜索引擎数据存储层Tokyo Tyrant,准实时(1分钟内)完成更新Sphinx增量索引,定期合并Sphinx索引。我预计在这周写出beta版。

点击在新窗口中浏览此图片

  图示说明:
  1、搜索查询接口:
  ①、Web应用服务器通过HTTP POST/GET方式,将搜索关键字等条件,传递给搜索引擎服务器的search.php接口;
  ②③、search.php通过Sphinx的API(我根据最新的Sphinx 0.9.9-rc1 API,改写了一个C语言的PHP扩展sphinx.so),查询Sphinx索引服务,取得满足查询条件的搜索引擎唯一ID(15位搜索唯一ID:前5位类别ID+后10位原数据表主键ID)列表;
  ④⑤、search.php将这些ID号作为key,通过Memcache协议一次性从Tokyo Tyrant中mget取回ID号对应的文本数据。
  ⑥⑦、search.php将搜索结果集,按查询条件,进行摘要和关键字高亮显示处理,以JSON格式或XML格式返回给Web应用服务器。

  2、索引更新接口:
  ⑴、Web应用服务器通过HTTP POST/GET方式,将要增加、删除、更新的内容告知搜索服务器的update.php接口;
  ⑵、update.php将接收到的信息处理后,写入TT高速队列(我基于Tokyo Tyrant做的一个队列系统);
  注:这两步的速度可达到1500次请求/秒以上,可应对6000万PV的搜索索引更新调用。

  3、搜索索引与数据存储控制:
  ㈠、“队列控制器”守护进程从TT高速队列中循环读取信息(每次50条,直到末尾);
  ㈡、“队列控制器”将读取出的信息写入搜索引擎数据存储层Tokyo Tyrant;
  ㈢、“队列控制器”将读取出的信息异步写入MySQL主表(这张主表按500万条记录进行分区,仅作为数据永久性备份用);
  ㈣、“队列控制器”将读取出的信息写入MySQL增量表;
  ㈤、“队列控制器”在1分钟内,触发Sphinx更新增量索引,Sphinx的indexer会将MySQL增量表作为数据源,建立增量索引。Sphinx的增量索引和作为数据源的MySQL增量表成对应关系;
  ㈥、“队列控制器”每间隔3小时,短暂停止从TT高速队列中读取信息,并触发Sphinx将增量索引合并入主索引(这个过程非常快),同时清空MySQL增量表(保证了MySQL增量表的记录数始终只有几千条至几十万条,大大加快Sphinx增量索引更新速度),然后恢复从TT高速队列中取出数据,写入MySQL增量表。

  本架构使用的开源软件:
  1、Sphinx 0.9.9-rc1
  2、Tokyo Tyrant 1.1.9
  3、MySQL 5.1.30
  4、Nginx 0.7.22
  5、PHP 5.2.6

  本架构自主研发的程序:
  1、搜索查询接口(search.php)
  2、索引更新接口(update.php)
  3、队列控制器
  4、Sphinx 0.9.9-rc1 API的PHP扩展(sphinx.so)
  5、基于Tokyo Tyrant的高速队列系统



  附1:MySQL FullText、Lucene搜索、Sphinx搜索的第三方对比结果:
  1、查询速度:
  MySQL FullText最慢,Lucene、Sphinx查询速度不相上下,Sphinx稍占优势。
  点击在新窗口中浏览此图片

  2、建索引速度:
  Sphinx建索引速度是最快的,比Lucene快9倍以上。因此,Sphinx非常适合做准实时搜索引擎。

  3、详细对比数据见以下PDF文档:  



  附2:国内各大中文搜索引擎搜索速度分析:
  以“APMServ张宴”为关键字,比较在各大中文搜索引擎的搜索速度:
  1、百度:
  ①、第一次搜索
  点击在新窗口中浏览此图片

  ②、第二次搜索
  点击在新窗口中浏览此图片

  分析:百度对第一次搜索的搜索结果做了Cache,所以第二次查询非常快。



  2、谷歌:
  ①、第一次搜索
  点击在新窗口中浏览此图片

  ②、第二次搜索
  点击在新窗口中浏览此图片

  分析:谷歌也对第一次搜索的搜索结果做了Cache,但两次查询跟百度同比,都要慢一些。



  3、搜狗:
  ①、第一次搜索
  点击在新窗口中浏览此图片

  ②、第二次搜索
  点击在新窗口中浏览此图片

  ③、第三次搜索
  点击在新窗口中浏览此图片

  分析:搜狗疑似对第一次搜索的搜索结果做了短暂的Cache,第二次搜索速度非常快,第三次搜索的速度比第二次搜索的速度慢。搜狗第一次搜索的速度跟百度差不多。



  4、中国雅虎:
  ①、第一次搜索
  点击在新窗口中浏览此图片

  ②、第二次搜索
  点击在新窗口中浏览此图片

  分析:搜索结果没有做Cache。中国雅虎的搜索速度跟百度第一次搜索的速度差不多。



  5、网易有道:
  ①、第一次搜索
  点击在新窗口中浏览此图片

  ②、第二次搜索
  点击在新窗口中浏览此图片

  分析:有道对第一次搜索的搜索结果做了Cache。但是,跟谷歌一样,两次搜索同比都要较百度、搜狗、中国雅虎慢一些。



技术大类 » 搜索引擎技术 | 评论(87) | 引用(1) | 阅读(136353)
spider
2008-12-30 15:45
你好,我想确定一下是不是把所有索引都放在内存中,然后另外再cash一些搜索结果,是这个意思吗?
我觉得想瞬时搜索就是将索引放在内存中搜索,而不是每次都从索引文件中读取的吧?有个朋友说他们每次搜索是从文件中读取的索引然后在解析,我觉得不可能达到毫秒级别的速度,我想知道是不是可以,谢谢!
张宴 回复于 2008-12-30 16:42
在sphinx会在“启动时”将所有索引文件加载到内存中,或者在“初次搜索”时将使用到的索引文件加载到内存中(两种方式可通过配置文件自行选择)。
spider
2008-12-30 17:08
也就是说如果在搜索是读取索引文件是不可能达到很快的速度了?
我是把索引都加载到内存中的,所以担心内存不够用怎么办,呵呵
Hunk Email Homepage
2009-1-11 02:47
请问,如何扩大SPHINX 使用的内存?

目前searchd始终只使用100M内存,速度上不去
   TOP结果:
   20756 root          1  96    0   100M 95572K select   0:00  0.00% searchd
Hunk Email Homepage
2009-1-11 02:48
我已经安装了SPHINX和LibMMSeg ,能运行了。速度一直提不上去,发现searchd进程一直占用100M内存,没有扩大。也没有找到如何配置内存的参数,很困惑,请你指点一下。

   TOP结果:
   20756 root          1  96    0   100M 95572K select   0:00  0.00% searchd
rollenc Homepage
2009-2-1 23:54
好文章, 受教了。
有两个问题想请教一下,

1。  ②③、search.php通过Sphinx的API(我根据最新的Sphinx 0.9.9-rc1 API,改写了一个C语言的PHP扩展sphinx.so),查询Sphinx索引服务,取得满足查询条件的搜索引擎唯一ID(15位搜索唯一ID:前5 位类别ID+后10位原数据表主键ID)列表;

search.so是通过什么方式来获取数据? searchd服务, 还是search 命令行? 亦或其他? search 命令行与searchd相比,其效率和负载分别如何?

2。 ㈤、“队列控制器”在1分钟内,触发Sphinx更新增量索引,Sphinx的indexer会将MySQL增量表作为数据源,建立增量索引。Sphinx的增量索引和作为数据源的MySQL增量表成对应关系;

Sphinx更新增量索引使用什么方式? indexer && restart searchd?  还是 indexer --rotate ?
44qq
2009-2-3 11:27
你测试cache的方法有些问题,因为从大系统的设计角度来看,你所“发现”的cache不见得是人家有意“cache”的结果。而是系统设计上导致的一种副作用,因为对这样的系统而言这种为了cache而cache的思路意义不大
realtime
2009-2-4 01:31
对实时搜索引擎的研究有用。
Chester Email
2009-2-4 17:53
这个方案检索是快,但是在数据同步方面比较麻烦。看过几个架构,各有各的好处,感觉主要还是业务需求了。
chenbing Email
2009-2-12 21:18
比较习惯Lucene+hadoop那一套路,集成到Java Web开发中比较喜欢Compass和Hibernate search。
hevin Email
2009-2-16 17:35
有没有Sphinx java api的demo啊?我搞了很久都搞不出来,有问题
bobma Email
2009-2-16 17:36
有没有Sphinx java api的demo啊?我也搞了很久都搞不出来,有问题。如方便发到俺的这个email里:hevinma@jobmet.com
Symphony
2009-2-18 13:35
不能光看时间吧,百度的结果比谷歌多出一倍,是不是谷歌做了筛选
djw_posion Email
2009-3-18 15:29
您好,感觉您的架构对于单机版是比较优秀的。(第一次看您的blog感觉很不错)
有三个问题:
1. 有一个数据我想知道7000万条记录是什么数据,是html正文还是标题之类的?(这个对索引的速度和膨胀率都有一定的影响)
2. “5000并发”是如何测试的,cache的命中率是多少?
3. 查全、查准率有没有进行系统的评测?
manof
2009-3-21 22:22
beta版还没出来吗?
luo
2009-4-6 12:00
冒昧的问一下,想知道大体的性能。
多大的数据量(索引大小),每秒的事务处理能力如何
sousw Email Homepage
2009-4-12 15:21
强劲...
路人甲
2009-6-2 17:15
对于实时更新:准实时(1分钟内)完成更新Sphinx增量索引,定期合并Sphinx索引。一分钟内的索引更新量有多大?索引在更新的同时还需要提供对外检索服务,更新过于频繁的话,对检索的性能会有比较大的压力吧。

系统的性能和具体的应用强相关,baidu,google,soso在检索的流程中做了相当多的应用优化:包括检索结果和检索词的相关性分析,一些不良结果的过滤,检索结果的二次重排,打散同一域名下的相同内容...........。其中任何一个特性都对性能产生重要影响,对索引的结构也会产生很大冲击。

从表面上看,你搭建的这套系统只实现了搜索引擎比较原始的功能,搜索结果的质量可能也不太好,在这样的前提下和 baidu、google比性能不太公平。
lucky
2009-6-3 10:28
当数据远大于内存时,就会发现,baidu,google的速度是相当的不简单了。
如果内存可以cache所有索引的话,用hash查找的速度也不会慢,呵呵。
freeman983 Email
2009-7-9 15:25
请教这套架构中所用的分词技术?
张宴 回复于 2009-7-10 00:45
ictclas
永和大王
2009-7-28 23:56
能开放源码吗?
分页: 2/5 第一页 上页 1 2 3 4 5 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]