- 作者:老汪软件技巧
- 发表时间:2024-08-25 10:06
- 浏览量:
Control plane(控制平面)
控制平面服务负责调度索引任务给索引器。调度会在调度器接收到外部或内部事件以及满足某些条件时执行:
Janitor(清理程序)
清理程序服务在索引上运行维护任务:垃圾收集、删除查询任务和保留策略任务。
Data sources(数据源)
Quickwit 支持 多种数据源 来摄取数据。
文件非常适合一次性摄取,例如初始加载;摄取 API 或消息队列则非常适合持续地向系统喂送数据。
Quickwit 索引器直接连接到外部消息队列,如 Kafka、Pulsar 或 Kinesis,并保证恰好一次(exactly-once)的语义。如果您需要支持其他分布式队列,请在此 链接 中投票选择您需要的支持。
高级概念Indexing(索引)支持的数据格式
Quickwit 摄取 JSON 记录,并将其称为“文档”或“docs”。每个文档必须是一个 JSON 对象。在摄取文件时,文档之间必须用换行符分隔。
Quickwit 目前还不支持如 Avro 或 CSV 这样的文件格式。压缩格式如 bzip2 或 gzip 也不受支持。
Data model(数据模型)
Quickwit 支持无模式索引和固定模式。索引的“文档映射”(通常也称为“doc 映射”)是一份字段名称和类型的列表,用于声明索引的模式。对于无模式或混合固定模式与无模式索引,请遵循我们的 无模式索引指南。此外,文档映射还指定了文档如何被索引(标记器)和存储(列式 vs. 行式)的方式。
合并过程与合并策略
索引被分割成不可变的分片。分片的大小由其携带的文档数量决定。当分片的大小达到索引配置中定义的阈值 split_num_docs_target 时,该分片被视为“成熟”。
索引器缓冲传入的文档,并在缓冲区的大小达到 split_num_docs_target 或者自第一个文档被排队以来经过了 commit_timeout_secs 秒时生成一个新的分片,具体取决于哪个事件先发生。在这种情况下,索引器会产生不成熟的分片。合并过程是指将不成熟的分片分组并合并在一起以产生成熟分片的迭代过程。
合并策略控制合并算法,该算法主要由两个参数驱动:split_num_docs_target 和 merge_factor。每当有新的分片发布时,合并策略都会检查不成熟分片的列表,并尝试将 merge_factor 个分片合并在一起以产生更大的分片。合并策略也可能根据需要决定合并更少或更多的分片。最后,合并算法永远不会合并超过 max_merge_factor 个分片。
Split store(分片存储)
分片存储是一个缓存,它将最近发布的和不成熟的分片保留在磁盘上以加快合并过程。在一个成功的合并阶段之后,分片存储会清除悬空的分片。
分配给分片存储的磁盘空间由配置参数 split_store_max_num_splits 和 split_store_max_num_bytes 控制。
Data sources(数据源)
数据源指定可以从外部数据存储(可以是文件、流或数据库)连接和摄取数据的位置和一组参数。通常,Quickwit 简单地将数据源称为“源”。索引引擎支持使用 进行本地临时文件摄取和流式源(例如 Kafka 源)。Quickwit 可以从一个或多个源将数据插入到索引中。更多详细信息可以在 源配置页面 中找到。
Checkpoint(检查点)
Quickwit 通过检查点实现了恰好一次(exactly-once)处理。对于每个源,“源检查点”记录了目标文件或流中已处理的文档位置。检查点存储在元存储中,并且每次发布新分片时都会原子性地更新。当出现索引错误时,索引过程会从最后一个成功发布的检查点后立即恢复。内部地,源检查点表示为一个对象映射,该映射从绝对路径或分区 ID 到偏移量或序列号。
Querying(查询)
Quickwit 提供了两个带有全文搜索查询的端点,这些查询由 query 参数标识:
一个搜索流端点返回请求的 字段值 的流
搜索器接收到的搜索查询将按照以下步骤使用 Map-Reduce 方法执行:
搜索器根据请求的时间戳区间(参见)和标签(参见)来确定相关的分片。它使用 rendez-vous 哈希 在集群中的其他可用搜索器之间分发分片工作负载,以优化缓存和负载。最后,它等待所有结果,合并它们,并将结果返回给客户端。
搜索流查询遵循与搜索查询相同的执行路径,除了最后一步:而不是等待每个搜索器的结果,搜索器一旦开始从某个搜索器接收结果就立即流式传输这些结果。
Time sharding(时间分片)
对于具有时间成分的数据集,Quickwit 将数据分片为具有时间戳感知的分片。借助此功能,Quickwit 能够在查询处理阶段之前过滤掉大部分分片,从而大幅减少处理查询所需的数据量。
以下查询参数可用于对您的查询应用时间戳剪枝:
Tag pruning(标签剪枝)
Quickwit 还提供了在第二个维度上进行剪枝的功能,这个维度被称为 tags。通过 将字段设置为带标签,Quickwit 将在索引时生成分片元数据,以便在查询时过滤出匹配请求标签的分片。请注意,这种元数据仅在字段基数小于 1,000 时生成。* quickwit.io/docs/config…
标签剪枝在多租户数据集中特别有用。
Partitioning(分区)
Quickwit 可以根据分区键将文档路由到不同的分片中。
此功能尤其适用于不同标签的文档混合在同一来源(通常是 Kafka 主题)的情况。
在这种情况下,仅仅将字段标记为标签对搜索没有积极影响,因为所有产生的分片几乎都包含所有标签。
partition_key 属性(在文档映射中定义)允许您配置 Quickwit 用来将文档路由到隔离分片的逻辑。Quickwit 在合并过程中也会强制执行这种隔离。从某种意义上说,此功能类似于分片。
分区和标签经常用于:
生成大量分片可能会给 indexer 带来巨大压力。因此,文档映射中的另一个参数 max_num_partitions 作为安全阀。如果分区数量接近超过 max_num_partitions,则创建一个额外的分区,并将所有额外分区组合到这个特殊分区中。
如果您期望有 20 个分区,我们强烈建议您不要将 max_num_partitions 设置为 20,而是使用一个较大的值(例如 200)。Quickwit 应该能够平稳地处理这么多分区的数量,并且可以避免由于少数错误的文档而导致属于不同分区的文档被组合在一起。
分区键 DSL
Quickwit 允许您使用简单的 DSL 配置文档的路由方式。以下是一些示例表达式及其结果的简短描述:
分区键 DSL 由以下语法生成:
RoutingExpr := RoutingSubExpr [ , RoutingExpr ]
RougingSubExpr := Identifier [ \( Arguments \) ]
Identifier := FieldChar [ Identifier ]
FieldChar := { a..z | A..Z | 0..9 | _ }
Arguments := Argument [ , Arguments ]
Argument := { \( RoutingExpr \) | RoutingSubExpr | DirectValue }
# We may want other DirectValue in the future
DirectValue := Number
Number := { 0..9 } [ Number ]
目前支持的函数包括:
当使用 hash_mod 与键元组(如 hash_mod((tenant_id,app_id), 50))时,请注意这可能会将文档路由到一起,从而使标签效果降低。例如,如果 tenant_1,app_1 和 tenant_2,app_2 都被发送到第 1 个分区,而 tenant_1,app_2 被发送到第 2 个分区,则对 tenant_1,app_2 的查询仍然会在第 1 个分区中搜索,因为它会被标记为 tenant_1,tenant_2,app_1 和 app_2。因此,您应该更倾向于使用像hash_mod(tenant_id, 10),hash_mod(app_id, 5) 这样的分区键,这样会生成同样数量的分片,但具有更好的标签。
搜索流查询限制
搜索流查询可能占用大量的 RAM。Quickwit 默认将每个分片的并发搜索流数量限制为 100。您可以通过设置搜索器配置文件中名为 max_num_concurrent_split_streams 的属性值来调整此限制。
Caching(缓存)
Quickwit 在许多地方使用缓存以实现高性能的查询引擎。
Scoring(排序)
Quickwit 支持按 BM25 分数对文档进行排序。为了按分数查询,必须为字段启用 。默认情况下,BM25 排序处于禁用状态以提高查询延迟,但可以通过在查询中将 sort_by 选项设置为 _score 来启用。
Deletes(删除)
Quickwit 通过 支持删除操作。需要注意的是,此功能主要用于遵守 GDPR(通用数据保护条例),并且应谨慎使用,因为删除操作成本较高:通常建议每小时或每天执行几次查询即可。
Delete tasks(删除任务)
针对特定索引的删除任务将在删除任务创建之前创建的所有分片上执行。如果删除查询匹配多个分片中的文档,这可能是一个持续很长时间的任务,可能需要几个小时。
为了跟踪执行进度,每个删除任务都会分配一个唯一的递增标识符,称为“操作戳记”或 opstamp。所有现有分片都将接受删除操作,并且在成功后,每个分片的元数据将更新为相应的操作戳记。
在删除任务创建之后创建的所有分片将具有大于或等于删除任务 opstamp 的 opstamp(如果有其他删除任务同时创建,则更大)。
Quickwit 对给定分片批量执行删除操作:例如,如果某个分片的删除 opstamp = n,而最新创建的删除任务的 opstamp = n + 10,那么将在该分片上一次性执行十个(10)删除查询。
Delete API
删除任务通过 创建。
Pitfalls(常见问题)Immature splits(不成熟的分片)
删除操作仅应用于“成熟的”分片,即不再进行合并的分片。分片是否成熟取决于 。可以定义 maturation_period,在此期间之后分片将变为成熟。因此,在 t0 时刻创建的删除请求将首先应用于成熟的分片,并且在最坏的情况下,将等待至 t0 + maturation_period 时刻,让不成熟的分片变得成熟。
Monitoring and dev XP(监控和开发体验)
目前无法监控删除操作。已有一个 issue 开启以改善开发体验,欢迎添加您的评论并关注其进展。