sphinx实时索引

sphinx实时索引

一.sphinx实时索引介绍

sphinx实时索引在版本1.10-bita被引入的。

实时像其他所有的索引类型,需要在sphinx.conf文件中声明。不需要并忽略数据来源,需要明确地列举所有文本域,不只是属性。

实时索引内部组织

实时索引内部是分块组织的,它使用内存块存储最新的更新。内存块的大小使用rt-mem-limit参数指定。一旦内存块中数据增长超过了这个指数的限定,一个新的硬盘块将被创造出来存储当前内存块中的数据,而内存块将被重置。因此,对于实时索引大多数的更新会只发生在内存块中并会在几毫秒内立即完成,而在创建硬盘块的几秒钟当中产生的溢出内存块的更新将被拖延,直到硬盘块创建完成,内存中现有的数据被复制到硬盘块中并将内存块清空。

硬盘块实际上就相当于常规的基于硬盘的索引。但是它们只是实时索引的一部分,由实时索引自动管理,所以你不需要手动配置和管理它们。因为每当实时索引内存块数据超出限制,新的硬盘块会被创建,并且内存块的格式近似于硬盘块的格式,所以每次创建的硬盘块的大小与rt_mem_limit规定的内存块大小接近。

一般来说,rt_mem_limit设定的数值越大越好,能够将刷新频率和索引残片(硬盘块的数量)减到最小。例如一个处理大型实时索引的专用搜索服务器,建议将rt_mem_limit设为1-3G。目前计划设置一个对于所有索引的全局限制参数,但是在1.10beta版本中尚未实现。

硬盘块上的全文检索数据不能被修改,所以在全文字段的修改(如整行删除或更新)使用了一个kill-list表单从硬盘块上废止了老的行,但并非物理的清除了这些数据。所以大量的全文字段更新会导致索引被这些老的行污染,搜索表现下降。物理清除数据能够改善表现,但是在1.10beta版本中尚未实现。

内存块中的数据在平滑关闭进程时会存入硬盘,并在启动时载入内存。但是当进程或服务器崩溃,内存块中的更新可能会丢失。为防止丢失,可以使用事务二进制日志。

实时索引中的全文更改是事务性的。他们存储在一个预线程存储器中,直到commit再一起实施。一个单一commit包含的批处理越多,索引速度越快。

二进制日志

二进制日志是一个必要的恢复机制。启用二进制日志,searchd会将每个事务写入二进制日志中,并且在非正常关机后从二进制日志中恢复。在正常关机时,内存块中的数据将被存入硬盘,然后所有的二进制日志会被断开。

常规操作中,每当当前的二进制日志文件达到binlog_max_log_size(默认为128M)的限制,一个新的二进制日志文件会被创建并打开。老的二进制文件会保存直到所有保存在其中的事务被存入硬盘块中。将binlog_max_log_size设置为0将会保持二进制文件在searchd运行时始终被打开,但是正常关机后它仍然会被断开关闭。

存在三种不同的二进制刷新策略。使用binlog_flush 0,1或2指令控制。0意味着每秒钟刷新日志到操作系统并同步到磁盘,1意味着每事务刷新并同步,2(默认模式)意味着每事务进行刷新,但每秒进行同步。同步相对较慢因为它需要进行物理硬盘读写,所以模式1是最安全但是也是最慢的(每个提交的事务都保证会写入磁盘)。刷新日志到操作系统会在searchd进程崩溃时防止数据丢失,但系统崩溃时无法防止。模式2是默认模式。

从一次非正常关机后恢复,二进制日志被回放,从最后一个完好的事务之后的所记录的事务都会被恢复。事务会被核对总和,所以一些无用数据不会被恢复。一旦损坏的事务被检查到,会停止回放。事务会有一个自动记号和时间戳,假如二进制文件中部损坏,技术上来说是可以跳过损坏的事务并从下一条完好的事务继续回放,同时也可以持续回放事务直到一个给定的时间戳(时间点恢复)。但是在1.10beta版本中这些都尚未实现。

 

二.sphinx实时索引安装

$ sudo apt-get install subversion

$ svn checkout http://sphinxsearch.googlecode.com/svn/trunk sphinx-bita

$ sudo ./configure –prefix=/usr/local/sphinx-bita

$ sudo make

$ sudo make install

三.sphinx实时索引配置

$ sudo cp sphinx.conf.dist sphinx.conf

$ sudo vim sphinx.conf

index bbs_post //索引名称bbs_post

