Xapian 搜索引擎 潘俊勇 易度  everydo.com
我使用 ZODB <ul><li>Z – Object Database </li></ul><ul><li>和 Python 语言绑定的对象数据库 </li></ul><ul><li>来自 ( 落魄少爱的 )zope 社区 </li></ul...
ZODB 的索引问题 <ul><li>ZODB 没有内置的索引 </li></ul><ul><li>… </li></ul>
需要独立的搜索模块 <ul><li>不仅仅是全文索引 </li></ul><ul><li>需要数据库的各种复杂搜索 </li></ul><ul><ul><li>而且要高性能 </li></ul></ul><ul><ul><li>多条件 </li...
可选的产品 <ul><li>继续用 MySQL </li></ul><ul><li>lucene    solr </li></ul><ul><li>Xapian </li></ul><ul><li>SphinxSearch </li></ul>
Mysql <ul><li>fulltext 索引性能不佳、功能不强 </li></ul><ul><li>多值属性 ( 比如 tag) 很难做索引 </li></ul><ul><li>每次查询的时候,只能利用一个索引 </li></ul><ul...
lucene /Solar <ul><li>Java 开发的老牌搜索引擎和服务 </li></ul><ul><li>我 </li></ul><ul><ul><li>不喜欢 java ,所以不感冒 </li></ul></ul><ul><ul><...
Xapian <ul><li>使用 C++ 开发 </li></ul><ul><li>del.icio.us (1 亿书签 ) </li></ul><ul><li>Gmane (9 千万条消息 ) </li></ul><ul><li>Douba...
Xapian performance <ul><li>非常好 </li></ul><ul><li>5 亿网页, 1.5T 数据库文件 </li></ul><ul><ul><li>小于 1S </li></ul></ul><ul><li>Gman...
sphinx <ul><li>最大: boardreader.com   </li></ul><ul><li>论坛搜索引擎, 20 亿份文档 (50 亿 ?) , 2TB(6TB?) </li></ul><ul><li>最忙 :  craigs...
简单比较 <ul><li>Xapian </li></ul><ul><li>25 年历史 </li></ul><ul><li>C++ </li></ul><ul><li>嵌入式 </li></ul><ul><li>写慢但读很快 </li></u...
我们选择 xapian <ul><li>用 xapian 的时候, Sphinx 还很弱 </li></ul><ul><li>Sphinx 对我们还是不适合 </li></ul><ul><ul><li>索引建立靠配置文件,不方便 </li></...
搜索服务 索引 数据库 索引  Index 搜索 Search 关系数据库 文件 NoSQL 数据库 Web 应用 各种数据源 异步、实时
Xapian 特性 <ul><li>Ranked probabilistic search  重要词汇 </li></ul><ul><li>Relevance feedback  相关的文档 </li></ul><ul><li>Phrase a...
Xapian 术语 <ul><li>Document  , document id :  一个整数 </li></ul><ul><ul><li>没有字段! </li></ul></ul><ul><li>terms   带位置信息的词或者短语,文...
首先在 Terms 里面找 documents 限定范围 完了,查相应的 value ,进行排序 如果数据量大, 这个过程可能比较慢。 如果需要,可把 data 再取出 所以技巧是,尽量减少第一步的 搜索结果量 另外, Sphinx 也是这个原...
Database 存储信息 <ul><li>必须 </li></ul><ul><ul><li>Posting list  table 每个 term  包含的 document </li></ul></ul><ul><ul><li>Record...
Xapian-backend 存储格式 <ul><li>chert : 1.2  数据库更小,但搜索更快 </li></ul><ul><li>flint  : 1.0 </li></ul><ul><li>Brass  :更好的支持 replic...
Xapian 的 python 接口 <ul><li>Xapian: swig 自动生成的接口 底层,功能强,但使用不方便 </li></ul><ul><li>Xappy :高层的封装 </li></ul><ul><ul><li>对多字段场景,...
建立索引 <ul><li>Import xapian </li></ul><ul><li>database = xapian.WritableDatabase('test/', xapian.DB_CREATE_OR_OPEN)  </li><...
写入速度慢? <ul><li>Commit  保证修改的原子性 Atomic </li></ul><ul><ul><li>大量数据写入逐一 commit 会很慢 </li></ul></ul><ul><li>解决方法 </li></ul><ul...
并行修改? <ul><li>不可以并行修改! </li></ul><ul><ul><li>单写多读 </li></ul></ul><ul><ul><li>这个和 sqlite 一样,嵌入式就是这个问题 </li></ul></ul><ul><l...
搜索 <ul><li>import xapian </li></ul><ul><li>database = xapian.Database('test/')  </li></ul><ul><li>enquire = xapian.Enquire...
组合搜索 <ul><li>xapian.Query(op, query1, query2) </li></ul><ul><ul><li>OP_AND  </li></ul></ul><ul><ul><li>OP_OR </li></ul></u...
使用 QueryParser <ul><li>类 Google 搜索 </li></ul><ul><ul><li>paas site:everydo.com –Service </li></ul></ul><ul><ul><li>更简单! </...
排序 <ul><li>相关性: enquire.set_sort_by_relevance()  </li></ul><ul><ul><li>默认是按 Rank 算法计算 BM25 </li></ul></ul><ul><ul><li>可使用 ...
多索引字段? <ul><li>内部只有一个索引! </li></ul><ul><ul><li>使用前缀解决 </li></ul></ul><ul><ul><li>Xappy 采用固定 2 个字母做字段前缀 </li></ul></ul>
搜索 <ul><li>读写不冲突 </li></ul><ul><ul><li>支持有限版本的 MVCC </li></ul></ul><ul><ul><li>如果写过于频繁,就出现读失效 ( 需要 reopen) </li></ul></ul>...
加大缓存提速? <ul><li>没有特殊的缓存控制 </li></ul><ul><li>全靠操作系统对硬盘读写的缓存 </li></ul>
分库查询 <ul><li>索引数据量太大,如何可扩展? </li></ul><ul><ul><li>更新慢 </li></ul></ul><ul><ul><li>搜索慢 </li></ul></ul><ul><ul><li>伸缩性小 </li>...
分布式搜索? <ul><li>索引数据库位于远端的服务器 </li></ul><ul><li>直接打开远端的数据库 </li></ul><ul><li>2 种方法 </li></ul><ul><ul><li>Prog </li></ul></u...
备份? <ul><li>很原始 </li></ul><ul><li>停止写数据库,拷贝数据库 </li></ul><ul><li>要么用支持快照的文件系统 (LVM) </li></ul><ul><li>无法增量备份 </li></ul>
“ 压缩”数据库 <ul><li>Xapian 会有很多预留空间,便于快速修改 </li></ul><ul><li>可使用 xapian-compact  进行压缩 </li></ul><ul><ul><li>数据库变小 </li></ul><...
Replication <ul><li>直接支持! </li></ul>
Xapian 优点 <ul><li>搜索速度快,支持大数据量 </li></ul><ul><li>强大的全文搜索 </li></ul><ul><li>内存占用少 </li></ul><ul><li>嵌入式,简单 </li></ul><ul><l...
Xapian 问题 <ul><li>错误的多写会导致数据库崩溃 ( 未来会修复 ) </li></ul><ul><li>多字段搜索,接口有点怪 </li></ul><ul><li>不能统计 : Sum/Group </li></ul><ul><...
结论 <ul><li>我们都喜欢简单的东西 </li></ul><ul><li>Xapian 整体设计还是很精巧的 </li></ul><ul><li>多方面因素做到了平衡 </li></ul>
Upcoming SlideShare
Loading in …5
×

