贝网博客

我的分类
流水记事
源码下载
Asp.net
其它
数据库
Javascript
.Net技术
我的相册
友情链接
博客园
CSDN博客
Start0
最新回复
fasdfasdf
[:..
lz这个东西好厉害,我..
哈哈,好照片
不错,以前一直用黄色..
终于找到支持ff的修正..
终于找到支持ff的修正..
新鲜性
看看,试试,好不好使。
好东西一起学习[:img0..
分类 =》.Net技术
软件搜索站点部署和使用过程中的优化
发表于:2012-11-01 11:24:00
更新于:2012-11-01 11:25:26

记录一下自己负责的软件搜索站点的优化过程

1、最初级的搜索方案,就是直接在SqlServer里使用类似这样的SQL语句:where name like '%keyword%' order by downNum desc
这个方案效率很低,全表扫描,数据量小还凑合,数据大了,SQLServer的CPU压力直线上升,而使用数据库本身的全文检索方案,很多结果出不来,放弃

2、建立一个搜索类给各个应用项目去引用,定义一个List<Soft>静态变量,每隔半小时,从数据库把所有软件数据填充到这个静态变量,搜索时,通过foreach循环这个List变量,用代码:
foreach(Soft s in list){
  if(s.Name.IndexOf(keyword) >= 0){
    returnLst.Add(s);
  }
}
把sql的like方案放到web服务器的内存中来匹配,效率比sql确实快了很多,而且压力分散到各个web服务器,数据库的压力减轻了很多,但是缺点同样很明显,就是每台web服务器都保存一份内存,到了半小时,都去数据库更新数据,这个时间点数据库压力一样很大,使用很短时间后,放弃

3、把搜索代码分离出来,单独架设一个搜索站点,通过WCF或JSON接口提供搜索服务,各个应用项目调用这个WCF或JSON接口实现搜索功能,同时改用盘古分词搜索功能,大大丰富了搜索结果数量不足的缺点
但是因为盘古分词搜索依赖于词库,对于新词,比如微博、陌陌之类,如果没有维护,就会搜索不到,另外对于非词组,也会搜索不到结果,最后把方案2中的IndexOf搜索功能也加上,先进行IndexOf搜索,再进行盘古分词搜索,把2个结果的并集返回,造成搜索站点的效率比较低下,而搜索内容又非常多样,把每个搜索词的搜索结果加入缓存也不太现实,内存占用太大,于是改进为对每周的TOP5000搜索词的搜索结果存入缓存,提高缓存命中率,同时还引入了Redis内存数据库,避免得到软件id列表,再去访问数据库时也造成数据库压力

4、一些细节改进:
  a、WCF接口不支持GZIP压缩,使用SOAP协议,造成网络流量偏大,弃用,改用ashx接口,通过Protobuf序列化结果并gzip压缩后返回,同时为调用方封装dll,请求ashx接口并反序列化,经过压力测试,Protobuf接口比WCF接口,网络流量降低了一半,cpu和内存压力也有很大提升,具体数据有空再贴上来吧
  b、s.Name.IndexOf(keyword) 修改为 s.Name.IndexOf(keyword, StringComparison.Ordinal),因为循环量非常大,这个小改进也降低了站点的不少压力
  c、对几十万的软件加载到内存时,根据标题的每个char进行分组到Dictionary中,原理大致是:如果搜索:手机,只对标题包括“手”的那些软件进行循环,这个功能加入后,站点的cpu压力降低了10%
  d、缓存由HttpRuntimeCache,改为自定义的静态变量保存缓存,在缓存过期时,也返回过期缓存,同时后台启动一个线程去填充新的数据,避免缓存过期时,都去执行业务的压力

发表评论
名称(*):
邮箱:
正文:

©2008 Beinet.cn 版权所有