副本放置插件

当您创建新集合或向现有集合添加副本时,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"
          }
        }
    }}'
  https://127.0.0.1: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 GB

如果节点的可用磁盘空间严格小于此值(以 GB 为单位),则该节点将从分配决策中排除。设置为 0 或更小以禁用。

prioritizedFreeDiskGB

可选

默认值:100 GB

副本分配会将副本分配给具有至少此数量的可用磁盘空间(以 GB 为单位)的节点,而不考虑这些节点上的内核数量,而不是将副本分配给可用磁盘空间少于此数量的节点(如果有选择的话)(如果没有选择,则仍然可以将副本分配给可用空间少于此数量的节点)。

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"
    }}'
  https://127.0.0.1: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
        }
    }}'
  https://127.0.0.1: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"
          }
        }
    }}'
  https://127.0.0.1:8983/api/cluster/plugin

此配置定义集合 collection_A 必须仅放置在具有 node_type 系统属性(其中包含 searchNodeindexNode)的节点上(例如,可以将节点标记为 -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"
          }
        }
    }}'
  https://127.0.0.1:8983/api/cluster/plugin