别名
SolrCloud 能够通过备用名称查询一个或多个集合。这些集合的备用名称称为别名,当您想要执行以下操作时,它们非常有用
-
通过重新定义别名,以零停机时间自动切换到使用新(重新)索引的集合
-
在客户端编程中隔离集合名称的更改
-
针对具有相同架构的多个集合发出单个查询
有两种类型的别名:标准别名和路由别名。在路由别名中,有两种类型:类别路由别名和时间路由别名。本节中将讨论这些类型。
可以将集合更新命令发送到别名,但只能发送到解析为单个集合的别名或定义多个集合之间路由的别名(路由别名)。在其他情况下,由于没有用于在多个集合中分发文档的逻辑,因此更新命令将被拒绝并显示错误。
标准别名
使用 CREATEALIAS 命令创建和更新标准别名。
可以通过 CLUSTERSTATUS 命令验证当前属于别名的集合列表。
可以通过 LISTALIASES 命令验证所有别名的完整定义,包括有关该别名的元数据(在路由别名的情况下,请参见下文)。
或者,可以通过使用本机 ZooKeeper 客户端或管理员 UI 中云菜单的 树形视图 页面检查 ZooKeeper 中的 /aliases.json
来获取此信息。
可以通过 DELETEALIAS 命令删除别名。在删除别名时,基础集合不受影响。
引用多个集合的任何别名(标准别名或路由别名)都可能使相关性复杂化。默认情况下,SolrCloud 根据每个分片的评分对文档进行评分。 在别名中有多个集合时,这始终是一个问题,因此,如果您有对 BM25 或 TF/IDF 相关性很重要的用例,则需要启用其中一个 ExactStatsCache 实现。 然而,对于根据数字、日期或字母数字字段值(而非相关性计算)对结果进行排序的分析用例,这不是问题。 |
路由别名
为了解决与标准别名相关的更新限制并提供其他有用的功能,已经开发了路由别名的概念。目前有两种类型的路由别名:时间路由和类别路由。这些将在下面详细描述,但它们有一些共同的行为。
在处理路由别名的更新时,Solr 会像往常一样初始化其更新请求处理器链,但是当DistributedUpdateProcessor
(DUP) 初始化时,它会检测到更新的目标是路由别名,并在其前面注入RoutedAliasUpdateProcessor
(RAUP)。RAUP 与 Overseer 协调,是路由别名的主要部分,并且必须紧接在 DUP 之前。无法在 RAUP 和 DUP 之间配置带有其他类型的 UpdateRequestProcessors 的自定义链。
理想情况下,作为路由别名的用户,您不必关心集合命名模式的具体细节,因为查询和更新都可以通过别名完成。在添加数据时,您通常应该将文档定向到别名(例如,引用别名名称而不是任何集合)。Solr 服务器和CloudSolrClient
会将更新请求定向到别名指向的第一个集合。一旦服务器收到数据,它将执行必要的路由。
对于所有路由别名,至关重要的是路由值不要更改。使用不同的路由值为同一 ID 重新索引文档会产生两个具有相同 ID 的不同文档,可以通过别名访问。一旦存在重复的 ID,路由别名的所有查询时间行为都是未定义的且不易预测。 |
对路由别名使用“数据驱动”模式(又名无模式模式)是一个坏主意,因为重复的模式突变可能会同时发生,从而导致错误。 |
时间路由别名
时间路由别名 (TRA) 是一项 SolrCloud 功能,用于管理别名和按时间顺序排列的一系列集合。
它会自动创建新集合,并(可选)删除旧集合,因为它会根据文档的时间戳将其路由到正确的集合。这种方法允许无限期地索引数据,而不会出现由于单个索引的持续增长而导致的性能下降。
如果您需要在 Solr 中存储大量带时间戳的数据,例如日志或物联网传感器数据,那么此功能可能比创建一个分片哈希路由集合更有意义。
工作原理
首先,使用具有所需路由器设置的CREATEALIAS命令创建一个时间路由别名。大多数设置稍后可以使用ALIASPROP命令进行编辑。
第一个集合将自动创建,并指向它的别名。集合中每个底层 Solr “核心”都是 TRA 成员,它具有一个引用别名的特殊核心属性。每个集合的名称由 TRA 名称和开始时间戳(UTC)组成,尾随的零和符号被截断。
TRA 的集合列表始终按相反顺序排序,因此请求的连接路径将路由到引导集合。建议使用 CloudSolrClient
,因为它可以将底层物理 HTTP 请求的数量减少一个。如果您知道要传递的特定文档集将进入特定的旧集合,那么您可以从客户端将其直接定向到那里作为优化,但这不是必需的。CloudSolrClient
(目前)不执行此操作。
RAUP 在初始化时首先从别名属性中读取 TRA 配置。当它看到每个文档时,它会检查 TRA 属性的更改,根据需要更新其缓存的配置,然后确定文档属于哪个集合
-
如果 RAUP 需要将其发送到由其他集合(而不是客户端选择用来通信的集合)表示的时间段,那么它将使用与 DUP 共享的机制来执行此操作。一旦文档被转发到正确的集合(即正确的 TRA 时间段),它将直接跳到目标集合上的 DUP 并正常继续,可能会再次路由到目标集合中的正确分片和副本。
-
如果它属于当前集合(如果在事件发生时处理事件,通常是这种情况),则文档将传递到 DUP。DUP 执行其正常的集合级处理,可能涉及将文档路由到另一个分片和副本。
-
如果文档上的时间戳比最近的 TRA 段更近,则需要在 TRA 的前面添加一个新集合。RAUP 将创建此集合,将其添加到别名,然后将文档转发到它刚刚创建的集合。如果需要创建多个集合,则此操作可以递归进行。
每次添加一个新集合时,都会检查 TRA 中最旧的集合是否可以删除(如果已配置)。所有这些都同步发生,可能会将几秒钟添加到更新请求和索引延迟中。
如果配置了
router.preemptiveCreateMath
,并且文档在此窗口内到达,那么它将异步发生。有关更多信息,请参阅时间路由别名参数。
RAUP 将任何其他类型的更新(如提交或删除)路由到所有集合。一般来说,这不是性能问题。当 Solr 收到删除或提交(其中没有任何内容被删除或不需要提交任何内容)时,它非常便宜。
类别路由别名
类别路由别名 (CRA) 是一项功能,用于根据单个字段的值管理别名和一组相关集合。
CRA 会自动创建新集合,但由于分区基于分类信息而不是连续的基于数字的值,因此没有自动删除的逻辑。此方法允许简化必须出于集群管理或安全原因而隔离到集合中的数据的索引。
工作原理
首先,使用具有所需路由器设置的 CREATEALIAS 命令创建类别路由别名。大多数设置稍后可以使用 ALIASPROP 命令进行编辑。
别名将使用特殊占位符集合创建,该集合始终命名为myAlias__CRA__NEW_CATEGORY_ROUTED_ALIAS_WAITING_FOR_DATA__TEMP
。索引到 CRA 中的第一个文档将创建一个名为myAlias__CRA__foo
的第二个集合(对于路由字段值为foo
)。索引的第二个文档将导致临时占位符集合被删除。此后,每当遇到该字段的新值时,都会创建集合。
为了防止失控的集合创建选项限制类别总数,并拒绝不匹配的值,提供了正则表达式参数(有关详细信息,请参见类别路由别名参数)。 |
+ 请注意,通过为这些选项提供非常大或非常宽松的值,您接受了这样一个风险,即混乱的数据可能会创建数千个集合并使您的集群陷入停滞。
字段值(以及集合名称)区分大小写。
与 Solr 中的其他地方一样,在将数据发送到 Solr 之前,外部进程应负责处理和清理数据,但有一个例外。在 Solr 中,集合名称中允许的字符受到限制。在计算类别的集合名称时,除 ASCII 字母数字字符(A-Za-z0-9
)、连字符(-
)或下划线(_
)之外的任何字符都将替换为下划线。对于名为myAlias
的 CRA,下表显示了如何计算集合名称
值 | CRA 集合名称 |
---|---|
foo |
myAlias__CRA__foo |
Foo |
myAlias__CRA__Foo |
foo bar |
myAlias__CRA__foo_bar |
FOÓB&R |
myAlias__CRA__FO_B_R |
中文的东西 |
myAlias__CRA_______ |
foo__CRA__bar |
导致 400 个错误请求 |
<null> |
导致 400 个错误请求 |
由于集合创建可能需要 1-3 秒以上,因此在 CRA 中插入数据的系统应构建为在每次创建新集合时处理此类暂停。与时间路由别名不同,无法预测下一个值,因此此类暂停是不可避免的。
没有自动方法来删除类别。如果需要从 CRA 中删除类别,建议执行以下过程
-
确保不会发送任何与要删除的类别对应的值的文档,方法是停止索引或修复传入的数据流
-
修改 ZooKeeper 中的别名定义,删除与该类别对应的集合。
-
删除与该类别对应的集合。请注意,如果该集合未首先从别名中删除,此步骤将失败。
维度路由别名
对于所需的数据分离与两个字段相关且在索引期间将它们组合成一个字段不切实际,或者在多个类别中需要 TRA 行为的情况,可以使用维度路由别名。此功能旨在处理任意数量和类别和时间维度的组合,但建议用户仔细考虑此类配置将产生的集合总数。ZooKeeper 中的集合计数在数百或数千个高位时开始构成重大挑战。
DRA 是一个新功能,目前仅支持 2 个维度。未来将支持更多维度(请参阅 https://issues.apache.org/jira/browse/SOLR-13628 以了解进度) |
工作原理
首先,您需要使用每个维度的所需路由器设置创建一个维度路由别名。有关如何指定每个维度配置的详细信息,请参阅 CREATEALIAS 命令文档。典型的集合名称将采用以下形式(示例是类别 x 时间示例,间隔为 30 分钟)
myalias__CRA__someCategory__TRA__2019-07-01_00_30
请注意,初始集合将是包含基于类别的维度的任何 DRA 的一次性占位符。集合名称的每个子部分的名称生成与组件维度类型的相应部分相同(例如,生成CRA 或TRA 的类别值仍会产生错误)。
关于使用不同的路由值重新索引文档的先前警告适用于 DRA 的每个维度。DRA 不适用于在路由中使用的类别或时间戳将更改的文档(当然,这也适用于未来其他 RA 类型中的其他路由值)。 |
与所有路由别名一样,如果您的数据表现不佳,DRA 会带来一些成本。除了每个组件维度通常的注意事项之外,还需要小心在 DRA 运行一段时间后发送新类别。有序维度(时间)的行为与无序(类别)维度略有不同。有序维度依赖于别名中集合的迭代顺序,因此无法容忍按顺序生成集合名称。这意味着,当时间等有序维度是 DRA 的组件,并且 DRA 收到具有与时间维度起始时间段不同的时间值的某个新类别的文档时,需要创建多个集合才能对文档建立索引。此“新类别效应”与您在过去选择开始日期时使用 TRA 所获得的行为相同。
例如,给定一个开始时间为 2019-07-01T00:00:00Z 的 Dimensional[time,category] DRA,为 4 个文档创建的集合模式可能如下所示
无文档
别名集合
myalias__TRA__2019-07-01__CRA__NEW_CATEGORY_ROUTED_ALIAS_WAITING_FOR_DATA_TEMP
文档 1
-
时间:2019-07-01T00:00:00Z
-
类别:someCategory
别名集合
myalias__TRA__2019-07-01__CRA__NEW_CATEGORY_ROUTED_ALIAS_WAITING_FOR_DATA_TEMP
myalias__TRA__2019-07-01__CRA__someCategory
文档 2
-
时间:2019-07-02T00:04:00Z
-
类别:otherCategory
别名集合
myalias__TRA__2019-07-01__CRA__someCategory
myalias__TRA__2019-07-01__CRA__otherCategory // 2 collections created in one update
myalias__TRA__2019-07-02__CRA__otherCategory
文档 3
-
时间:2019-07-03T00:12:00Z
-
类别:thirdCategory
别名集合
myalias__TRA__2019-07-01__CRA__someCategory
myalias__TRA__2019-07-01__CRA__otherCategory
myalias__TRA__2019-07-02__CRA__otherCategory
myalias__TRA__2019-07-01__CRA__thirdCategory // 3 collections created in one update!
myalias__TRA__2019-07-02__CRA__thirdCategory
myalias__TRA__2019-07-03__CRA__thirdCategory
文档 4
-
时间:2019-07-03T00:12:00Z
-
类别:someCategory
别名集合
myalias__TRA__2019-07-01__CRA__someCategory
myalias__TRA__2019-07-01__CRA__otherCategory
myalias__TRA__2019-07-02__CRA__otherCategory
myalias__TRA__2019-07-01__CRA__thirdCategory
myalias__TRA__2019-07-02__CRA__thirdCategory
myalias__TRA__2019-07-03__CRA__thirdCategory
myalias__TRA__2019-07-02__CRA__someCategory // 2 collections created in one update
myalias__TRA__2019-07-03__CRA__someCategory
因此,DRA 的最佳点是数据集具有不会更改且所有排列定期发生的标准化维度集。如果稍后引入新类别且索引延迟是重要的 SLA 功能,则有几种策略可以减轻此影响
-
如果要创建的额外时间段数量不大,则可以发送单个文档以脱离常规索引,并在允许通过 SLA 约束流程发送新类别之前等待集合创建完成。
-
如果上述过程可能创建大量集合,并且已知新类别中最早可能的文档,则可以使用 ALIASPROP 命令调整时间维度的开始时间
改进可能性
路由别名是 SolrCloud 的一项相对较新的功能,可以预期会得到改进。一些潜在的改进领域尚未实现
-
TRA:带有时间过滤器的搜索只应转到适用的集合。
-
TRA:自动优化(或减少资源)预计不会接收更多更新且搜索需求可能较低较旧集合的方法。
-
CRA:通过 Base64 编码对非英语文本提供内在支持。
-
CRA:提供一个初始值列表,用于在事先已知这些值的情况下减少索引期间的暂停。
-
DRA:支持 2 个以上的维度。
-
CloudSolrClient
可以根据路由值将文档路由到正确的集合,而不是始终选择最新/第一个集合。 -
目前,只有更新被路由,查询被分发到别名中的所有集合,但未来的功能可能会基于特殊参数或路由字段的过滤器,将查询路由到单个适当的集合。
-
集合可能受其大小限制,而不是或除了时间或类别值之外。这可能作为另一种类型的路由别名实现,或可能作为现有路由别名上的一个选项实现
-
删除别名的选项,该选项还一步删除底层集合。路由别名可能会在初始测试期间快速创建比预期更多的集合。在这些事件之后删除它们过于繁琐。
一如既往,欢迎补丁和拉取请求!
集合命令和别名
SolrCloud 支持在集合命令中使用别名,在集合命令中通常需要集合名称。仅在满足以下条件时才有效
-
使用请求参数
followAliases=true
-
别名不得引用多个集合
-
别名不得引用路由别名
如果满足所有条件,则命令将解析所有别名并操作别名引用的集合,就像使用集合名称调用它一样。否则,命令将不会执行,并且将抛出异常。
应谨慎使用 followAliases=true
参数,以便解析的目标确实是预期的目标。在多级别名或影子别名(与现有集合同名的别名,但指向其他集合)的情况下,强烈不建议使用此选项,因为可能难以正确预测效果。