Xapian介绍

5,368 views
5,100 views

Published on

为什么

Published in: Technology
1 Comment
11 Likes
Statistics
Notes
No Downloads
Views
Total views
5,368
On SlideShare
0
From Embeds
0
Number of Embeds
53
Actions
Shares
0
Downloads
89
Comments
1
Likes
11
Embeds 0
No embeds

No notes for slide

Xapian介绍

  1. 1. Xapian 搜索引擎 潘俊勇 易度 everydo.com
  2. 2. 我使用 ZODB <ul><li>Z – Object Database </li></ul><ul><li>和 Python 语言绑定的对象数据库 </li></ul><ul><li>来自 ( 落魄少爱的 )zope 社区 </li></ul><ul><li>开发非常快速方便! </li></ul><ul><li>我们的易度云办公基于这个 </li></ul>
  3. 3. ZODB 的索引问题 <ul><li>ZODB 没有内置的索引 </li></ul><ul><li>… </li></ul>
  4. 4. 需要独立的搜索模块 <ul><li>不仅仅是全文索引 </li></ul><ul><li>需要数据库的各种复杂搜索 </li></ul><ul><ul><li>而且要高性能 </li></ul></ul><ul><ul><li>多条件 </li></ul></ul><ul><ul><li>排序 </li></ul></ul><ul><ul><li>COUNT 统计 </li></ul></ul><ul><li>支持多值字段查询 </li></ul><ul><ul><li>比如 tag </li></ul></ul>
  5. 5. 可选的产品 <ul><li>继续用 MySQL </li></ul><ul><li>lucene  solr </li></ul><ul><li>Xapian </li></ul><ul><li>SphinxSearch </li></ul>
  6. 6. Mysql <ul><li>fulltext 索引性能不佳、功能不强 </li></ul><ul><li>多值属性 ( 比如 tag) 很难做索引 </li></ul><ul><li>每次查询的时候,只能利用一个索引 </li></ul><ul><ul><li>组合查询,需要建立很多多列索引 </li></ul></ul><ul><ul><li>太多索引导致索引膨胀,性能降低 </li></ul></ul>
  7. 7. lucene /Solar <ul><li>Java 开发的老牌搜索引擎和服务 </li></ul><ul><li>我 </li></ul><ul><ul><li>不喜欢 java ,所以不感冒 </li></ul></ul><ul><ul><li>不很了解 </li></ul></ul><ul><li>好些从 Lucene 社区跑到 xapian </li></ul><ul><ul><li>说 Lucene 的可扩展性不强 </li></ul></ul><ul><ul><li>数据量大就撑不住 </li></ul></ul><ul><li>性能一般 ( 传 Sphnix 比他快 2-4 倍 ) </li></ul>
  8. 8. Xapian <ul><li>使用 C++ 开发 </li></ul><ul><li>del.icio.us (1 亿书签 ) </li></ul><ul><li>Gmane (9 千万条消息 ) </li></ul><ul><li>Douban </li></ul>类搜索引擎的简单服务
  9. 9. Xapian performance <ul><li>非常好 </li></ul><ul><li>5 亿网页, 1.5T 数据库文件 </li></ul><ul><ul><li>小于 1S </li></ul></ul><ul><li>Gmane : 9 千万邮件,单服务器 </li></ul>
  10. 10. sphinx <ul><li>最大: boardreader.com </li></ul><ul><li>论坛搜索引擎, 20 亿份文档 (50 亿 ?) , 2TB(6TB?) </li></ul><ul><li>最忙 : craigslist.org , 免费的分类广告站点 ( 美国的 top10), 每天 5 千万请求 </li></ul>各种复杂的应用
  11. 11. 简单比较 <ul><li>Xapian </li></ul><ul><li>25 年历史 </li></ul><ul><li>C++ </li></ul><ul><li>嵌入式 </li></ul><ul><li>写慢但读很快 </li></ul><ul><li>无统计功能 </li></ul><ul><li>利用磁盘存储结构 </li></ul><ul><li>适合构建搜索引擎 </li></ul><ul><li>Sphinx </li></ul><ul><li>起步 2003 年 </li></ul><ul><li>C++ </li></ul><ul><li>服务器 </li></ul><ul><li>和 mysql 整合好 </li></ul><ul><li>提供 SQL API </li></ul><ul><li>索引推荐在内存中 </li></ul><ul><li>适合更复杂应用 </li></ul>
  12. 12. 我们选择 xapian <ul><li>用 xapian 的时候, Sphinx 还很弱 </li></ul><ul><li>Sphinx 对我们还是不适合 </li></ul><ul><ul><li>索引建立靠配置文件,不方便 </li></ul></ul><ul><ul><li>Sphinx 的 attribute 全部在内存里面 </li></ul></ul><ul><li>Xapian 更简单可控 </li></ul><ul><ul><li>嵌入式,而启动服务器 </li></ul></ul><ul><ul><li>代码量也不大 </li></ul></ul><ul><ul><li>总体结构也比较简单 </li></ul></ul>
  13. 13. 搜索服务 索引 数据库 索引 Index 搜索 Search 关系数据库 文件 NoSQL 数据库 Web 应用 各种数据源 异步、实时
  14. 14. Xapian 特性 <ul><li>Ranked probabilistic search 重要词汇 </li></ul><ul><li>Relevance feedback 相关的文档 </li></ul><ul><li>Phrase and proximity searching </li></ul><ul><li>Full range of structured boolean search operators (&quot;stock NOT market&quot;, etc) </li></ul><ul><li>stemming of search terms 近似词 </li></ul><ul><li>Wildcard 任意匹配 (xap*) </li></ul><ul><li>Synonyms 同义词 </li></ul><ul><li>Facet search 分面搜索 </li></ul>
  15. 15. Xapian 术语 <ul><li>Document , document id : 一个整数 </li></ul><ul><ul><li>没有字段! </li></ul></ul><ul><li>terms 带位置信息的词或者短语,文本搜索 </li></ul><ul><li>values 短的 字符串 ,用于 二进制 范围搜索和排序 </li></ul><ul><li>document data 用于返回显示的任何数据,不能搜索 </li></ul>
  16. 16. 首先在 Terms 里面找 documents 限定范围 完了,查相应的 value ,进行排序 如果数据量大, 这个过程可能比较慢。 如果需要,可把 data 再取出 所以技巧是,尽量减少第一步的 搜索结果量 另外, Sphinx 也是这个原理。只是 他为了提高性能,把 value 全部放入 内存了。
  17. 17. Database 存储信息 <ul><li>必须 </li></ul><ul><ul><li>Posting list table 每个 term 包含的 document </li></ul></ul><ul><ul><li>Record table document 关联的 data </li></ul></ul><ul><ul><li>Term list table 每个 document 包括的所有 term </li></ul></ul><ul><li>可选 </li></ul><ul><ul><li>position list table 每个 term 出现的位置 </li></ul></ul><ul><ul><li>value table  主要用于保存、排序等 </li></ul></ul><ul><ul><li>Spelling table 拼写纠正 </li></ul></ul><ul><ul><li>synonym table 同义字典 </li></ul></ul>
  18. 18. Xapian-backend 存储格式 <ul><li>chert : 1.2 数据库更小,但搜索更快 </li></ul><ul><li>flint : 1.0 </li></ul><ul><li>Brass :更好的支持 replication ( 开发中 ) </li></ul><ul><li>Remote :远端的数据库 </li></ul>
  19. 19. Xapian 的 python 接口 <ul><li>Xapian: swig 自动生成的接口 底层,功能强,但使用不方便 </li></ul><ul><li>Xappy :高层的封装 </li></ul><ul><ul><li>对多字段场景,使用更简单 </li></ul></ul><ul><ul><li>太自动化,反而乱来 </li></ul></ul><ul><ul><li>不是很成熟,跟不上 xapian 的变化 </li></ul></ul><ul><ul><li>理解原理即可,不推荐使用 </li></ul></ul>
  20. 20. 建立索引 <ul><li>Import xapian </li></ul><ul><li>database = xapian.WritableDatabase('test/', xapian.DB_CREATE_OR_OPEN) </li></ul><ul><li>doc = xapian.Document() </li></ul><ul><li>doc.set_data(“ 我们爱祖国” ) </li></ul><ul><li>doc.add_posting(“ 我们” , 1) </li></ul><ul><li>doc.add_posting(“ 爱” , 3) </li></ul><ul><li>doc.add_posting(“ 祖国” , 4) </li></ul><ul><li>doc.add_value(0, “20111130”) </li></ul><ul><li>doc.add_value(1, “ 潘俊勇” ) </li></ul><ul><li># 添加并写入数据库 </li></ul><ul><li>database.add_document(doc) </li></ul><ul><li>database.commit() </li></ul>
  21. 21. 写入速度慢? <ul><li>Commit 保证修改的原子性 Atomic </li></ul><ul><ul><li>大量数据写入逐一 commit 会很慢 </li></ul></ul><ul><li>解决方法 </li></ul><ul><ul><li>批量添加,成批 commit </li></ul></ul><ul><ul><ul><li>Commit 之前只是内存操作 </li></ul></ul></ul><ul><ul><li>hack 代码,不做完整性检查 </li></ul></ul><ul><ul><li>多机分区索引,事后合并 </li></ul></ul><ul><ul><ul><li>Xapian-compact --multipass </li></ul></ul></ul>
  22. 22. 并行修改? <ul><li>不可以并行修改! </li></ul><ul><ul><li>单写多读 </li></ul></ul><ul><ul><li>这个和 sqlite 一样,嵌入式就是这个问题 </li></ul></ul><ul><li>会导致数据库崩溃! </li></ul><ul><ul><li>xapian 的 lock 机制有 bug </li></ul></ul><ul><ul><li>检查是否崩溃 </li></ul></ul><ul><ul><ul><li>xapian-check foo/termlist.DB </li></ul></ul></ul>
  23. 23. 搜索 <ul><li>import xapian </li></ul><ul><li>database = xapian.Database('test/') </li></ul><ul><li>enquire = xapian.Enquire(database) </li></ul><ul><li>terms = [“ 我们” , “ 祖国” ] </li></ul><ul><li>query = xapian.Query(xapian.Query.OP_OR, terms) </li></ul><ul><li>enquire.set_query(query) </li></ul><ul><li>matches = enquire.get_mset(0, 10) </li></ul><ul><li>count = matches.get_matches_estimated() </li></ul><ul><li>for match in matches: </li></ul><ul><li>print match[xapian.MSET_DID] </li></ul><ul><li>print match[xapian.MSET_PERCENT] </li></ul><ul><li>print match[xapian.MSET_DOCUMENT].get_data() </li></ul>
  24. 24. 组合搜索 <ul><li>xapian.Query(op, query1, query2) </li></ul><ul><ul><li>OP_AND </li></ul></ul><ul><ul><li>OP_OR </li></ul></ul><ul><ul><li>OP_AND_NOT </li></ul></ul><ul><ul><li>OP_FILTER </li></ul></ul><ul><ul><li>OP_AND_MAYBE </li></ul></ul><ul><ul><li>OP_XOR </li></ul></ul><ul><ul><li>OP_NEAR </li></ul></ul><ul><ul><li>OP_PHRASE </li></ul></ul><ul><ul><li>OP_ELITE_SET </li></ul></ul>
  25. 25. 使用 QueryParser <ul><li>类 Google 搜索 </li></ul><ul><ul><li>paas site:everydo.com –Service </li></ul></ul><ul><ul><li>更简单! </li></ul></ul><ul><li>qp = xapian.QueryParser() </li></ul><ul><li>qp.set_database(database) </li></ul><ul><li>query = qp.parse_query(query_string) </li></ul>
  26. 26. 排序 <ul><li>相关性: enquire.set_sort_by_relevance() </li></ul><ul><ul><li>默认是按 Rank 算法计算 BM25 </li></ul></ul><ul><ul><li>可使用 BoolWeight ,采用进索引顺序,快速 </li></ul></ul><ul><ul><ul><li>配合 enquire.set_docid_order </li></ul></ul></ul><ul><li>按照其他属性排序 : </li></ul><ul><ul><li>enquire.set_sort_by_value() value 必须统一为可排序的字符串 </li></ul></ul><ul><ul><li>enquire.set_sort_by_value_then_relevance() </li></ul></ul><ul><ul><li>enquire.set_sort_by_relevance_then_value() </li></ul></ul><ul><ul><li>自定义算法 </li></ul></ul><ul><ul><ul><li>地理位置排序 </li></ul></ul></ul><ul><ul><ul><li>图片相似性排序 </li></ul></ul></ul>
  27. 27. 多索引字段? <ul><li>内部只有一个索引! </li></ul><ul><ul><li>使用前缀解决 </li></ul></ul><ul><ul><li>Xappy 采用固定 2 个字母做字段前缀 </li></ul></ul>
  28. 28. 搜索 <ul><li>读写不冲突 </li></ul><ul><ul><li>支持有限版本的 MVCC </li></ul></ul><ul><ul><li>如果写过于频繁,就出现读失效 ( 需要 reopen) </li></ul></ul><ul><li>可以对数据库 rebuild 提升读性能 </li></ul>
  29. 29. 加大缓存提速? <ul><li>没有特殊的缓存控制 </li></ul><ul><li>全靠操作系统对硬盘读写的缓存 </li></ul>
  30. 30. 分库查询 <ul><li>索引数据量太大,如何可扩展? </li></ul><ul><ul><li>更新慢 </li></ul></ul><ul><ul><li>搜索慢 </li></ul></ul><ul><ul><li>伸缩性小 </li></ul></ul><ul><li>可分拆成多个索引 </li></ul><ul><ul><li>按照不同栏目 </li></ul></ul><ul><ul><li>不同的类型的数据 </li></ul></ul><ul><li>轻松支持多库搜索 </li></ul><ul><ul><li>Add_database </li></ul></ul>
  31. 31. 分布式搜索? <ul><li>索引数据库位于远端的服务器 </li></ul><ul><li>直接打开远端的数据库 </li></ul><ul><li>2 种方法 </li></ul><ul><ul><li>Prog </li></ul></ul><ul><ul><ul><li>Xapian.database(Xapian::Remote::open(&quot;ssh&quot;, &quot;search.example.com xapian-progsrv /var/lib/xapian/data/db1&quot;)); </li></ul></ul></ul><ul><ul><li>服务器 </li></ul></ul><ul><ul><ul><li>xapian-tcpsrv: --port 33333 </li></ul></ul></ul><ul><ul><ul><li>Xapian::Database database(Xapian::Remote::open(&quot;searchserver&quot;, 33333)); </li></ul></ul></ul>
  32. 32. 备份? <ul><li>很原始 </li></ul><ul><li>停止写数据库,拷贝数据库 </li></ul><ul><li>要么用支持快照的文件系统 (LVM) </li></ul><ul><li>无法增量备份 </li></ul>
  33. 33. “ 压缩”数据库 <ul><li>Xapian 会有很多预留空间,便于快速修改 </li></ul><ul><li>可使用 xapian-compact 进行压缩 </li></ul><ul><ul><li>数据库变小 </li></ul></ul><ul><ul><li>搜索会更快 </li></ul></ul><ul><ul><li>但修改会变慢 </li></ul></ul><ul><li>仅仅在很少修改的时候做这个 </li></ul>
  34. 34. Replication <ul><li>直接支持! </li></ul>
  35. 35. Xapian 优点 <ul><li>搜索速度快,支持大数据量 </li></ul><ul><li>强大的全文搜索 </li></ul><ul><li>内存占用少 </li></ul><ul><li>嵌入式,简单 </li></ul><ul><li>支持“实时”索引 </li></ul>
  36. 36. Xapian 问题 <ul><li>错误的多写会导致数据库崩溃 ( 未来会修复 ) </li></ul><ul><li>多字段搜索,接口有点怪 </li></ul><ul><li>不能统计 : Sum/Group </li></ul><ul><li>文档资料不够 </li></ul><ul><li>开发维护人员少 </li></ul><ul><li>Value 必须为字符串,更占用存储空间 </li></ul>
  37. 37. 结论 <ul><li>我们都喜欢简单的东西 </li></ul><ul><li>Xapian 整体设计还是很精巧的 </li></ul><ul><li>多方面因素做到了平衡 </li></ul>

×