在这篇文章中,我们讨论了 Manticore 索引的介绍。
Manticore 搜索支持两种存储索引类型:
普通(也称为离线或磁盘)索引。数据在创建时索引一次,支持在线重建和非文本属性的在线更新
实时索引。类似于数据库表,在线更新随时可能
此外,一种基于实时类型的特殊索引,称为 percolate,可用于存储 <span class="std std-ref">Percolate 查询</span> 。
在当前版本中,索引使用类似于正常数据库表的模式。模式可以有 3 种大类型的列:
第一列始终是一个无符号的 64 位非零数字,称为 id。与数据库不同,没有自动递增的机制,因此您需要确保文档 id 是唯一的
全文字段 - 它们包含已索引的内容。每个索引可以有多个全文字段。可以对所有字段或选择性进行全文搜索。目前原始文本不被存储,如果需要在搜索结果中显示其内容,必须使用搜索结果提供的 id(或其他标识符)进行一次回访原始来源
属性 - 它们的值被存储并且不用于全文匹配。相反,它们可以用于常规过滤、分组、排序。它们也可以用于得分排名的表达式中。
以下数据类型可以存储在属性中:
无符号 32 位和有符号 64 位整数
32 位单精度浮点数
UNIX 时间戳
布尔值
字符串
JSON 对象
无符号 32 位整数或有符号 64 位整数的多值属性列表
Manticore 搜索支持一种无存储索引类型,称为分布式索引,允许在多个索引上进行搜索。连接的索引可以是本地或远程。分布式索引允许在多台机器上分散大数据或构建高可用性设置。
另一种无存储索引类型是 template 。模板索引不存储数据,但可以像存储索引一样保存标记化设置。它可以用于测试标记化规则或生成高亮。
普通索引
除了数字(包括 MVA)属性之外,普通索引中的其他数据是不可变的。如果您需要更新/添加新记录,则需要再次执行重建。在索引被重建时,现有索引仍然可以为请求提供服务。当新版本准备好时,会执行一个称为 rotation 的过程,将新版本上线并丢弃旧版本。
索引性能过程取决于几个因素:
源提供数据的速度
标记化设置
硬件资源(CPU 功率、存储速度)
在最简单的使用场景中,我们会使用一个普通索引,并不时对其进行重建。
这意味着:
索引不如源数据新鲜
索引持续时间随着数据增长而增长
如果我们希望数据更加新鲜,则需要缩短索引时间间隔。如果索引花费的时间过长,甚至可能会与索引之间的时间重叠,这是一个主要问题。然而,Manticore 搜索可以在多个索引上执行搜索。因此,产生了使用一个仅捕获最新更新的辅助索引的想法。
这个索引会小得多,我们将更频繁地对其进行索引。随着这个增量索引的增长,我们会想要“重置”它。
这可以通过重新索引主索引或将增量合并到主索引中来完成。主 + 增量索引模式的详细信息见 <span class="std std-ref">Delta 索引更新</span> 。
由于引擎无法在文档 id 上全局执行唯一性,因此一个需要考虑的重要事项是增量索引是否可能包含对主索引中现有索引记录的更新。
为此,有一个选项允许定义一个文档 id 列表,由增量索引抑制。有关更多详细信息,请查看 <span class="std std-ref">sql_query_killlist</span> 。
实时索引
RealTime 索引 允许在线更新,但更新全文数据和非数字属性需要完全替换行。
实时索引从空开始,您可以以与数据库表相同的方式添加、替换、更新或删除数据。更新首先保留在一个内存区域(称为 RAM 块)中,该区域由
<span class="std std-ref">rt_mem_limit</span>
定义。当它填满后,它会作为磁盘块转储 - 其结构与普通索引类似。随着磁盘块数量的增加,搜索性能会下降,因为搜索在块上是顺序进行的。为了克服这个问题,需要将块合并为一个单块,这通过
<span class="std std-ref">OPTIMIZE INDEX</span>
命令完成。
RAM 块也可以通过
FLUSH RAMCHUNK
强制写入磁盘。在刷新 RAM 块并优化索引后,实时(RT)索引的性能最佳 - RT 索引将所有数据放在单个块中,并且性能与普通索引相同。
填充实时索引可以通过两种方式完成:发送 INSERT 或
转换
普通索引为实时索引。现有数据可以逐条插入,也可以批量插入多条记录。多个并行工作进程插入数据将加快进程,但会消耗更多 CPU。
RAM 块大小会影响更新速度,更大的 RAM 块可提供更好的性能,但需要根据可用内存进行调整。还需注意的是,rt_mem_limit 仅限制 RAM 块的大小。磁盘块(基本上是普通索引)将有其自身的内存需求(用于加载词典或属性)。
RAM 块的内容在干净关闭时或按
rt_flush_period
指令定义的周期写入磁盘(可以使用 FLUSH RTINDEX 命令强制执行)。RT 索引还可以使用
二进制日志
记录更改。二进制日志可以在守护进程启动时重放,以便在非正常关闭后恢复,并在 RAM 块刷新到磁盘后清除。
刷新二进制日志的
策略
(类似于 MySQL 的 innodb_flush_log_at_trx_commit)可能会影响性能。也可以禁用二进制日志(通过设置空的二进制日志路径),但这将无法保护尚未刷新到磁盘的更新。
本地分布式索引
Manticore Search 中的分布式索引不存储任何数据。相反,它充当"主节点",在其他索引上触发所需查询,并提供从"节点"索引接收的响应的合并结果。分布式索引可以连接到本地索引或位于其他服务器上的索引。在我们的示例中,分布式索引如下所示:
index_dist {
type = distributed
local = index1
local = index2
...
}
启用多核搜索的最后一步是在 searchd 部分定义 dist_threads。Dist_threads 告诉引擎可以为分布式索引使用的最大线程数。
远程分布式索引和高可用性
index mydist {
type = distributed
agent = box1:9312:shard1
agent = box2:9312:shard2
agent = box3:9312:shard3
agent = box4:9312:shard4
}
在这里,我们将数据分散在 4 台服务器上,每台服务器服务一个分片。如果一台服务器失败,我们的分布式索引仍将工作,但将丢失失败分片的结果。
index mydist {
type = distributed
agent = box1:9312|box5:9312:shard1
agent = box2:9312:|box6:9312:shard2
agent = box3:9312:|box7:9312:shard3
agent = box4:9312:|box8:9312:shard4
}
现在我们添加了镜像,每个分片位于 2 台服务器上。默认情况下,主服务器(具有分布式索引的 searchd 实例)将随机选择一个镜像。
选择镜像的模式可以通过 ha_strategy 设置。除了随机,另一种简单的方法是进行轮询选择(ha_strategy = roundrobin)。
更有趣的策略是基于延迟加权概率的策略。noerrors 和 nodeads 不仅剔除存在问题的镜像,还监控响应时间并进行平衡。如果一个镜像响应较慢(例如由于正在运行某些操作),它将接收较少的请求。当镜像恢复并提供更好的响应时间时,它将接收更多请求。