Xapian介绍

37
Xapian 搜搜搜搜 搜搜搜 搜搜 everydo.com

description

为什么

Transcript of Xapian介绍

Page 1: Xapian介绍

Xapian 搜索引擎

潘俊勇

易度 everydo.com

Page 2: Xapian介绍

我使用 ZODB

Z – Object Database 和 Python 语言绑定的对象数据库 来自 ( 落魄少爱的 )zope 社区 开发非常快速方便! 我们的易度云办公基于这个

Page 3: Xapian介绍

ZODB 的索引问题 ZODB 没有内置的索引 …

Page 4: Xapian介绍

需要独立的搜索模块 不仅仅是全文索引 需要数据库的各种复杂搜索

而且要高性能 多条件 排序 COUNT 统计

支持多值字段查询 比如 tag

Page 5: Xapian介绍

可选的产品 继续用 MySQL lucene solr Xapian SphinxSearch

Page 6: Xapian介绍

Mysql

fulltext 索引性能不佳、功能不强 多值属性 ( 比如 tag) 很难做索引 每次查询的时候,只能利用一个索引

组合查询,需要建立很多多列索引 太多索引导致索引膨胀,性能降低

Page 7: Xapian介绍

lucene /Solar

Java 开发的老牌搜索引擎和服务 我

不喜欢 java ,所以不感冒 不很了解

好些从 Lucene 社区跑到 xapian 说 Lucene 的可扩展性不强 数据量大就撑不住

性能一般 ( 传 Sphnix 比他快 2-4 倍 )

Page 8: Xapian介绍

Xapian

使用 C++ 开发 del.icio.us (1 亿书签 ) Gmane (9 千万条消息 ) Douban

类搜索引擎的简单服务

Page 9: Xapian介绍

Xapian performance

非常好 5 亿网页, 1.5T 数据库文件

小于 1S Gmane : 9 千万邮件,单服务器

Page 10: Xapian介绍

sphinx

• 最大: boardreader.com 论坛搜索引擎, 20 亿份文档 (50 亿 ?) , 2TB(6TB?)

• 最忙 : craigslist.org, 免费的分类广告站点 ( 美国的 top10), 每天 5 千万请求

各种复杂的应用

Page 11: Xapian介绍

简单比较 Xapian 25 年历史 C++ 嵌入式 写慢但读很快 无统计功能 利用磁盘存储结构

适合构建搜索引擎

Sphinx 起步 2003 年 C++ 服务器 和 mysql 整合好 提供 SQL API 索引推荐在内存中

适合更复杂应用

Page 12: Xapian介绍

我们选择 xapian

用 xapian 的时候, Sphinx 还很弱 Sphinx 对我们还是不适合

索引建立靠配置文件,不方便 Sphinx 的 attribute 全部在内存里面

Xapian 更简单可控 嵌入式,而启动服务器 代码量也不大 总体结构也比较简单

Page 13: Xapian介绍

搜索服务

索引数据库

索引 Index 搜索 Search

关系数据库

文件

NoSQL 数据库

Web应用

各种数据源

异步、实时

Page 14: Xapian介绍

Xapian 特性 Ranked probabilistic search

重要词汇 Relevance feedback

相关的文档 Phrase and proximity searching Full range of structured boolean search operators

("stock NOT market", etc) stemming of search terms 近似词 Wildcard 任意匹配 (xap*) Synonyms 同义词 Facet search 分面搜索

Page 15: Xapian介绍

Xapian 术语 Document , document id : 一个整数

没有字段!

terms 带位置信息的词或者短语,文本搜索

values 短的字符串,用于二进制范围搜索和排序

document data 用于返回显示的任何数据,不能搜索

Page 16: Xapian介绍

首先在 Terms 里面找 documents限定范围

完了,查相应的 value ,进行排序如果数据量大,这个过程可能比较慢。

如果需要,可把 data再取出

所以技巧是,尽量减少第一步的搜索结果量

另外, Sphinx 也是这个原理。只是他为了提高性能,把 value 全部放入内存了。

Page 17: Xapian介绍

Database 存储信息必须

Posting list table每个 term 包含的 document

Record tabledocument 关联的 data

Term list table每个 document包括的所有 term

可选 position list table 每个 term出现的位置 value table  主要用于保存、排序等 Spelling table 拼写纠正 synonym table 同义字典

Page 18: Xapian介绍

Xapian-backend 存储格式 chert : 1.2 数据库更小,但搜索更快

flint : 1.0

Brass :更好的支持 replication( 开发中 )

Remote :远端的数据库

Page 19: Xapian介绍

Xapian 的 python接口 Xapian: swig 自动生成的接口底层,功能强,但使用不方便

Xappy :高层的封装 对多字段场景,使用更简单 太自动化,反而乱来 不是很成熟,跟不上 xapian 的变化 理解原理即可,不推荐使用

