副本放置插件

创建新集合或向现有集合添加副本时,Solr 首先需要确定将副本放在哪个节点上,以便以平衡良好的方式(根据某些标准)分配集群资源。

副本放置插件是确定这些放置的可配置组件。它还可以对操作(例如集合或副本删除)强制执行其他约束 - 例如,如果插件希望一些集合始终位于同一节点上,或始终在存在其他集合时出现。

在 Solr 的早期版本中,此功能是使用按集合规则或自动缩放框架提供的。

插件配置

副本放置插件配置在 solr.xml 文件 中配置,或使用 /cluster/plugin API。只要没有将副本放置插件定义为集群插件,在 solr.xml 中配置的任何插件都将被使用。一次只能有一个集群范围的插件配置,并且它使用预定义的插件名称:.placement-plugin

Solr 发行版中包含多个放置插件。可以添加其他放置插件 - 它们必须实现 PlacementPluginFactory 接口。如果插件实现了 ConfigurablePlugin 接口,则配置条目还可能包含一个 config 元素。

Solr 附带的放置插件

Solr 9.0 中开箱即用的放置插件如下。如果群集属性中未定义放置插件,Solr 将默认使用系统属性 solr.placementplugin.default 或环境变量 SOLR_PLACEMENTPLUGIN_DEFAULT 中配置的插件。支持的值为 simplerandomaffinityminimizecores。如果未设置此类属性或环境变量,则使用 SimplePlacementPlugin

为了使用插件,必须使用 /cluster/plugin API 添加其配置。例如,为了使用 AffinityPlacementFactory 插件,应执行以下命令

curl -X POST -H 'Content-type: application/json' -d '{
    "add":{
        "name": ".placement-plugin",
        "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory",
        "config": {
          "minimalFreeDiskGB": 20,
          "prioritizedFreeDiskGB": 100,
          "withCollections": {
            "A_primary": "A_secondary",
            "B_primary": "B_secondary"
          },
          "collectionNodeType": {
            "collection_A": "searchNode,indexNode",
            "collection_B": "analyticsNode"
          }
        }
    }}'
  http://localhost:8983/api/cluster/plugin

同样,可以更新或删除配置。

放置插件配置必须使用预定义的名称 .placement-plugin。只能定义一个(或没有)放置配置。

SimplePlacementFactory

默认情况下,Solr 9.0 使用一种用于副本放置的旧方法,即 SimplePlacementFactory。每当放置插件配置缺失或无效时,都会使用此方法。

简单放置只是以循环方式将新副本分配给活动节点:首先,它准备一个按现有副本数最少的节点排序的列表,尤其是集合的副本。然后,对于请求中的每个分片,它按此顺序将副本添加到连续的节点,如果副本数大于节点数,则环绕到第一个节点。

此放置策略不能确保分片的副本不超过 1 个放置在同一节点上。此外,循环分配仅大致近似于副本在节点之间的均匀分布。

在 9.0 之前,这是默认的非自动扩展行为,当时称为 LegacyAssignStrategy。

RandomPlacementFactory

此插件创建随机放置,同时防止同一分片的两个副本放置在同一节点上。如果节点太少以满足这些约束,则会引发异常,并且请求将被拒绝。

由于其简单的算法,此插件应仅用于简单的部署。

此插件不需要任何配置。

MinimizeCoresPlacementFactory

此插件创建放置,以最大程度地减少所有活动节点上的每个节点的核心数,同时不将同一分片的两个副本放置在同一节点上。如果节点太少以满足这些约束,则会引发异常,并且请求将被拒绝。

由于其简单的算法,此插件应仅用于简单的部署。

此插件不需要任何配置。

AffinityPlacementFactory

此插件实现了副本放置算法,该算法大致复制了 此处定义的 Solr 8.x 自动扩展配置。

上述配置中的自动扩展规范旨在执行以下操作

  • 尽可能均匀地跨多个可用区(由系统属性提供)传播每个分片的副本,

  • 根据副本类型将副本分配给特定类型的节点(另一个系统属性),并且

  • 避免在同一节点上为每个分片拥有多个副本。

  • 仅在满足上述约束后

    • 最小化每个节点的核心数,或

    • 最小化磁盘使用量。

它还支持其他每个集合的约束

  • withCollection 强制将共置集合的副本放置在同一节点上,并防止删除集合和副本,这会破坏此约束。

  • withCollectionShards 与上述相同,但也会将分片并置。即 shardN 放置在引用集合中的 shardN 所在的同一节点上。注意:withCollectionShards 的键应与 withCollection 键不相交。

  • collectionNodeType 将符合放置资格的节点限制为仅匹配一个或多个指定节点类型的节点。

请参阅以下内容以了解有关这些约束的更多详细信息。

此插件的总体策略

  • 获取集群中的节点集。如果 withCollectionwithCollectionShards 已定义且适用于当前集合,则此候选集将被筛选,以便仅保留符合此约束的合格节点。

  • 将生成的节点集转换为 3 个独立的节点集(可能重叠),这些节点集接受三种副本类型(NRT、TLOG 和 PULL)中的每一种。

  • 对于需要放置副本的每个分片,然后对于要放置的每个副本类型(从 NRT 开始,然后是 TLOG,然后是 PULL)

    • 使用与副本类型相对应的候选节点集,并从该集中删除已为该分片拥有副本(任何类型)的节点。

    • 如果没有足够的节点,则会引发错误(这将在处理过程中进一步检查)。

    • 收集每个可用区域 (AZ) 上当前类型的(已存在)副本数。

    • 将可用节点集分成与候选节点定义的 AZ 数量一样多的子集(可能有些是空的)

    • 在每个 AZ 节点子集中,按核心总数升序对节点进行排序。

    • 迭代要放置的副本数(对于当前分片的当前副本类型)

      • 根据先前收集的每个 AZ 的副本数,选择具有最少副本数的非空节点集。然后选择该集合中的第一个节点。副本放置在该节点上。从给定 AZ 的可用节点集中删除该节点,并增加放置在该 AZ 上的副本数。

    • 在此过程中,通常会跟踪节点上的核心数,以考虑放置决策,以便并非所有分片都决定将副本放在同一节点上(不过,如果这些节点负载较低,它们可能会这样做)。

