基于 lucene 的站内搜索实战


      Beta 技术沙龙
           http://club.blogbeta.com
          官方 twitter : @betasalon

 tangfulin <tan...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
关于手机之家

手机之家是一个旨在提供全方位的手机相关服务的资讯类网站。在 7 年的

时间里,手机之家从无到有,已经发展成为极具人气、最受关注的手机产

品资讯网站。



目前已有的一些统计数据:

●a. 1100w+ 用户
●b. 30...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
手机之家的搜索 V1.0(1/3)
   产品大全搜索
   新闻 CMS  搜索
   论坛搜索(默认只搜索标题)
   论坛帖子及回复搜索
   手机铃声,主题,电子书,软件搜索
   二手交易搜索
   其它版块的搜索
手机之家的搜索 V1.0(2/3)

    基本实现了多个业务模块需要的搜索功能
    
        不同的搜索字段
    
        不同的排序方式
    
        不同的更新频率
    
       ...
手机之家的搜索 V1.0(3/3)
   运行概况
       Dev by chaoqian (http://www.longker.org/)
       最初基于 Lucene 2.2 ,当前 2.4.1
       开发时...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
需求背景 (1/3)

    重建索引
    
        索引字段变更
    
        分词算法变更
    
        搜索结果异常(记录重复,记录丢失)
    
        索引文件意外损坏
   ...
需求背景 (2/3)

    缩短更新周期(及时更新)
    
        Google 更新手机之家内容的周期为 30 分钟左右
    
        V1.0 索引更新周期为 10 - 15 分钟左右
    
    ...
需求背景 (3/3)
   搜索大索引( V1.5 )
       3300+ 万条记录的一个库, xml 原始文件 14G
       V1.0 索引文件为 13 G ,无法快速更新
       V1.5 索引文件为 3.9G ...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
目标

    及时更新( 3 分钟)

    快速重建( < 2 小时)

    可配置(拥抱需求变化)

    可监控(运维友好)

    SLA :永远可写,永远可读,异常的时候唯一的表现是
    更新延迟

   ...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
进度

    2009 年 4 月 1 号 search 2.0 init

    4 月 12 号,修改版本号为 1.5

    6 月 1 号, search 1.5 在线上试运行

    6 月 22 号,正式替换原来的搜...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
设计 (1/8)

    分离索引与存储,二次读取

    分离读与写

    分离 update 和 rebuild

    拆分大库和小库

    new open 小库(小库滚动), reopen 大库

    新...
设计 (2/8) 分离索引与存储,二次读取
   索引里只存储 id ,其他的字段只索引不存储。
   优点:
       保持索引的大小为一个可接受的范围
       提高索引读取速度
       提高索引 cache 效率
...
设计 (3/8) 分离读与写

    优点:
    
        降低编程复杂度
    
        保证搜索服务的可用性,和可扩展性(可以将索引文件
        分发到多台机器上,同时对外提供服务)
    
   ...
设计 (4/8) 分离       update 和 rebuild


    Rebuild 的同时, update 正常更新

    Rebuild 需要将重建这段时间的更新计入新的索引中

    Rebuild 完成后,通知 ...
设计 (5/8) 拆分大库和小库

    保证及时更新的同时,减少索引频繁同步(由写索引同
    步到读索引)带来的 io 压力

    更新频率
    • 小库(最近更新库) 1 分钟
    • 大库(历史库) 1 天到 1 周...
设计 (6/8) 拆分大库和小库(续)

    增加新记录:
    
        增加到小库

    更新记录:
    
        从大库中删除(标记删除)
    
        从小库中删除(物理删除)
   ...
设计 (7/8) 搜索端索引更新

    小库每次同步到一个新的文件夹中

    保留最近打开的 n (2) 份小库索引目录

    检测到新的索引到达,关闭一个最旧的,打开新的,预
    热后标识为可用

    检测到新的小...
设计 (8/8) 新索引预热

    目的:消除新打开的索引上前几次搜索慢的问题

    实现:
    • 过去:遍历一遍新打开的索引,将数据都读入内存
     • 引起 gc ,导致搜索暂停
     • 对 lucene 内置的...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
实现 (1/8)
                                         IndexRebuilder
    搜索管理后台
 发出开始重建索引命令         IndexReceiver
  cron 发送重建数...
实现 (2/8)IndexReceiver
                                          IndexRebuilder
     搜索管理后台        IndexReceiver
  发出开始重建索引...
实现 (2/8)IndexReceiver

    By Java , Daemon 程序

    监听端口,使用 SCGI 通讯协议

    使用 Monkey 为底层 NIO 处理框架

    接收客户端 post 过来的数...
实现 (3/8)IndexUpdater
                                         IndexRebuilder
     搜索管理后台
  发出开始重建索引命令
   cron 发送重建数据
     ...
实现 (3/8)IndexUpdater

    By Java , Daemon 程序

    多个索引共用,每个索引起一个线程

    可根据需要随时停止或启动单个索引更新的线程

    AddShutdownHook 退出...
实现 (4/8)IndexRebuilder
                                     IndexRebuilder

     搜索管理后台
  发出开始重建索引命令
   cron 发送重建数据
      ...
实现 (4/8)IndexRebuilder

     By Java , Daemon 程序

     多个索引共用,每个索引一个线程

     重建索引时序图:
                                 ...
实现 (5/8)IndexRebuilder

    切换索引过程
    • Updater 删除自己当前的索引和未更新完的 xml 文件
    • Updater 将 rebuilder 的索引和 rebuild-update 的 x...
实现 (6/8)Transfer

     搜索管理后台
  发出开始重建索引命令
   cron 发送重建数据
                              Rebuild
                          ...
实现 (6/8)Transfer

    Bash 脚本,每个 indexId 一个进程,由 ControlCenter 或 monitor 启
    动和停止

    监控索引快照目录

    快照目录下存在子目录,并且子目录中...
实现 (7/8)Searcher

     搜索管理后台
  发出开始重建索引命令
   cron 发送重建数据
                           Rebuild
                           xm...
实现 (7/8)Searcher

    By Java , Daemon 程序

    使用 Monkey 为底层 NIO 处理框架

    使用 SCGI 通讯协议

    启动后第一件事: warmUpAllIndex
...
实现 (8/8)Utils

    Cleaner
    • Bash 脚本,每个 indexId 一个进程
    • 用来删除 Searcher 已经关闭或跳过的索引

    Monitor
    • 监控系统的各个进程是否存在...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
性能简单测试结果
   Apache bench
       ­n 1000 ­c 10   ( 99%    545ms     100%  32838ms )
       ­n 2000 ­c 20   ( 90%   1171m...
性能对比测试结果 (1/6)
   Apache bench
       库大小: 4.1G ,条目数: 3300+w ,更新周期: 1 分钟
       搜索词:手机之家论坛板块名随机
       对比条件
          ...
性能对比测试结果 (2/6)
Time taken for tests                        停止更新 正常更新
分配索引大小1倍内存             ab -n 2000 -c   20    21.85 64...
性能对比测试结果 (3/6)
Requests per second             停止更新 正常更新
分配索引大小1倍内存 ab -n 2000 -c   20    91.52 31.17
分配索引大小1倍内存 ab -n 100...
性能对比测试结果 (4/6)
Time per request                         停止更新      正常更新
                                         218.531   ...
性能对比测试结果 (5/6)
Transfer rate                          停止更新 正常更新
分配索引大小1倍内存        ab -n 2000 -c   20    154.06  52.47
分配索引...
性能对比测试结果 (6/6)
耗时比例                          停止更新 正常更新
                              50%  59 50% 162
                     ...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
部署上线
   运行概况
       updater , rebuilder 部署在 Imobile-SV25-B50 上
        • IntelXeon 4 cpu @2.60GHz , 6G mem
        • Sla...
生产环境运行观察
   Slow search  比例: >1s 1.x%; >2s 0.2%
   机器负载 : 49(search): 1~3; 50(update): <1
   内存消耗: search: ­Xms4096M ­X...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
开发中的一些收获 (1/5)

    FileChannel.transferTo 拷贝文件失败:
    
        Fewer than the requested number of bytes are transferred...
开发中的一些收获 (2/5)
   Kill  的问题
       Never kill smart frog, don't kill ­9
       Java use Runtime.getRuntime().addShutdow...
开发中的一些收获 (3/5)

    更新太频繁导致的磁盘 IO 问题
    – 同一台机器目录之间同步:没有问题
    – 一拖二,一拖三

    暂时解决
    – 建索引的机器不提供搜索服务
    – rsync 限速
开发中的一些收获 (4/5)
   GC  引起的服务暂停
    
        多个索引共用 Search 进程
    
        每个索引维持了多个 searcher
    
        索引更新太过频繁: 30 ...
开发中的一些收获 (5/5)
   Java server  程序的 trouble shooting
       性能问题: jprofile
       内存问题: jmx  + jconsole
       线程问题: Th...
目录
   关于手机之家
   过去:手机之家搜索 V1.0
   现在:手机之家搜索 V1.5
       需求背景
       目标
       进度
       设计
       实现
       测试
  ...
持续改进

    配置文件改动检测,自动重新加载

    更智能的处理索引字段变更

    分词算法改进

    搜索关键字数据挖掘(搜索新词自动发现)

    搜索建议,搜索联想功能

    排序算法改进

    ...
Lucene 3
   Lucene 2.9
    • Searchable.search(Weight, Filter, Collector): collector 终于可用了
    • Added new MultiReaderHit...
定制功能

    在某些情况下作为数据库的替代数据源
    
        类似淘宝搜索,按多个字段筛选,过滤,排序
    
        当前解决方案:使用 sql 从数据库中选取数据
    
        问题:数据可...
参考资料

    Lucene
    
        http://lucene.apache.org/
    
        http://lucene.apache.org/java/2_4_1/api/index.html...
关于我们

    关于 imobile
    
        网站首页 http://www.imobile.com.cn/
    
        关于  http://www.imobile.com.cn/about.html...
更多讨论

    Java GC  的问题
   巨大的索引库与频繁更新如何共存
   全站整合搜索,后台技术实现与前台表现设计
   更多
基于Lucene的站内搜索 Beta
Upcoming SlideShare
Loading in...5
×

基于Lucene的站内搜索 Beta

1,145

Published on

beta 沙龙上 唐福林(tangfulin) 《基于Lucene的站内搜索实战》讲稿
http://blog.fulin.org

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,145
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
45
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

基于Lucene的站内搜索 Beta

  1. 1. 基于 lucene 的站内搜索实战 Beta 技术沙龙 http://club.blogbeta.com 官方 twitter : @betasalon tangfulin <tangfulin@gmail.com> www.imobile.com.cn 2009.07.26
  2. 2. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  3. 3. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  4. 4. 关于手机之家 手机之家是一个旨在提供全方位的手机相关服务的资讯类网站。在 7 年的 时间里,手机之家从无到有,已经发展成为极具人气、最受关注的手机产 品资讯网站。 目前已有的一些统计数据: ●a. 1100w+ 用户 ●b. 3000w+ 帖子 ●c. 1.1TB+ 附件 ●d. 780w+ Page View/ 每天 ●e. 5~10w 在线用户 /15 分钟
  5. 5. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  6. 6. 手机之家的搜索 V1.0(1/3)  产品大全搜索  新闻 CMS  搜索  论坛搜索(默认只搜索标题)  论坛帖子及回复搜索  手机铃声,主题,电子书,软件搜索  二手交易搜索  其它版块的搜索
  7. 7. 手机之家的搜索 V1.0(2/3)  基本实现了多个业务模块需要的搜索功能  不同的搜索字段  不同的排序方式  不同的更新频率  Java 多进程,多线程实现
  8. 8. 手机之家的搜索 V1.0(3/3)  运行概况  Dev by chaoqian (http://www.longker.org/)  最初基于 Lucene 2.2 ,当前 2.4.1  开发时间: 07 年 12 月- 08 年 4 月  08 年 12 月随新版系统上线  部署在 Imobile-SV39-A49 上: • X86_64 , 8 cpu @ 2.50GHz , 32G mem • CentOS release 5.2, JDK64 1.6,  搜索: 35+ 万查询 / 天,高峰期 > 20 次 /s  更新: 平均 15 条 / 分钟
  9. 9. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  10. 10. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  11. 11. 需求背景 (1/3)  重建索引  索引字段变更  分词算法变更  搜索结果异常(记录重复,记录丢失)  索引文件意外损坏  V1.0 :半手工重建,重建过程需人工参与,重建过程中 不能正常更新  V1.5 :自动重建,重建过程中正常更新原来的索引
  12. 12. 需求背景 (2/3)  缩短更新周期(及时更新)  Google 更新手机之家内容的周期为 30 分钟左右  V1.0 索引更新周期为 10 - 15 分钟左右  V1.5 预期更新周期为 3 分钟,实际为 1-5 分钟
  13. 13. 需求背景 (3/3)  搜索大索引( V1.5 )  3300+ 万条记录的一个库, xml 原始文件 14G  V1.0 索引文件为 13 G ,无法快速更新  V1.5 索引文件为 3.9G (还是无法快速更新?)  V1.5 完整重建一次: 140 分钟
  14. 14. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  15. 15. 目标  及时更新( 3 分钟)  快速重建( < 2 小时)  可配置(拥抱需求变化)  可监控(运维友好)  SLA :永远可写,永远可读,异常的时候唯一的表现是 更新延迟  高性能,能承受较大的流量,并发压力
  16. 16. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  17. 17. 进度  2009 年 4 月 1 号 search 2.0 init  4 月 12 号,修改版本号为 1.5  6 月 1 号, search 1.5 在线上试运行  6 月 22 号,正式替换原来的搜索进程
  18. 18. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  19. 19. 设计 (1/8)  分离索引与存储,二次读取  分离读与写  分离 update 和 rebuild  拆分大库和小库  new open 小库(小库滚动), reopen 大库  新索引预热  更多: http://blog.fulin.org/category/tech/lucene
  20. 20. 设计 (2/8) 分离索引与存储,二次读取  索引里只存储 id ,其他的字段只索引不存储。  优点:  保持索引的大小为一个可接受的范围  提高索引读取速度  提高索引 cache 效率  缺点:搜索时需要额外的请求来获取其它必须的字段 ( lucene + db 方案)  衍生项目: blackdb , memcache 协议 + bdbJE 存储
  21. 21. 设计 (3/8) 分离读与写  优点:  降低编程复杂度  保证搜索服务的可用性,和可扩展性(可以将索引文件 分发到多台机器上,同时对外提供服务)  提升索引更新速度  缺点: • 需要移动索引文件 • 需要额外的索引更新逻辑( reopen ) • 无法使用当前设计中的 lucene 的 real-time search
  22. 22. 设计 (4/8) 分离 update 和 rebuild  Rebuild 的同时, update 正常更新  Rebuild 需要将重建这段时间的更新计入新的索引中  Rebuild 完成后,通知 update 切换到新索引上来,并 继续更新  进程间通信,当前使用最原始的基于文件的方式
  23. 23. 设计 (5/8) 拆分大库和小库  保证及时更新的同时,减少索引频繁同步(由写索引同 步到读索引)带来的 io 压力  更新频率 • 小库(最近更新库) 1 分钟 • 大库(历史库) 1 天到 1 周,可配置  并行搜索,加速搜索速度  问题: group by
  24. 24. 设计 (6/8) 拆分大库和小库(续)  增加新记录:  增加到小库  更新记录:  从大库中删除(标记删除)  从小库中删除(物理删除)  增加到小库  删除记录  从大库中删除(标记删除)  从小库中删除(物理删除)  定期合并小库到大库,并清空小库
  25. 25. 设计 (7/8) 搜索端索引更新  小库每次同步到一个新的文件夹中  保留最近打开的 n (2) 份小库索引目录  检测到新的索引到达,关闭一个最旧的,打开新的,预 热后标识为可用  检测到新的小库到达, reopen 大库(为了逻辑上的简 单起见,大小库同步更新)
  26. 26. 设计 (8/8) 新索引预热  目的:消除新打开的索引上前几次搜索慢的问题  实现: • 过去:遍历一遍新打开的索引,将数据都读入内存 • 引起 gc ,导致搜索暂停 • 对 lucene 内置的 cache 无贡献 • 现在:搜几个热门的词,并遍历结果集 • 将来:使用原来的 cache 填充新的 cache  预热完成后,再投入使用
  27. 27. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  28. 28. 实现 (1/8) IndexRebuilder 搜索管理后台 发出开始重建索引命令 IndexReceiver cron 发送重建数据 Rebuild xml data 端口 1986 Update xml data IndexUpdater DAL 数据更新 配置文件 同步通知搜索 Searcher 搜索客户端调用 Searcher 的 API 端口 1985
  29. 29. 实现 (2/8)IndexReceiver IndexRebuilder 搜索管理后台 IndexReceiver 发出开始重建索引命令 cron 发送重建数据 Rebuild xml data 端口 1986 Update xml data IndexUpdater DAL 数据更新 配置文件 同步通知搜索 Searcher 搜索客户端调用 Searcher 的 API 端口 1985
  30. 30. 实现 (2/8)IndexReceiver  By Java , Daemon 程序  监听端口,使用 SCGI 通讯协议  使用 Monkey 为底层 NIO 处理框架  接收客户端 post 过来的数据,并写入对应的目录  Update 和 rebuild 共用  为了保证原子性,先写入 .0.***.xml ,写入完成后,再 rename  Receiver 只负责写入, updater 和 rebuilder 稍后负责删除(备份)  对外提供服务,所以尽可能简单,单独进程
  31. 31. 实现 (3/8)IndexUpdater IndexRebuilder 搜索管理后台 发出开始重建索引命令 cron 发送重建数据 Rebuild xml data 端口 1986 Update IndexUpdater xml data DAL 数据更新 配置文件 同步通知搜索 Searcher 搜索客户端调用 Searcher 的 API 端口 1985
  32. 32. 实现 (3/8)IndexUpdater  By Java , Daemon 程序  多个索引共用,每个索引起一个线程  可根据需要随时停止或启动单个索引更新的线程  AddShutdownHook 退出前 close 所有打开的 IndexWriter  功能: • 更新新数据到当前索引 • 合并大小库 • 拷贝当前索引的快照供搜索使用 • 切换 rebuild 出来的新索引
  33. 33. 实现 (4/8)IndexRebuilder IndexRebuilder 搜索管理后台 发出开始重建索引命令 cron 发送重建数据 Rebuild xml data 端口 1986 Update xml data DAL 数据更新 配置文件 同步通知搜索 Searcher 搜索客户端调用 Searcher 的 API 端口 1985
  34. 34. 实现 (4/8)IndexRebuilder  By Java , Daemon 程序  多个索引共用,每个索引一个线程  重建索引时序图: Receiver 接到通 知,停止抄送 updater 数据。 客户端发送开 客户端发送重 客户端发送结 重建过程结束 始重建标识 建索引的数据 束重建标识 Receiver 开始抄送 update 数据到 receiver rebuild-update Updater 接到 Updater 正常 通知,切换索 T0 T1 T2 T3 T4 T5 更新 引。完成后通 updater 知 receiver Rebuilder Rebuilder Rebuilder 处理完 t0 开始工作 处理完重 到 当前的更新数据, rebuilder 建数据 通知 updater ,然后 自己退出 开始重建 重建数据 重建完成 时间线 接收完毕
  35. 35. 实现 (5/8)IndexRebuilder  切换索引过程 • Updater 删除自己当前的索引和未更新完的 xml 文件 • Updater 将 rebuilder 的索引和 rebuild-update 的 xml 文件 “据为己有” • 通知 receiver 停止抄送 • 继续正常的数据更新过程  可以证明这个过程中,不会有数据丢失,也不会有数据重复 • 前提: updater 的 xml 文件和 rebuild-update 的 xml 文件是完全相 同的(包括文件名和数据) • t3-t4 : 数据来自 rebuild-update • t4-t5 : rebuild-update 中的数据可以被直接忽略
  36. 36. 实现 (6/8)Transfer 搜索管理后台 发出开始重建索引命令 cron 发送重建数据 Rebuild xml data 端口 1986 Update xml data DAL 数据更新 配置文件 同步通知搜索 Searcher Transfer 搜索客户端调用 Searcher 的 API 端口 1985
  37. 37. 实现 (6/8)Transfer  Bash 脚本,每个 indexId 一个进程,由 ControlCenter 或 monitor 启 动和停止  监控索引快照目录  快照目录下存在子目录,并且子目录中存在 copy.done.sign ( IndexUpdater 拷贝快照完成后 touch 的标识),则 rsync 子目录到 search  Rsync 的时候:先 rsync 大库快照,再 rsync 小库快照,都成功后再 rsync 一个 trans.done.sign  以 0 字节的 sign 文件作为标识,模拟两阶段提交,保证文件拷贝, 传输的原子性
  38. 38. 实现 (7/8)Searcher 搜索管理后台 发出开始重建索引命令 cron 发送重建数据 Rebuild xml data 端口 1986 Update xml data DAL 数据更新 配置文件 同步通知搜索 Searcher 搜索客户端调用 Searcher 的 API 端口 1985
  39. 39. 实现 (7/8)Searcher  By Java , Daemon 程序  使用 Monkey 为底层 NIO 处理框架  使用 SCGI 通讯协议  启动后第一件事: warmUpAllIndex  当有新索引到达的时候,在后台打开,预热后,再投入使用  关闭旧的 IndexSearcher 实例的前提:当前没有线程还在使用它 • 方法:计数 ( get +1 , return -1 ,为 0 表示没有被使用)  Stat 统计
  40. 40. 实现 (8/8)Utils  Cleaner • Bash 脚本,每个 indexId 一个进程 • 用来删除 Searcher 已经关闭或跳过的索引  Monitor • 监控系统的各个进程是否存在,如不存在,则启动一个新的进程  ControlCenter • Usage: ./controlCenter.sh {start|stop|restart} {all|receiver|updater| rebuilder|searcher|trans|cleaner} • OR: ./controlCenter.sh {start|stop|restart} {monitor| logSlowSearch} • OR: ./controlCenter.sh {mkdirs}
  41. 41. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  42. 42. 性能简单测试结果  Apache bench  ­n 1000 ­c 10   ( 99%    545ms     100%  32838ms )  ­n 2000 ­c 20   ( 90%   1171ms    99%   4106ms )  库大小: 4.1G 条目数: 3300+w 更新周期: 1 分钟  总请求 3000 ,慢查询 ( 耗时大于 1 秒 ) 比例 4%  搜索词:手机之家论坛首页的板块名,随机  最长: 37s  > 10s : 22  (索引切换, gc )  2s­10s : 38  1s­2s : 62
  43. 43. 性能对比测试结果 (1/6)  Apache bench  库大小: 4.1G ,条目数: 3300+w ,更新周期: 1 分钟  搜索词:手机之家论坛板块名随机  对比条件  停止更新与正常更新  分配索引 1 倍大小的内存与 2 倍大小的内存  并发 10 个与 20 个  Document Length:     1529 bytes  Total transferred:       3447737 bytes (1722053 bytes)  HTML transferred:    3085737 bytes (1541053 bytes)
  44. 44. 性能对比测试结果 (2/6) Time taken for tests 停止更新 正常更新 分配索引大小1倍内存 ab -n 2000 -c 20 21.85 64.17 分配索引大小1倍内存 ab -n 1000 -c 10 13.1 11.93 分配索引大小2倍内存 ab -n 2000 -c 20 22.8 22.89 分配索引大小2倍内存 ab -n 1000 -c 10 10.37 10.74 备注:单位为秒
  45. 45. 性能对比测试结果 (3/6) Requests per second 停止更新 正常更新 分配索引大小1倍内存 ab -n 2000 -c 20 91.52 31.17 分配索引大小1倍内存 ab -n 1000 -c 10 76.33 83.83 分配索引大小2倍内存 ab -n 2000 -c 20 87.71 87.39 分配索引大小2倍内存 ab -n 1000 -c 10 96.45 93.13
  46. 46. 性能对比测试结果 (4/6) Time per request 停止更新 正常更新 218.531 641.674 分配索引大小1倍内存 ab -n 2000 -c 20 10.927 32.084 131.015 119.288 分配索引大小1倍内存 ab -n 1000 -c 10 13.102 11.929 228.012 228.870 分配索引大小2倍内存 ab -n 2000 -c 20 11.401 11.444 103.676 107.375 分配索引大小2倍内存 ab -n 1000 -c 10 10.368 10.738 备注: [ms] (mean) (mean, across all concurrent requests)
  47. 47. 性能对比测试结果 (5/6) Transfer rate 停止更新 正常更新 分配索引大小1倍内存 ab -n 2000 -c 20 154.06 52.47 分配索引大小1倍内存 ab -n 1000 -c 10 128.46 140.98 分配索引大小2倍内存 ab -n 2000 -c 20 147.63 146.82 分配索引大小2倍内存 ab -n 1000 -c 10 162.07 156.39 备注: (Kbytes/sec)
  48. 48. 性能对比测试结果 (6/6) 耗时比例 停止更新 正常更新 50% 59 50% 162 95% 905 90% 1403 分配索引大小1倍内存 ab -n 2000 -c 20 100% 1525 98% 5738 50% 34 50% 24 99% 978 98% 750 分配索引大小1倍内存 ab -n 1000 -c 10 100% 1420 100% 3600 50% 61 50% 41 95% 906 95% 988 分配索引大小2倍内存 ab -n 2000 -c 20 99% 1519 99% 1678 50% 28 50% 27 99% 744 99% 698 分配索引大小2倍内存 ab -n 1000 -c 10 100% 905 100% 764 备注:百分比 毫秒
  49. 49. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  50. 50. 部署上线  运行概况  updater , rebuilder 部署在 Imobile-SV25-B50 上 • IntelXeon 4 cpu @2.60GHz , 6G mem • Slackware 12.1, JDK32 1.6  Search 部署在 Imobile-SV39-A49 上: • X86_64 , 8 cpu @ 2.50GHz , 32G mem • CentOS release 5.2, JDK64 1.6  搜索: 35+ 万查询 / 天,高峰期 > 20 次 /s  更新: 平均 15 条 / 分钟
  51. 51. 生产环境运行观察  Slow search  比例: >1s 1.x%; >2s 0.2%  机器负载 : 49(search): 1~3; 50(update): <1  内存消耗: search: ­Xms4096M ­Xmx4096M  Cpu 消耗 :多核之间平均比较分配  索引平均更新速度: ~1 分钟  索引延迟率(因各种原因导致延迟更新的比例)
  52. 52. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  53. 53. 开发中的一些收获 (1/5)  FileChannel.transferTo 拷贝文件失败:  Fewer than the requested number of bytes are transferred if the target channel is non-blocking and it has fewer than count bytes free in its output buffer.  解决: check copied size ,断点续传  根据 lucene 索引文件更新的特性 ( 每次更新一个新版本的时 候,都会新建一个全新的文件 ) ,使用 cp -l 链接替代真实的 大文件拷贝动作
  54. 54. 开发中的一些收获 (2/5)  Kill  的问题  Never kill smart frog, don't kill ­9  Java use Runtime.getRuntime().addShutdownHook  to do the cleaning  things  Lucene IndexWriter need close!  server  程序,都应该考虑信号捕捉和处理的问题( java  程序容易忽 略这个问题)
  55. 55. 开发中的一些收获 (3/5)  更新太频繁导致的磁盘 IO 问题 – 同一台机器目录之间同步:没有问题 – 一拖二,一拖三  暂时解决 – 建索引的机器不提供搜索服务 – rsync 限速
  56. 56. 开发中的一些收获 (4/5)  GC  引起的服务暂停  多个索引共用 Search 进程  每个索引维持了多个 searcher  索引更新太过频繁: 30 秒  暂时解决  纵向拆分:将两个最大的库拆分到单独的进程  减少 searcher 个数到 2  个  谨慎的选择 gc 的类型,并调整 gc 的参数  G1 改进不明显,不稳定
  57. 57. 开发中的一些收获 (5/5)  Java server  程序的 trouble shooting  性能问题: jprofile  内存问题: jmx  + jconsole  线程问题: Thread.currentThread().setName("diffDetect­" +  indexId);   详细的 log : log4j  常用的脚本: logslowsearch.sh  开发调试阶段:方便的重新编译并重启脚本  线上服务阶段:完善的监控及报警机制
  58. 58. 目录  关于手机之家  过去:手机之家搜索 V1.0  现在:手机之家搜索 V1.5  需求背景  目标  进度  设计  实现  测试  上线,运维  经验分享  将来:手机之家搜索 V2.0
  59. 59. 持续改进  配置文件改动检测,自动重新加载  更智能的处理索引字段变更  分词算法改进  搜索关键字数据挖掘(搜索新词自动发现)  搜索建议,搜索联想功能  排序算法改进  全站整合搜索  准实时搜索
  60. 60. Lucene 3  Lucene 2.9 • Searchable.search(Weight, Filter, Collector): collector 终于可用了 • Added new MultiReaderHitCollector: 解决 group by • near real-time search via IndexWriter.getReader(): 单机方案  Lucene 3.0 • Del deprecated apis: 大版本升级要谨慎 • Port to Java5: 应该会有性能的提升  Lucene 3.1 • Near Realtime Search (using a built in RAMDirectory): 还是单机方案 • Complete overhaul of FieldCache API/Implementation: 等到花儿也谢了
  61. 61. 定制功能  在某些情况下作为数据库的替代数据源  类似淘宝搜索,按多个字段筛选,过滤,排序  当前解决方案:使用 sql 从数据库中选取数据  问题:数据可能因为业务逻辑的设计而分散在多个不同的 库,表中,联表查询问题,并发压力问题  难点:非典型的复杂的查询条件,如 group by
  62. 62. 参考资料  Lucene  http://lucene.apache.org/  http://lucene.apache.org/java/2_4_1/api/index.html  中文分词  http://code.google.com/p/paoding/  http://code.google.com/p/imdict-chinese-analyzer/  http://code.google.com/p/mmseg4j/  Monkey ( Java 底层异步网络 IO 框架)  DAL
  63. 63. 关于我们  关于 imobile  网站首页 http://www.imobile.com.cn/  关于 http://www.imobile.com.cn/about.html  Longker ( V1.0 版本)  http://www.longker.org/  关于我( V1.5 版本)  http://www.fulin.org/  http://twitter.com/tangfl
  64. 64. 更多讨论  Java GC  的问题  巨大的索引库与频繁更新如何共存  全站整合搜索,后台技术实现与前台表现设计  更多
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×