Page 20: Xapian介绍

建立索引Import xapian

database = xapian.WritableDatabase('test/', xapian.DB_CREATE_OR_OPEN)

doc = xapian.Document() doc.set_data(“ 我们爱祖国” ) doc.add_posting(“ 我们” , 1) doc.add_posting(“ 爱” , 3) doc.add_posting(“祖国” , 4) doc.add_value(0, “20111130”)doc.add_value(1, “ 潘俊勇” )

# 添加并写入数据库database.add_document(doc) database.commit()

Page 21: Xapian介绍

写入速度慢? Commit 保证修改的原子性 Atomic

大量数据写入逐一 commit会很慢

解决方法 批量添加,成批 commit

Commit之前只是内存操作 hack 代码,不做完整性检查 多机分区索引,事后合并

Xapian-compact --multipass

Page 22: Xapian介绍

并行修改? 不可以并行修改!

单写多读 这个和 sqlite 一样,嵌入式就是这个问题

会导致数据库崩溃! xapian 的 lock机制有 bug 检查是否崩溃

xapian-check foo/termlist.DB

Page 23: Xapian介绍

搜索import xapian

database = xapian.Database('test/') enquire = xapian.Enquire(database)

terms = [“ 我们” , “祖国” ] query = xapian.Query(xapian.Query.OP_OR, terms) enquire.set_query(query)

matches = enquire.get_mset(0, 10) count = matches.get_matches_estimated() for match in matches: print match[xapian.MSET_DID] print match[xapian.MSET_PERCENT] print match[xapian.MSET_DOCUMENT].get_data()

Page 24: Xapian介绍

组合搜索 xapian.Query(op, query1, query2)

OP_AND OP_OR OP_AND_NOT OP_FILTER OP_AND_MAYBE OP_XOR OP_NEAR OP_PHRASE OP_ELITE_SET

Page 25: Xapian介绍

使用 QueryParser

类 Google 搜索 paas site:everydo.com –Service 更简单!

qp = xapian.QueryParser() qp.set_database(database) query = qp.parse_query(query_string)

Page 26: Xapian介绍

排序 相关性: enquire.set_sort_by_relevance()

默认是按 Rank算法计算 BM25 可使用 BoolWeight ,采用进索引顺序,快速

配合 enquire.set_docid_order

按照其他属性排序 : enquire.set_sort_by_value()

value必须统一为可排序的字符串 enquire.set_sort_by_value_then_relevance() enquire.set_sort_by_relevance_then_value() 自定义算法

地理位置排序图片相似性排序

Page 27: Xapian介绍

多索引字段? 内部只有一个索引!

使用前缀解决 Xappy采用固定 2 个字母做字段前缀

Page 28: Xapian介绍

搜索 读写不冲突

支持有限版本的 MVCC 如果写过于频繁,就出现读失效 ( 需要 reopen)

可以对数据库 rebuild 提升读性能

Page 29: Xapian介绍

加大缓存提速? 没有特殊的缓存控制 全靠操作系统对硬盘读写的缓存

Page 30: Xapian介绍

分库查询 索引数据量太大,如何可扩展?

更新慢 搜索慢 伸缩性小

可分拆成多个索引 按照不同栏目 不同的类型的数据

轻松支持多库搜索 Add_database

Page 31: Xapian介绍

分布式搜索? 索引数据库位于远端的服务器直接打开远端的数据库 2 种方法

ProgXapian.database(Xapian::Remote::open("ssh", "search.exampl

e.com xapian-progsrv /var/lib/xapian/data/db1"));

服务器xapian-tcpsrv: --port 33333Xapian::Database database(Xapian::Remote::open("searchserv

er", 33333));

Page 32: Xapian介绍

备份?很原始

停止写数据库,拷贝数据库 要么用支持快照的文件系统 (LVM) 无法增量备份

Page 33: Xapian介绍

“压缩”数据库 Xapian会有很多预留空间,便于快速修改 可使用 xapian-compact 进行压缩

数据库变小 搜索会更快 但修改会变慢

仅仅在很少修改的时候做这个

Page 34: Xapian介绍

Replication

直接支持!

Page 35: Xapian介绍

Xapian优点 搜索速度快,支持大数据量 强大的全文搜索 内存占用少 嵌入式,简单 支持“实时”索引

Page 36: Xapian介绍

Xapian 问题错误的多写会导致数据库崩溃 (未来会修复 ) 多字段搜索,接口有点怪 不能统计 : Sum/Group 文档资料不够 开发维护人员少 Value必须为字符串,更占用存储空间

Page 37: Xapian介绍

结论 我们都喜欢简单的东西 Xapian 整体设计还是很精巧的 多方面因素做到了平衡