目前,可用性区域属性的名称和副本类型属性的名称不可配置,分别设置为 availability_zonereplica_type

配置

此插件支持以下配置参数

minimalFreeDiskGB

可选

默认值:5 千兆字节

如果某个节点的可用磁盘空间低于此值,则该节点将从分配决策中排除。设置为 0 或更低值以禁用。

prioritizedFreeDiskGB

可选

默认值:100 千兆字节

副本分配将把副本分配给具有至少此数量可用磁盘空间的节点,而不管这些节点上的内核数量如何,而不是将副本分配给可用磁盘空间少于此数量的节点(如果这不是一个选项,则副本仍然可以分配给可用空间少于此数量的节点)。

withCollection

可选

默认值:无

定义一个附加约束,即主集合(键)必须位于与次集合(值)相同的节点上。该插件将假定次集合副本已就位,并忽略尚未存在候选节点。

请参阅以下部分 withCollection 约束

withCollectionShards

可选

默认值:无

withCollection 相同,但强制执行分片级别约束。例如,主集合的 shardN(出现在键中)仅放置在次集合的 shardN(作为值出现)所在的节点上。在删除次集合 shardN 的副本时,将强制执行相同的约束。如果主集合的 shardN 与某个节点并置,则它会阻止删除。键应与 withCollection 不相交。

collectionNodeType

可选

默认值:无

此属性定义了一个附加约束,即集合(键)必须仅位于标记有一个或多个匹配“节点类型”标签的节点上(映射中的值是逗号分隔的标签)。使用 node_type 系统属性对节点进行标记,其值是逗号分隔的标签的任意列表。相应地,插件配置可以指定特定的集合必须仅放置在与此处定义的(逗号分隔的)标签中的至少一个匹配的节点上。

withCollection 约束

此插件支持强制执行名为 withCollection 的附加约束,这会导致两个配对集合的副本放置在同一节点上。

用户可以在插件配置中定义集合对,在 config/withCollection 元素中,这是一个 JSON 映射,其中键是主集合名称,值是辅助集合名称。目前仅支持 1:1 映射 - 但是,多个主集合可以使用相同的辅助集合,这实际上将此放松为 N:1 映射。

与 Solr 的以前版本不同,此插件不会自动放置辅助集合的副本 - 假设这些副本已经到位,并且用户负责将它们放在正确的节点上(很可能只是通过使用此插件来首先创建辅助集合,使用足够大的复制因子来确保目标节点集填充有辅助副本)。

当处理对 withCollection 映射中具有键的主集合的放置计算请求时,首先过滤候选节点集以消除不包含辅助集合副本的节点。请注意,这可能会导致一个空集和一个异常 - 在这种情况下,需要首先创建足够数量的辅助副本。

如果辅助集合(或其副本)仍在放置主副本的节点上使用,则插件通过拒绝辅助集合(或其副本)的删除操作来保留此共置 - 执行此操作的请求将被拒绝并出现错误。为了从这些节点删除辅助集合(或其副本),必须先从共置节点中删除主集合的副本,或者必须更改配置以删除主集合的共置映射。

示例配置

这是一个使用默认值的简单配置

curl -X POST -H 'Content-type: application/json' -d '{
    "add":{
        "name": ".placement-plugin",
        "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory"
    }}'
  http://localhost:8983/api/cluster/plugin

此配置指定基本参数

curl -X POST -H 'Content-type: application/json' -d '{
    "add":{
        "name": ".placement-plugin",
        "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory",
        "config": {
          "minimalFreeDiskGB": 20,
          "prioritizedFreeDiskGB": 100
        }
    }}'
  http://localhost:8983/api/cluster/plugin

此配置定义集合 A_primary 必须与集合 Common_secondary 共置,集合 B_primary 也必须与集合 Common_secondary 共置

curl -X POST -H 'Content-type: application/json' -d '{
    "add":{
        "name": ".placement-plugin",
        "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory",
        "config": {
          "withCollection": {
            "A_primary": "Common_secondary",
            "B_primary": "Common_secondary"
          }
        }
    }}'
  http://localhost:8983/api/cluster/plugin

此配置定义集合 collection_A 必须仅放置在具有包含 searchNodeindexNodenode_type 系统属性的节点上(例如,节点可能标记为 -Dnode_type=searchNode,indexNode,uiNode,zkNode)。同样,集合 collection_B 必须仅放置在包含 analyticsNode 标签的节点上

curl -X POST -H 'Content-type: application/json' -d '{
    "add":{
        "name": ".placement-plugin",
        "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory",
        "config": {
          "collectionNodeType": {
            "collection_A": "searchNode,indexNode",
            "collection_B": "analyticsNode"
          }
        }
    }}'
  http://localhost:8983/api/cluster/plugin