Manticore 索引基础

在本文中,我们讨论 Manticore 索引的介绍。

Manticore Search 支持两种存储索引类型:

  • 普通(也称为离线或磁盘)索引。数据在创建时被索引一次,支持在线重建和非文本属性的在线更新。

  • 实时索引。类似于数据库表,任何时候都可以进行在线更新。

此外,基于实时类型的特殊索引,称为 percolate,可用于存储 <span class="std std-ref">Percolate 查询</span>

在当前版本中,索引使用类似于普通数据库表的模式。模式可以有 3 种主要类型的列:

  • 第一列始终是一个无符号的 64 位非零数字,称为 id。与数据库不同,没有自动递增的机制,因此您需要确保文档 ID 是唯一的。

  • 全文字段 - 它们包含被索引的内容。每个索引可以有多个全文字段。可以对所有字段或选择性字段进行全文搜索。目前原始文本不被存储,如果需要在搜索结果中显示其内容,必须使用搜索结果提供的 ID(或其他标识符)访问原始源。

  • 属性 - 其值被存储,并且不用于全文匹配。相反,它们可以用于常规过滤、分组、排序。它们也可以用于评分排名的表达式中。

可以在属性中存储以下数据类型:

  • 无符号 32 位和有符号 64 位整数。

  • 32 位单精度浮点数。

  • UNIX 时间戳。

  • 布尔值。

  • 字符串。

  • JSON 对象。

  • 无符号 32 位整数或有符号 64 位整数的多值属性列表。

Manticore Search 支持一种称为分布式的无存储索引类型,允许在多个索引上进行搜索。连接的索引可以是本地的或远程的。分布式索引允许将大数据分散到多台机器上或构建高可用性设置。

另一种无存储索引类型是 template 。模板索引不存储数据,但可以保存像存储索引的标记设置。它可以用于测试标记化规则或生成高亮显示。

普通索引


除了数字(包括 MVA)属性,普通索引中的其余数据是不可变的。如果您需要更新/添加新记录,您需要再次执行重建。在索引重建期间,现有索引仍然可用以处理请求。当新版本准备好时,会执行一个称为 rotation 的过程,将新版本上线并丢弃旧版本。

索引性能过程取决于几个因素:

  • 源提供数据的速度。

  • 标记设置。

  • 硬件资源(CPU 功率、存储速度)。

在最简单的使用场景中,我们将使用一个普通索引,并不时对其进行重建。

这意味着:

  • 索引不如源中的数据新鲜。

  • 索引持续时间随着数据的增长而增加。

如果我们希望数据更为新鲜,我们需要缩短索引间隔。如果索引耗时过长,甚至可能会与索引之间的时间重叠,这将是一个主要问题。然而,Manticore Search 可以在多个索引上执行搜索。因此,产生了使用一个仅捕获最新更新的辅助索引的想法。

这个索引会小得多,我们将更频繁地对其进行索引。随着这个增量索引的增长,我们会想要“重置”它。

这可以通过重新索引主索引或将增量合并到主索引中来完成。主+增量索引模式的详细信息见 <span class="std std-ref">增量索引更新</span>

由于引擎无法对文档 ID 进行全局唯一性检查,因此需要考虑的重要事项是增量索引是否可能包含对主索引中现有索引记录的更新。

为此,有一个选项允许定义一个文档 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 不仅会排除有问题的镜像,还会监控响应时间并进行平衡。如果一个镜像响应较慢(例如由于正在运行某些操作),它将接收较少的请求。当镜像恢复并提供更好的响应时间时,它将接收更多请求。

安装Manticore Search

安装Manticore Search