一、 Sphinx简介

Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。意图为其他应用提供高速、低空间占用、高结果相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从标准输入读取特定格式的XML数据。

Sphinx的特性如下:

a) 高速的建立索引(在当代CPU上,峰值性能可达到10 MB/秒);

b) 高性能的搜索(在2 – 4GB 的文本数据上,平均每次检索响应时间小于0.1秒);

c) 可处理海量数据(目前已知可以处理超过100 GB的文本数据, 在单一CPU的系统上可处理100 M 文档);

d) 提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;

e) 支持分布式搜索;

f) 支持短语搜索

g) 提供文档摘要生成

h) 可作为MySQL的存储引擎提供搜索服务;

i) 支持布尔、短语、词语相似度等多种检索模式;

j) 文档支持多个全文检索字段(最大不超过32个);

k) 文档支持多个额外的属性信息(例如:分组信息,时间戳等);

l) 支持断词;

虽然mysql的MYISAM提供全文索引,但是性能却不敢让人恭维,另外数据库毕竟不是很善于做这样的事情,我们需要把这些活让给更适合的程序去做,减少数据库的压力。因此采用Sphinx来做mysql的全文索引工具是一个很好的选择。这个星期主要来学习这个这个工具的使用,下面将学习过程大致的记录一下,做个备忘,也希望能对学习这个工具的其他朋友有所启发。

横向对比ElasticSearch与Sphinx(转)

先从Elastic Search与Sphinx的横向对比开始。横向对比是反映优点和暴露问题的好方法。我是Sphinx阵营转向Elastic Search阵营的,两者都是成熟的开源搜索引擎,各有优劣,这篇文章也可以给纠结使用哪套方案的同学提供一些选择的依据。

• 导入MySQL数据生成索引

Elastic Search:RESTful接口,或 GitHub - scharron/elasticsearch-river-mysql

Sphinx:原生支持基于MySQL的表建索引

Elastic Search官方文档上,数据都是使用RESTful接口一条一条插入的,也就是增量更新。有个bulk接口,可以批量导入、大幅加快速度。在数据量非常大的时候,遍历全表重建一次索引会比较消耗时间。elasticsearch-rivel-mysql这个项目并不是很靠谱,开发者甚至曾经在git上标明deprecated。

我是推荐使用bulk方法的,毕竟Logstash就是用这个。

在导入MySQL数据生成索引时,从易用性、可靠性、速度上来看,Sphinx优于Elastic Search。Sphinx真的很快。

• 增量更新支持

Elastic Search优于Sphinx。Elastic Search把增量更新作为首选CURD方式;而Sphinx使用辅助表的方案不但不优雅,还会让你的其他系统变得复杂起来,在你频繁更改单条数据的时候很容易出错。

• 可视化与辅助工具

Elastic Search:Kibana,Beats,Logstash,Marvel,Head

Sphinx:Sphinx Tools

Kibana是Elastic Search提供的数据可视化界面,基本功能有:1)读取一个Index 2)对一个Index写query查询出具体数据 3)通过这些数据生成图表 4)拉几个图表生成一个报表。

Kibana非常强大,根据这些基础功能,我们已经可以自由定制完成各种复杂需求了。Kibana还可以加各种插件,其中最常用的是Marvel(性能、状态监控),非常好用。

Beats是一套收集日志的框架,官方称为Data Shipper。这个以后单独拿来说。

Logstash是一套日志处理框架。老实说我很长一段时间迷茫Logstash跟Beats各自定位...简单来说,Beats是专门用来收集数据的,Logstash是专门用来处理数据的。

反观Sphinx Tools,还停留在性能监控的阶段,而且还在内测,被Elastic Search的全家桶甩太远了。

• 搜索算法支持

ElasthcSearch的搜索底层功能基于Lucene,Sphinx也该有的都有。然而Elastic Search的Query DSL支持更复杂的查询逻辑,这一点是超越Sphinx的。

在自定义Ranker方面,Elastic Search的Function Score Query比Sphinx的expression-ranker强大许多。当年我为了让Sphinx支持一个定制的Ranker,不得不去改源码,后来发现这个功能在Elastic Search上可以轻松实现。

总的来说,Elastic Search稍微优于Sphinx。

• 横向扩展与高可用

Elastic Search是天生为了集群化而设计的。索引如果没有Replica就会显示黄灯,有才会亮绿灯。每个节点分为Client Node、Data Node、Master Node三种角色,在合理的配置之下,任意一台(甚至多台)机器炸了,整个集群都能正常运行。Elastic Search还支持动态加机器等等功能,暂不赘述。

Sphinx也有master searchd和slave searchd的概念,可以分布式,但想实现高可用就相当复杂了。

Elastic Search优于Sphinx。Sphinx的劣势不在于做不到,而在于不好用。

• 资源占用

Sphinx优于Elastic Search。

不得不说,java在这方面比不上C++。无论是CPU还是内存占用,Sphinx都比Elastic Search优秀。所以在一些高并发的简单需求,我依然会选择Sphinx。

• 搜索速度

搜索速度主要看怎么配置Cluster,越多搜起来就越快。

• NLP支持

这里只说中文NLP。

Elastic Search:IK、结巴

Sphinx:曾经有个叫coreseek的项目,可惜没有继续维护了。

其实双方都可以开发第三方插件,接入国内的LTP或者ICTCLAS都不难。

• 总结

Sphinx和Elastic Search都是很优秀的方案,都经历了实战的考验。当时为什么我从Sphinx倒戈去了Elastic Search,主要原因是:

• 我有定制Ranker的需求,Elastic Search的Functional Score Query刚好满足了我

• 业务越来越大,Elastic Search有更强的横向扩展能力和高可用性

• 可以用Kibana整出好看的报表啊!

现在回头一看,Elastic Search发力非常猛,版本迭代如火箭一般,社区也很活跃。我认为这个选择没有出错。

技术改变命运