{

type = rt //索引类型

path = /usr/local/sphinx-bita/var/data/bbs_post

docinfo = extern

mlock = 0

morphology = none

min_word_len = 1

html_strip = 0

rt_field = author //全文索引字段

rt_field = subject

rt_field = message

rt_attr_uint = fid //属性字段

rt_attr_uint = tid

rt_attr_uint = first

rt_attr_uint = invisible

rt_attr_uint = authorid

rt_attr_timestamp = dateline

rt_mem_limit = 512M //实时索引内存

}

searchd

{

listen = localhost:9306:mysql41 //mysql协议支持sphinxql。sphinx模拟mysql接口,不需要真正的mysql服务,mysql41表示支持mysql4.1-mysql5.1协议

log = /usr/local/sphinx-bita/var/log/searchd.log

query_log = /usr/local/sphinx-bita/var/log/query.log

read_timeout = 5

client_timeout = 300

max_children = 30

pid_file = /usr/local/sphinx-bita/var/log/searchd.pid

max_matches = 1000

seamless_rotate = 1

preopen_indexes = 1

unlink_old = 1

mva_updates_pool = 1M

max_packet_size = 8M

crash_log_path = /usr/local/sphinx-bita/var/log/crash

max_filters = 256

max_filter_values = 4096

max_batch_queries = 32

binlog_flush = 2

binlog_max_log_size = 256M

thread_stack = 128K

query_log_format = sphinxql

compat_sphinxql_magics = 1

}

四.启动

$ sudo /usr/local/sphinx-bita/bin/searchd –config /usr/local/sphinx-bita/etc/sphinx.conf

Sphinx 2.0.2-dev (r2895)

Copyright (c) 2001-2011, Andrew Aksyonoff

Copyright (c) 2008-2011, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file ‘/usr/local/sphinx-bita/etc/sphinx.conf’…

listening on 127.0.0.1:9306

precaching index ‘bbs_post’

precached 1 indexes in 0.001 sec

五.测试

$ mysql -h127.0.0.1 -P9306

mysql> desc bbs_post;

+———–+———–+

| Field | Type |

+———–+———–+

| id | integer |

| author | field |

| subject | field |

| message | field |

| fid | uint |

| tid | uint |

| first | uint |

| invisible | uint |

| authorid | uint |

| dateline | timestamp |

+———–+———–+

mysql> insert into bbs_post values (1,’mobei’,’sphinx Real-time indexes’,’test sphinx Real-time indexes’,1,1,1,0,1,1311895260);

mysql> insert into bbs_post values (2,’mobei-2′,’sphinx ‘,’sphinx’,1,1,1,0,1,1311895600);

mysql> insert into bbs_post values (3,’mobei-3′,’Real-time indexes’,’SPHINX Real-time indexes’,1,1,1,0,1,1311896260);

mysql> select * from bbs_post where match(‘mobei’);

+——+——–+——+——+——-+———–+———-+————+

| id | weight | fid | tid | first | invisible | authorid | dateline |

+——+——–+——+——+——-+———–+———-+————+

| 1 | 1319 | 1 | 1 | 1 | 0 | 1 | 1311895260 |

| 2 | 1319 | 1 | 1 | 1 | 0 | 1 | 1311895600 |

| 3 | 1319 | 1 | 1 | 1 | 0 | 1 | 1311896260 |

+——+——–+——+——+——-+———–+———-+————+

3 rows in set (0.00 sec)

mysql> select * from bbs_post where match(‘beibei’);

Empty set (0.00 sec)

mysql> select * from bbs_post where match(‘test’);

+——+——–+——+——+——-+———–+———-+————+

| id | weight | fid | tid | first | invisible | authorid | dateline |

+——+——–+——+——+——-+———–+———-+————+

| 1 | 1680 | 1 | 1 | 1 | 0 | 1 | 1311895260 |

+——+——–+——+——+——-+———–+———-+————+

1 row in set (0.00 sec)

mysql> delete from bbs_post where id=1;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from bbs_post where match(‘test’);

Empty set (0.00 sec)

mysql> select * from bbs_post;

+——+——–+——+——+——-+———–+———-+————+

| id | weight | fid | tid | first | invisible | authorid | dateline |

+——+——–+——+——+——-+———–+———-+————+

| 2 | 1 | 1 | 1 | 1 | 0 | 1 | 1311895600 |

| 3 | 1 | 1 | 1 | 1 | 0 | 1 | 1311896260 |

+——+——–+——+——+——-+———–+———-+————+

2 rows in set (0.00 sec)