- 浏览: 2188883 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
Sphinx介绍
Sphinx是由一个开源的全文检索引擎,功能类似Lucune,用C++编写,可为其他应用提供高速、低空间占用、高结果相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成,当前系统内置MySQL和PostgreSQL数据库数据源的支持,也支持从标准输入读取特定格式的XML数据,通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS的原生支持)
Sphinx特性
1:Sphinx支持高速建立索引(可达10MB/秒,而Lucene建立索引的速度是1.8MB/秒)
2:高性能的搜索(在2--4GB的文本数据上,平均每次检索响应时间小于0.1秒)
3:高扩展性(实测最高可对100GB的文本建立索引,单一索引可包含1亿条记录)
4:提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法
5:支持分布式搜索
6:支持短语搜索
7:可作为MySQL的存储引擎提供搜索服务
8:支持布尔、短语、词语相似度等多种检索模式
9:文档支持多个全文检索字段
系统组成
整个Sphinx系统由多个可执行程序和一套api组成,这里引用Coreseek(一个基于Sphinx的开源检索引擎,提供了良好的中文支持)的一个结构图做个示例
可执行程序
1:索引建立和维护程序(索引程序indexer)
2:查询服务程序(后台服务程序searchd)
3:辅助工具程序(search, spelldump等)
api
1:应用程序api(包括ruby,C/C++, Python, php, java的程序api)
2:Mysql的SphinxSE引擎接口
3:SphinxQL支持
工作流程
安装好Sphinx后,首先需要根据想要检索的场景来建立对应的配置文件,Sphinx是以sphinx.conf为配置文件,索引与搜索均以这个文件为依据进行,要进行全文检索,首先就要配置好sphinx.conf,告诉sphinx哪些字段需要进行索引,哪些字段需要在where,orderby,groupby中用到。
该文件的结构大致如下:
Java代码 收藏代码
<![CDATA[source 源名称1{
…
}
index 索引名称1{
source=源名称1
…
}
source 源名称2{
…
}
index 索引名称2{
source = 源名称2
…
}
indexer{
…
}
searchd{
…
}
]]>
从配置文件的组成中我们可以发现Sphinx可以定义多个索引与数据源,不同的索引与数据源可以应用到不同表或不同应用的全文检索方式。
source
以MySQL为例,示范如何配置全量索引的数据源
Java代码 收藏代码
source poi_name
{
type = mysql ######数据源类型
sql_host = localhost ######mysql主机
sql_user = root ######mysql用户名
sql_pass = ************ ######mysql密码
sql_db = *** ######mysql数据库名
sql_port = 3306 ######mysql端口
sql_query_pre = SET NAMES utf8 ###mysql检索编码,特别要注意这点,很多人中文检索不到是数据库的编码是GBK或其他非UTF8
sql_query = \
SELECT id, poi_name, poi_name as name, branch_name, city_id, district_id, biz_area_id, type_id, level, latitude/1000000 latitude, longitude/1000000 longitude, complain_status, creator_id, create_time, check_status, modify_time, deleted, link_status \
FROM poi ####### 获取数据的sql,这里可以指定条件查询进行过滤
#####以下是用来过滤或条件查询的属性,这里列出的字段将可以进行条件查询,同时不参与全文检索############
sql_attr_uint = city_id
sql_attr_uint = district_id
sql_attr_uint = biz_area_id
sql_attr_uint = type_id
sql_attr_uint = level
sql_attr_uint = complain_status
sql_attr_uint = creator_id
sql_attr_uint = create_time
sql_attr_uint = check_status
sql_attr_uint = deleted
sql_attr_uint = modify_time
sql_attr_uint = link_status
sql_attr_float = latitude
sql_attr_float = longitude
sql_attr_string = poi_name ####### poi_name字段将不参与全文检索
}
增量索引的配置与之类似,只不过需要根据增量条件对获取数据进行过滤,这里以时间戳为例(也可以通过对id设置更新记录表等其它方式来设置增量条件)
Java代码 收藏代码
source poi_name_incr : poi_name
{
sql_query = \
SELECT id, poi_name, poi_name as name, branch_name, city_id, district_id, biz_area_id, type_id, level, latitude/1000000 latitude, longitude/1000000 longitude, complain_status, creator_id, create_time, check_status, modify_time, deleted, link_status \
FROM poi where create_time > unix_timestamp() - 360
...
}
实时索引不需要设置数据源,直接在index里配置为rt即可
index
全量索引的index配置如下,这里没有配置采用外置的分词插件如mmseg等
Java代码 收藏代码
index poi_name
{
source = poi_name #### 声明索引数据源
path = /opt/***/mtpoi/indexfiles/poi_name #######索引文件存放路径
docinfo = extern #### 文档信息存储方式
mlock = 0 #### 缓存数据内存锁定
morphology = none #### 形态学(对中文无效)
min_word_len = 1 #### 索引的词最小长度
charset_type = utf-8 #### 数据编码
ngram_len = 1 #### 对于非字母型数据的长度切割
ngram_chars = U+3000..U+2FA1F #加上这个选项,则会对每个中文,英文字词进行分割
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F ##### 字符表,如使用这种方式,则Sphinx会对中文进行单字切分
html_strip = 0
}
增量索引的index配置与之类似,只是将数据源及path设置为增量索引的即可
Java代码 收藏代码
index poi_name_incr
{
source = poi_name_incr
path = /opt/***/mtpoi/indexfiles/poi_name_incr
....
}
实时索引由于不需要设置数据源,配置有些不同
Java代码 收藏代码
index poi_rt
{
type = rt #### 声明为实时索引
rt_mem_limit = 512M
path = /opt/***/mtpoi/indexfiles/poi_rt
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
ngram_chars = U+3000..U+2FA1F
#### 实时索引的条件查询字段 ####
rt_attr_uint = city_id
rt_attr_uint = district_id
rt_attr_uint = biz_area_id
rt_attr_uint = type_id
rt_attr_uint = level
rt_attr_uint = complain_status
rt_attr_uint = creator_id
rt_attr_uint = create_time
rt_attr_uint = check_status
rt_attr_uint = deleted
rt_attr_uint = modify_time
rt_attr_uint = link_status
rt_attr_float = latitude
rt_attr_float = longitude
rt_attr_string = poi_name
#### 参与全文检索的属性 ####
rt_field = poi_name
rt_field = branch_name
}
indexer
indexer的配置比较简单,一般来说不需要改动,配置完毕后执行indexer工具重建索引即可
Java代码 收藏代码
# 重建配置里的全部索引,必须关闭searchd
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***mtpoi/conf/sphinx.conf.incr --all
# 重建部分索引(poi_name_incr),可指定多个
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***/mtpoi/conf/sphinx.conf.incr poi_name_incr
# searchd运行过程中更新索引,添加--ratate参数
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***/mtpoi/conf/sphinx.conf.incr --rotate poi_name
searchd
searchd的配置项里最主要的是监听端口
Java代码 收藏代码
searchd
{
listen = 9346 # 监听端口,api访问端口
listen = 9340:mysql41 # SphinxQL访问端口
log = /var/sankuai/logs/sphinx_poi_incr/sphinx-searchd.log
query_log = /var/sankuai/logs/sphinx_poi_incr/sphinx-query.log
max_matches = 10000 # 最大匹配结果,在某些情况下该数值会导致查询不到结果,比如有设置分页项时想获取1w条之后的记录
query_log_format = sphinxql # 日志查询格式化,plain为简单文本格式,这里采用sphinxql以获取更丰富的查询信息
mysql_version_string = 5.5.21 # 返回给通过SphinxQL访问的MySQL版本号,目前采用的mysql-connector-java-5.1.15需要设置该值,否则连接时会报错
....
}
执行indexer建好索引后,直接启动searchd即可启用Sphinx查询服务
/usr/local/sphinx-2.1.0/bin/searchd -c /opt/***/mtpoi/conf/sphinx.conf.incr
然后通过crontab等方式调用indexer来更新索引文件
SphinxQL
Sphinx的searchd守护程序从版本0.9.9-rc2开始支持MySQL二进制网络协议,并且能够通过标准的MySQL API访问
Java代码 收藏代码
$ mysql -P 9306
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 0.9.9-dev (r1734)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
新的访问方法是对原生API的一种补充,原生API仍然可用。事实上,两种访问方法可以同时使用。另外,原生API仍旧是默认的访问方法。MySQL协议支持需要经过额外的配置才能启用。当然这只需要更动一行配置文件,加入一个协议为mysql41的监听器(listener)就可以了:
listen = 9340:mysql41 # SphinxQL访问端口
分布式索引
除了实时索引之外,Sphinx还支持一种特殊的索引方式------分布式索引,分布式检索可以改善查询延迟问题(即缩短查询时间)和提高多服务器、多CPU或多核环境下的吞吐率(即每秒可以完成的查询数)。这对于大量数据(即十亿级的记录数和TB级的文本量)上的搜索应用来说是很关键的。其关键思想是对数据进行水平分区(HP,Horizontally partition),然后并行处理:
1:在不同服务器上设置Sphinx程序集(indexer和searchd)的多个实例
2:让这些实例对数据的不同部分做索引(并检索)
3:在searchd的一些实例上配置一个特殊的分布式索引然后对这个索引进行查询
这个特殊索引只包括对其他本地或远程索引的引用,因此不能对它执行重新建立索引的操作,相反,如果要对这个特殊索引进行重建,要重建的是那些被这个索引被引用到的索引。
当searchd收到一个对分布式索引的查询时,它做如下操作:
1:连接到远程代理
2:执行查询 :#(在远程代理执行搜索的同时)对本地索引进行查询;
3:接收来自远程代理的搜索结果
4:将所有结果合并,删除重复项
5:将合并后的结果返回给客户端
在应用程序看来,普通索引和分布式索引完全没有区别。也就是说,分布式索引对应用程序而言是完全透明的,实际上也无需知道查询使用的索引是分布式的还是本地的。<br/> 任一个searchd实例可以同时做为主控端(master,对搜索结果做聚合)和从属端(只做本地搜索)。这有如下几点好处:
1: 集群中的每台机器都可以做为主控端来搜索整个集群,搜索请求可以在主控端之间获得负载平衡,相当于实现了一种HA(high availability,高可用性),可以应对某个节点失效的情况.
2: 如果在单台多CPU或多核机器上使用,一个做为代理对本机进行搜索的searchd实例就可以利用到全部的CPU或者核
这里采用前述配置的几种索引做一个简单的分布式索引配置示例
Java代码 收藏代码
index poi_dist
{
type = distributed #### 设置为分布式搜索
local = poi_name #### 设置查询本地全量索引
local = poi_name_incr #### 设置查询本地增量索引
local = poi_rt #### 设置查询本地实时索引
agent = srv24:9340:poi_name #### 也可以通过agent来进行查询远程全量索引
}
更详细的分布式搜索的相关配置参数比如超时等参考官方文档。
近实时索引实现
在商家数据中心的使用场景中,目前存在一些对实时性要求比较高的检索需求,比如在CRM系统里,对商家的审核状态进行审核(0->1)后,页面会自动刷新,此时会根据审核状态(1)进行查询,如果实时性不够的话此时会查询不到该数据,而且使用原状态(0)进行查询的时候,依然能查询到,这就要求目前的Sphinx查询能够尽可能的支持实时检索。
rt
如前面介绍,现有的Sphinx是有实时索引这种类型的,但据一些文章说其在大数据量的情况下性能不太好,另外,其初始时是没有数据的,而现有的数据库里已经有大约100w+的数据需要索引,全部采用rt索引看来不是一个好选择
参考:
http://www.ivinco.com/blog/plain-rt-and-mixed-indexes-performance-comparison/
http://www.ivinco.com/blog/how-to-speed-up-sphinx-real-time-indexes-up-to-5-10-times/
全量+增量
结合目前MDC中商家数据的实际情况(新增,更新相对较少),可以采用对稳定数据采用全量索引,对发生更新的数据采用增量索引,然后利用distributed的特性来合并查询
Java代码 收藏代码
index poi_dist
{
type = distributed #### 设置为分布式搜索
local = poi_name #### 设置查询本地全量索引
local = poi_name_incr #### 设置查询本地增量索引
}
增量索引由于数据量少,每次重建索引时耗时不到1s,可以做到5-10s左右更新一次,然后与全量索引进行merge,把增量索引更新到进来。
Java代码 收藏代码
indexer --merge DSTINDEX SRCINDEX --rotate
这种方案依然存在一些问题:
1:由于索引合并的间隔问题,如果一条记录被修改了,在还没有执行增量索引合并前,全量索引里依然是修改前的值,而增量索引已更新为修改后的值,这样在通过distributed来进行查询时合并后的结果集可能并不符合预期(有可能查询到修改前的记录)。对这个问题,可以采用API里提供的updateAttributes方法来实时更新索引的值,但Java版本的API目前仅支持对int,long类型的属性进行实时更新;当然也可以采用SphinxQL来进行属性的更新,其依然存在不支持非int,long类型的属性即时更新问题,但由于增量索引可以重建的比较频繁,在索引重建时会将这些非int,long类型的属性修改进行更新,这样对这些属性的索引大约存在5-10s左右的延迟,对int,long属性的修改可以即时索引进来.
2:由于其不支持即时新增索引项,只能等待增量索引重建时进行更新,所以其对新增记录也存在5-10s左右的延迟
全量+rt+SphinxQL
和全量+增量的方式类似,只不过将增量索引换成直接使用rt索引,然后类似进行merge合并,其好处是可以即时将新增或修改的记录反映到索引中(这里对新增索引必须采用SphinxQL,目前Java版本的API不支持新增索引记录),但对于非int,long类型的属性修改依然没有什么好办法,只能等待执行索引更新时进行更新,但全量索引的更新相对周期比较长,所以相对延迟会比较大。
与Lucene的简单对比
对Lucene暂时接触不深,简单对比一下:
1: Sphinx建索引速度非常的快;Lucene建索引相比Sphinx要差很多,同样建1000w数据,Sphinx2分钟以内,Lucene10分钟多,不过搜索性能上相差不太大
2: Sphinx的索引结构必须提前预定义好;Lucene的索引结构是比较自由的
3: Sphinx查询中Attribute(属性)的概念,而且Sphinx在启动Searchd的时候会将所有属性加载到内存中;而Lucene则没有,虽然Lucene也有NumericField,但是底层仍然是作为String处理的。这点可能会导致Sphinx比Lucene查询性能上好一些
4: Lucene用Java,代码阅读上相对容易
转载:http://hot66hot.iteye.com/blog/1759559
Sphinx是由一个开源的全文检索引擎,功能类似Lucune,用C++编写,可为其他应用提供高速、低空间占用、高结果相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成,当前系统内置MySQL和PostgreSQL数据库数据源的支持,也支持从标准输入读取特定格式的XML数据,通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS的原生支持)
Sphinx特性
1:Sphinx支持高速建立索引(可达10MB/秒,而Lucene建立索引的速度是1.8MB/秒)
2:高性能的搜索(在2--4GB的文本数据上,平均每次检索响应时间小于0.1秒)
3:高扩展性(实测最高可对100GB的文本建立索引,单一索引可包含1亿条记录)
4:提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法
5:支持分布式搜索
6:支持短语搜索
7:可作为MySQL的存储引擎提供搜索服务
8:支持布尔、短语、词语相似度等多种检索模式
9:文档支持多个全文检索字段
系统组成
整个Sphinx系统由多个可执行程序和一套api组成,这里引用Coreseek(一个基于Sphinx的开源检索引擎,提供了良好的中文支持)的一个结构图做个示例
可执行程序
1:索引建立和维护程序(索引程序indexer)
2:查询服务程序(后台服务程序searchd)
3:辅助工具程序(search, spelldump等)
api
1:应用程序api(包括ruby,C/C++, Python, php, java的程序api)
2:Mysql的SphinxSE引擎接口
3:SphinxQL支持
工作流程
安装好Sphinx后,首先需要根据想要检索的场景来建立对应的配置文件,Sphinx是以sphinx.conf为配置文件,索引与搜索均以这个文件为依据进行,要进行全文检索,首先就要配置好sphinx.conf,告诉sphinx哪些字段需要进行索引,哪些字段需要在where,orderby,groupby中用到。
该文件的结构大致如下:
Java代码 收藏代码
<![CDATA[source 源名称1{
…
}
index 索引名称1{
source=源名称1
…
}
source 源名称2{
…
}
index 索引名称2{
source = 源名称2
…
}
indexer{
…
}
searchd{
…
}
]]>
从配置文件的组成中我们可以发现Sphinx可以定义多个索引与数据源,不同的索引与数据源可以应用到不同表或不同应用的全文检索方式。
source
以MySQL为例,示范如何配置全量索引的数据源
Java代码 收藏代码
source poi_name
{
type = mysql ######数据源类型
sql_host = localhost ######mysql主机
sql_user = root ######mysql用户名
sql_pass = ************ ######mysql密码
sql_db = *** ######mysql数据库名
sql_port = 3306 ######mysql端口
sql_query_pre = SET NAMES utf8 ###mysql检索编码,特别要注意这点,很多人中文检索不到是数据库的编码是GBK或其他非UTF8
sql_query = \
SELECT id, poi_name, poi_name as name, branch_name, city_id, district_id, biz_area_id, type_id, level, latitude/1000000 latitude, longitude/1000000 longitude, complain_status, creator_id, create_time, check_status, modify_time, deleted, link_status \
FROM poi ####### 获取数据的sql,这里可以指定条件查询进行过滤
#####以下是用来过滤或条件查询的属性,这里列出的字段将可以进行条件查询,同时不参与全文检索############
sql_attr_uint = city_id
sql_attr_uint = district_id
sql_attr_uint = biz_area_id
sql_attr_uint = type_id
sql_attr_uint = level
sql_attr_uint = complain_status
sql_attr_uint = creator_id
sql_attr_uint = create_time
sql_attr_uint = check_status
sql_attr_uint = deleted
sql_attr_uint = modify_time
sql_attr_uint = link_status
sql_attr_float = latitude
sql_attr_float = longitude
sql_attr_string = poi_name ####### poi_name字段将不参与全文检索
}
增量索引的配置与之类似,只不过需要根据增量条件对获取数据进行过滤,这里以时间戳为例(也可以通过对id设置更新记录表等其它方式来设置增量条件)
Java代码 收藏代码
source poi_name_incr : poi_name
{
sql_query = \
SELECT id, poi_name, poi_name as name, branch_name, city_id, district_id, biz_area_id, type_id, level, latitude/1000000 latitude, longitude/1000000 longitude, complain_status, creator_id, create_time, check_status, modify_time, deleted, link_status \
FROM poi where create_time > unix_timestamp() - 360
...
}
实时索引不需要设置数据源,直接在index里配置为rt即可
index
全量索引的index配置如下,这里没有配置采用外置的分词插件如mmseg等
Java代码 收藏代码
index poi_name
{
source = poi_name #### 声明索引数据源
path = /opt/***/mtpoi/indexfiles/poi_name #######索引文件存放路径
docinfo = extern #### 文档信息存储方式
mlock = 0 #### 缓存数据内存锁定
morphology = none #### 形态学(对中文无效)
min_word_len = 1 #### 索引的词最小长度
charset_type = utf-8 #### 数据编码
ngram_len = 1 #### 对于非字母型数据的长度切割
ngram_chars = U+3000..U+2FA1F #加上这个选项,则会对每个中文,英文字词进行分割
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F ##### 字符表,如使用这种方式,则Sphinx会对中文进行单字切分
html_strip = 0
}
增量索引的index配置与之类似,只是将数据源及path设置为增量索引的即可
Java代码 收藏代码
index poi_name_incr
{
source = poi_name_incr
path = /opt/***/mtpoi/indexfiles/poi_name_incr
....
}
实时索引由于不需要设置数据源,配置有些不同
Java代码 收藏代码
index poi_rt
{
type = rt #### 声明为实时索引
rt_mem_limit = 512M
path = /opt/***/mtpoi/indexfiles/poi_rt
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
ngram_chars = U+3000..U+2FA1F
#### 实时索引的条件查询字段 ####
rt_attr_uint = city_id
rt_attr_uint = district_id
rt_attr_uint = biz_area_id
rt_attr_uint = type_id
rt_attr_uint = level
rt_attr_uint = complain_status
rt_attr_uint = creator_id
rt_attr_uint = create_time
rt_attr_uint = check_status
rt_attr_uint = deleted
rt_attr_uint = modify_time
rt_attr_uint = link_status
rt_attr_float = latitude
rt_attr_float = longitude
rt_attr_string = poi_name
#### 参与全文检索的属性 ####
rt_field = poi_name
rt_field = branch_name
}
indexer
indexer的配置比较简单,一般来说不需要改动,配置完毕后执行indexer工具重建索引即可
Java代码 收藏代码
# 重建配置里的全部索引,必须关闭searchd
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***mtpoi/conf/sphinx.conf.incr --all
# 重建部分索引(poi_name_incr),可指定多个
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***/mtpoi/conf/sphinx.conf.incr poi_name_incr
# searchd运行过程中更新索引,添加--ratate参数
/usr/local/sphinx-2.1.0/bin/indexer -c /opt/***/mtpoi/conf/sphinx.conf.incr --rotate poi_name
searchd
searchd的配置项里最主要的是监听端口
Java代码 收藏代码
searchd
{
listen = 9346 # 监听端口,api访问端口
listen = 9340:mysql41 # SphinxQL访问端口
log = /var/sankuai/logs/sphinx_poi_incr/sphinx-searchd.log
query_log = /var/sankuai/logs/sphinx_poi_incr/sphinx-query.log
max_matches = 10000 # 最大匹配结果,在某些情况下该数值会导致查询不到结果,比如有设置分页项时想获取1w条之后的记录
query_log_format = sphinxql # 日志查询格式化,plain为简单文本格式,这里采用sphinxql以获取更丰富的查询信息
mysql_version_string = 5.5.21 # 返回给通过SphinxQL访问的MySQL版本号,目前采用的mysql-connector-java-5.1.15需要设置该值,否则连接时会报错
....
}
执行indexer建好索引后,直接启动searchd即可启用Sphinx查询服务
/usr/local/sphinx-2.1.0/bin/searchd -c /opt/***/mtpoi/conf/sphinx.conf.incr
然后通过crontab等方式调用indexer来更新索引文件
SphinxQL
Sphinx的searchd守护程序从版本0.9.9-rc2开始支持MySQL二进制网络协议,并且能够通过标准的MySQL API访问
Java代码 收藏代码
$ mysql -P 9306
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 0.9.9-dev (r1734)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
新的访问方法是对原生API的一种补充,原生API仍然可用。事实上,两种访问方法可以同时使用。另外,原生API仍旧是默认的访问方法。MySQL协议支持需要经过额外的配置才能启用。当然这只需要更动一行配置文件,加入一个协议为mysql41的监听器(listener)就可以了:
listen = 9340:mysql41 # SphinxQL访问端口
分布式索引
除了实时索引之外,Sphinx还支持一种特殊的索引方式------分布式索引,分布式检索可以改善查询延迟问题(即缩短查询时间)和提高多服务器、多CPU或多核环境下的吞吐率(即每秒可以完成的查询数)。这对于大量数据(即十亿级的记录数和TB级的文本量)上的搜索应用来说是很关键的。其关键思想是对数据进行水平分区(HP,Horizontally partition),然后并行处理:
1:在不同服务器上设置Sphinx程序集(indexer和searchd)的多个实例
2:让这些实例对数据的不同部分做索引(并检索)
3:在searchd的一些实例上配置一个特殊的分布式索引然后对这个索引进行查询
这个特殊索引只包括对其他本地或远程索引的引用,因此不能对它执行重新建立索引的操作,相反,如果要对这个特殊索引进行重建,要重建的是那些被这个索引被引用到的索引。
当searchd收到一个对分布式索引的查询时,它做如下操作:
1:连接到远程代理
2:执行查询 :#(在远程代理执行搜索的同时)对本地索引进行查询;
3:接收来自远程代理的搜索结果
4:将所有结果合并,删除重复项
5:将合并后的结果返回给客户端
在应用程序看来,普通索引和分布式索引完全没有区别。也就是说,分布式索引对应用程序而言是完全透明的,实际上也无需知道查询使用的索引是分布式的还是本地的。<br/> 任一个searchd实例可以同时做为主控端(master,对搜索结果做聚合)和从属端(只做本地搜索)。这有如下几点好处:
1: 集群中的每台机器都可以做为主控端来搜索整个集群,搜索请求可以在主控端之间获得负载平衡,相当于实现了一种HA(high availability,高可用性),可以应对某个节点失效的情况.
2: 如果在单台多CPU或多核机器上使用,一个做为代理对本机进行搜索的searchd实例就可以利用到全部的CPU或者核
这里采用前述配置的几种索引做一个简单的分布式索引配置示例
Java代码 收藏代码
index poi_dist
{
type = distributed #### 设置为分布式搜索
local = poi_name #### 设置查询本地全量索引
local = poi_name_incr #### 设置查询本地增量索引
local = poi_rt #### 设置查询本地实时索引
agent = srv24:9340:poi_name #### 也可以通过agent来进行查询远程全量索引
}
更详细的分布式搜索的相关配置参数比如超时等参考官方文档。
近实时索引实现
在商家数据中心的使用场景中,目前存在一些对实时性要求比较高的检索需求,比如在CRM系统里,对商家的审核状态进行审核(0->1)后,页面会自动刷新,此时会根据审核状态(1)进行查询,如果实时性不够的话此时会查询不到该数据,而且使用原状态(0)进行查询的时候,依然能查询到,这就要求目前的Sphinx查询能够尽可能的支持实时检索。
rt
如前面介绍,现有的Sphinx是有实时索引这种类型的,但据一些文章说其在大数据量的情况下性能不太好,另外,其初始时是没有数据的,而现有的数据库里已经有大约100w+的数据需要索引,全部采用rt索引看来不是一个好选择
参考:
http://www.ivinco.com/blog/plain-rt-and-mixed-indexes-performance-comparison/
http://www.ivinco.com/blog/how-to-speed-up-sphinx-real-time-indexes-up-to-5-10-times/
全量+增量
结合目前MDC中商家数据的实际情况(新增,更新相对较少),可以采用对稳定数据采用全量索引,对发生更新的数据采用增量索引,然后利用distributed的特性来合并查询
Java代码 收藏代码
index poi_dist
{
type = distributed #### 设置为分布式搜索
local = poi_name #### 设置查询本地全量索引
local = poi_name_incr #### 设置查询本地增量索引
}
增量索引由于数据量少,每次重建索引时耗时不到1s,可以做到5-10s左右更新一次,然后与全量索引进行merge,把增量索引更新到进来。
Java代码 收藏代码
indexer --merge DSTINDEX SRCINDEX --rotate
这种方案依然存在一些问题:
1:由于索引合并的间隔问题,如果一条记录被修改了,在还没有执行增量索引合并前,全量索引里依然是修改前的值,而增量索引已更新为修改后的值,这样在通过distributed来进行查询时合并后的结果集可能并不符合预期(有可能查询到修改前的记录)。对这个问题,可以采用API里提供的updateAttributes方法来实时更新索引的值,但Java版本的API目前仅支持对int,long类型的属性进行实时更新;当然也可以采用SphinxQL来进行属性的更新,其依然存在不支持非int,long类型的属性即时更新问题,但由于增量索引可以重建的比较频繁,在索引重建时会将这些非int,long类型的属性修改进行更新,这样对这些属性的索引大约存在5-10s左右的延迟,对int,long属性的修改可以即时索引进来.
2:由于其不支持即时新增索引项,只能等待增量索引重建时进行更新,所以其对新增记录也存在5-10s左右的延迟
全量+rt+SphinxQL
和全量+增量的方式类似,只不过将增量索引换成直接使用rt索引,然后类似进行merge合并,其好处是可以即时将新增或修改的记录反映到索引中(这里对新增索引必须采用SphinxQL,目前Java版本的API不支持新增索引记录),但对于非int,long类型的属性修改依然没有什么好办法,只能等待执行索引更新时进行更新,但全量索引的更新相对周期比较长,所以相对延迟会比较大。
与Lucene的简单对比
对Lucene暂时接触不深,简单对比一下:
1: Sphinx建索引速度非常的快;Lucene建索引相比Sphinx要差很多,同样建1000w数据,Sphinx2分钟以内,Lucene10分钟多,不过搜索性能上相差不太大
2: Sphinx的索引结构必须提前预定义好;Lucene的索引结构是比较自由的
3: Sphinx查询中Attribute(属性)的概念,而且Sphinx在启动Searchd的时候会将所有属性加载到内存中;而Lucene则没有,虽然Lucene也有NumericField,但是底层仍然是作为String处理的。这点可能会导致Sphinx比Lucene查询性能上好一些
4: Lucene用Java,代码阅读上相对容易
转载:http://hot66hot.iteye.com/blog/1759559
发表评论
-
centos7安装mysql
2016-11-14 16:41 1294centos7的默认yum源已经 ... -
MySQL的InsertOrUpdate语法
2016-08-04 14:47 1748MySQL的插入语法提供了 ... -
unbutu+mysql的root密码重置方法
2016-01-11 14:16 1267MySQL密码重置策略: 1,停止mysql服务 s ... -
使用shell分页读取600万+的MySQL数据脚本
2015-07-15 13:02 2736shell-mysql (1)脚本背景: 由于要在Linux ... -
玩转大数据系列之Apache Pig如何与MySQL集成(三)
2015-03-07 19:43 2632上篇介绍了如何把Pig的结果存储到Solr中,那么可能就会有朋 ... -
JAVA内存数据库使用demo
2014-10-13 17:51 2442上篇文章散仙,写了关于SQLite的使用,本篇我们看下几款JA ... -
JDBC预编译语句表名占位异常
2014-10-11 11:41 1952有时候,我们有这样的需求,需要清空多个表的内容,这样我们有两种 ... -
Mysql安装完注意事项
2014-02-19 09:43 832即使是经验老道的人也 ...
相关推荐
Sphinx以其高效、灵活和可扩展性著称,广泛应用于网站、数据库和各类信息系统中。 1. **Sphinx安装**: 安装Sphinx通常涉及下载源代码,编译并安装。首先,你需要访问Sphinx的官方网站获取最新版本的源代码。然后...
Sphinx是一个高性能、开源的全文检索引擎,专为配合SQL数据库而设计,如MySQL和PostgreSQL,用于实现高效且专业的全文搜索功能。它的核心优势在于能够提供比数据库原生搜索更强大的搜索性能,并且易于集成到各种使用...
1. **PocketSphinx介绍** PocketSphinx是CMU Sphinx(卡内基梅隆大学Sphinx)项目的一部分,它是一个轻量级的解码器,特别适合嵌入式设备。它的主要优点是能够离线运行,不依赖云端服务,因此对于数据隐私和网络...
Sphinx介绍 Sphinx是一款开源的实时全文搜索引擎,具有高效、灵活和高度可定制的特点。它支持多种编程语言的API,包括PHP,使得在Web应用中集成搜索变得简单。 ### 2. CoreSeek介绍 CoreSeek是基于Sphinx的中文...
1. **CMU Sphinx介绍** CMU Sphinx是由卡内基梅隆大学开发的一套开源语音识别框架,它包含了一系列的语音处理工具,如声学模型训练、语言模型构建等。PocketSphinx是其在嵌入式系统和移动设备上的优化版本,对资源...
1. **PocketSphinx介绍**:PocketSphinx是CMU Sphinx(卡内基梅隆大学的Sphinx)项目的一部分,专门针对嵌入式系统和移动设备进行了优化。它支持实时连续语音识别,可以处理多种语言,并且支持自定义词汇表和语言...
1. **Sphinx介绍**:Sphinx是一个基于Python的文档生成工具,它被广泛用于Python项目的文档编写。Sphinx通过解析结构化的文本文件(如reStructuredText)生成HTML、PDF、EPUB等多种格式的文档。 2. **...
**Sphinx介绍** Sphinx是一个用于创建高质量文档的工具,特别适合于技术文档的编写。它支持多种输出格式,如HTML、PDF、Epub等,并且有丰富的主题和扩展支持。Sphinx通过`reStructuredText`(reST)语法来编写文档...
**Sphinx介绍** Sphinx是一个强大的文档生成工具,广泛用于编写技术文档、项目手册以及API文档。它使用简洁明了的ReStructuredText (reST) 格式编写源文件,然后生成HTML、PDF、EPUB等多种格式的文档,支持自定义...
介绍sphinx实时索引的特点和工作机制
### Sphinx 中英文分词检索介绍 #### 一、Sphinx简介 Sphinx是一款高性能的全文检索引擎,能够显著提升在大型数据库中进行全文检索的速度。它最初由Andrew Aksyonoff设计并开发,旨在解决MySQL数据库在处理大量文本...
2. PocketSphinx介绍: PocketSphinx是CMU Sphinx针对嵌入式设备,特别是移动设备设计的一个轻量级版本。它的目标是低资源消耗和快速响应,使得在Android手机和平板电脑上实时语音识别成为可能。PocketSphinx包含了...
本文档介绍Sphinx4在Windows下的中文训练过程及注意事项,与本文档配套的是我自己的训练实例bergtrain和用到的软件。 本文档编写日期 2013-04-23 1、为什么要训练? sphinx4目前的版本中仅提供了英文等语音识别库。...
2. **基本API使用**:介绍如何使用Pocketsphinx的API进行语音识别,包括初始化、录音、解码和关闭等步骤。 3. **模型训练**:解释如何收集数据、创建自定义模型,并进行训练。 4. **实例演示**:提供实际应用案例...
**一、Sphinx介绍** Sphinx是由Benoit Stein创建的一个开源文档生成器,它支持多种输出格式,如HTML、PDF、Epub等。Sphinx以其简洁的文本格式ReStructuredText(reST)为基础,允许开发者使用易于阅读和写作的语法...
本文将详细介绍pocketsphinx以及其在中文语音识别中的应用。pocketsphinx是一款开源的、轻量级的语音识别引擎,它主要用于离线语音识别任务,特别适合于资源有限的设备上运行。该软件包是CMU Sphinx项目的一部分,由...
6. Sphinx Domains(Sphinx域):这是Sphinx的一个重要特性,介绍域的概念,它允许Sphinx针对特定领域(如Python、C、C++、JavaScript等)生成定制的文档,并提供特定于这些领域的标记。 7. Serialization builder ...
- **文档**:包括用户手册和开发者指南,详细介绍如何使用和开发pocketsphinx。 通过pocketsphinx-0.8,开发者可以构建各种应用场景,如智能家居控制、语音助手、教育软件、无障碍应用等,将语音识别技术融入到日常...
本文将详细介绍如何在Linux下配置和使用PHP与Sphinx进行实际操作。 首先,Sphinx是一个开源的全文搜索引擎,它设计用于提供高速、高精度的全文检索服务。它的核心特性包括实时索引、低内存占用以及支持多种数据源,...
在提供的链接 http://www.cnblogs.com/strick/p/4173757.html 中,博主详细介绍了如何搭建 Sphinx 的环境以及进行基本的配置。这个教程主要分为以下几个部分: 1. **下载与安装**: - `coreseek-4.1-win32` 文件是...