熔断器
Solr 的熔断器基础设施允许防止导致节点超出其容量或宕机的操作。熔断器的前提是确保更高质量的服务,并且仅接受当前资源配置下可服务的请求负载。
何时使用熔断器
当用户希望以牺牲请求吞吐量为代价来换取更高的 Solr 稳定性时,应使用熔断器。如果启用了熔断器,则在节点高压力的情况下,可能会拒绝请求,并返回 HTTP 错误代码 429“请求过多”。客户端需要处理此错误,并可能构建重试逻辑,因为这应该是一种瞬态情况。
也可以在“仅警告”模式下启用单个熔断器。已超过阈值的“仅警告”熔断器会被记录下来,但不用于阻止或短路请求。这可以用作在不影响流量的情况下调整熔断器阈值的方法。
在对分片集合的请求中,仅在处理初始请求的节点上检查熔断器,而不对节点间请求进行检查。因此,建议跨 Solr 节点对客户端请求进行负载均衡,以避免热点。
熔断器配置
可以为整个节点全局配置熔断器,也可以为每个集合单独配置熔断器,或者两者结合配置。会先检查每个集合的熔断器,然后再检查全局熔断器,如果发生冲突,则每个集合的熔断器优先。通常,任何每个集合的熔断器阈值都设置得低于全局阈值。
断路器可以注册自身以检查查询请求和/或更新请求。用户可以为每种请求类型注册具有不同阈值的相同类型的断路器。
全局断路器
可以使用环境变量(例如在 solr.in.sh
中)或系统属性全局配置断路器。可用的变量有
名称 | 环境变量名称 | 系统属性名称 |
---|---|---|
JVM 堆使用率 |
|
|
系统 CPU 使用率 |
|
|
系统平均负载 |
|
|
可以通过添加带有布尔值的 "warnonly" 后缀的环境变量或系统属性,将断路器配置为“仅警告”模式。
例如,您可以通过设置以下环境变量启用一个全局 CPU 断路器,当 CPU 负载高于 95% 时拒绝更新请求:SOLR_CIRCUITBREAKER_UPDATE_CPU=95
。如果希望此断路器处于“仅警告”模式,可以设置 SOLR_CIRCUITBREAKER_UPDATE_CPU_WARNONLY=true
环境变量或 solr.circuitbreaker.update.cpu.warnonly=true
系统属性。
当前支持的断路器
自 Solr 9.4 起,使用 |
JVM 堆使用率
此断路器跟踪 JVM 堆内存使用率,如果堆使用率超过 JVM 分配的最大堆 ( -Xmx ) 的配置百分比,则会使用 429 错误代码拒绝传入的请求。此断路器的主要配置是控制断路器跳闸的阈值百分比。
要启用和配置基于 JVM 堆使用率的断路器,请添加以下内容
solrconfig.xml
中<circuitBreaker class="org.apache.solr.util.circuitbreaker.MemoryCircuitBreaker">
<double name="threshold">75</double>
</circuitBreaker>
solr.in.sh
中SOLR_CIRCUITBREAKER_QUERY_MEM=75
threshold
定义为 JVM 分配的最大堆的百分比。
对于断路器配置,值“0”映射到 0% 使用率,值“100”映射到 100% 使用率。
将阈值设置在 JVM 分配的最大堆的 50% 以下或 95% 以上在逻辑上没有意义。因此,此参数的有效值范围是 [50, 95],包括边界值。
考虑以下示例
JVM 已分配了 5GB 的最大堆 (-Xmx),threshold
设置为 75
。在这种情况下,断路器跳闸时的堆使用率为 3.75GB。
系统 CPU 使用率断路器
此断路器跟踪系统 CPU 使用率,如果最近的 CPU 使用率超过可配置的阈值,则会触发。
这是通过 JMX 指标 OperatingSystemMXBean.getSystemCpuLoad()
进行跟踪的。该指标测量整个系统的最近 CPU 使用率。该指标由 com.sun.management
包提供,该包并非在所有 JVM 上都实现。如果该指标不可用,断路器将被禁用并记录错误消息。另一种方法是使用 系统平均负载断路器。
要启用和配置基于 CPU 利用率的断路器
solrconfig.xml
中<circuitBreaker class="org.apache.solr.util.circuitbreaker.CPUCircuitBreaker">
<double name="threshold">75</double>
</circuitBreaker>
solr.in.sh
中SOLR_CIRCUITBREAKER_QUERY_CPU=75
触发阈值以 CPU 使用率的百分比定义。值 “0” 映射到 0% 使用率,值 “100” 映射到 100% 使用率。上面的示例将在 CPU 使用率等于或大于 75% 时触发。
系统平均负载断路器
此断路器跟踪系统平均负载,如果最近的平均负载超过可配置的阈值,则会触发。
这是通过 JMX 指标 OperatingSystemMXBean.getSystemLoadAverage()
进行跟踪的。该指标测量整个系统的最近平均负载。“平均负载”是使用或等待 CPU 的进程数,通常在一分钟内平均得出。某些系统将等待 IO 的进程也包括在平均负载中。请查看您的系统和 JVM 的文档以了解此指标。有关更多信息,请参阅负载维基百科页面。
要启用和配置平均负载断路器
solrconfig.xml
中<circuitBreaker class="org.apache.solr.util.circuitbreaker.LoadAverageCircuitBreaker">
<double name="threshold">8.0</double>
</circuitBreaker>
solr.in.sh
中SOLR_CIRCUITBREAKER_QUERY_LOADAVG=8.0
触发阈值是一个与平均负载匹配的浮点数。上面的示例断路器将在平均负载等于或大于 8.0 时触发。
系统平均负载断路器的行为取决于操作系统,并且可能无法在某些操作系统(如 Microsoft Windows)上运行。有关更多信息,请参阅 JavaDoc。 |
高级示例
在此示例中,我们将阻止 CPU 负载高于 80% 的更新请求,并阻止 CPU 负载高于 95% 的查询请求。支持的请求类型为 query
和 update
。这将防止代价高昂的批量更新影响搜索。另请注意对短形式类名称的支持。
solrconfig.xml
中<config>
<circuitBreaker class="solr.CPUCircuitBreaker">
<double name="threshold">80</double>
<arr name="requestTypes">
<str>update</str>
</arr>
</circuitBreaker>
<circuitBreaker class="solr.CPUCircuitBreaker">
<double name="threshold">95</double>
<arr name="requestTypes">
<str>query</str>
</arr>
</circuitBreaker>
</config>
solr.in.sh
中SOLR_CIRCUITBREAKER_UPDATE_CPU=80
SOLR_CIRCUITBREAKER_QUERY_CPU=95
性能注意事项
虽然 JVM 或 CPU 断路器不会为每个请求增加任何明显的开销,但是对于单个请求检查过多的断路器可能会导致性能开销。
此外,在繁忙的节点上重试请求时,最好使用指数退避策略。请参阅 指数退避维基百科页面。