概述
Solr包含一个开发者API和工具,用于在Solr服务及其各种组件的整个生命周期中收集详细的面向性能的指标。
内部使用 Dropwizard Metrics API,它使用以下类别的计量器来测量事件:
- counters(计数器):简单地计算事件数量。提供单个长整型值,例如请求数量
- meters(计量器):额外计算事件速率。提供计数(如上)和1分钟、5分钟、15分钟指数衰减率,类似于Unix系统负载平均值
- histograms(直方图):根据事件值计算事件的近似分布。提供类似指数衰减的近似统计:平均值(算术平均)、中位数、最大值、最小值、标准差和75%、95%、98%、99%和99.9%百分位数
- timers(计时器):测量事件数量和持续时间。提供计数和时间直方图
- gauges(测量器):提供当前值的即时读数,例如当前队列深度、当前活动连接数、空闲堆大小
指标注册表
Solr包含多个指标注册表,用于分组相关指标。指标在组件的整个生命周期中维护和累积,从进程开始直到关闭。例如,特定SolrCore的指标通过多个加载、卸载和/或重命名操作进行跟踪,仅在核心被明确删除时才删除。但是,指标不会在进程重启后持续存在;重启Solr将丢弃所有收集的指标。
JVM注册表
此注册表在 solr.jvm
返回,包含以下信息。在使用Metrics API请求时,可以指定 &group=jvm
来限制仅获取这些指标。
包含的指标:
- 直接和映射缓冲池
- 类加载/卸载
- 操作系统内存、CPU时间(纳秒)、文件描述符、交换、系统负载
- GC计数和时间
- 堆、非堆内存和GC池
- 线程数量、状态和死锁
- 系统属性,如Java信息、各种安装目录路径、端口和类似信息(可通过修改
solr.xml
控制显示内容)
Overseer注册表
此注册表在SolrCloud模式下运行时在 solr.overseer
返回,包含以下信息。使用Metrics API时,可以指定 &group=overseer
来限制仅获取这些指标。
包含的指标:
- Overseer队列大小(集合工作队列和集群状态更新队列)
Node/CoreContainer注册表
此注册表在 solr.node
返回,包含以下信息。使用Metrics API时,可以指定 &group=node
来限制仅获取这些指标。
包含的指标:
- 处理程序请求(计数、计时):集合、信息、管理、配置集等
- 核心数量(已加载、延迟、未加载)
Core(SolrCore)注册表
Core注册表包括 solr.core.<collection>
,每个核心一个。使用Metrics API时,可以指定 &group=core
来限制仅获取这些指标。
包含的指标:
- 所有常见RequestHandler报告:请求计时器/计数器、超时、错误
- 支持处理分布式分片请求的处理程序还报告每种分布式请求类型的
shardRequests
子计数器 - 索引级事件:小型/大型合并的计量器、合并文档数量、删除文档数量、当前运行合并及其大小的测量器
- 分片复制和副本上的事务日志重播
- 分片处理程序和更新处理程序的打开/可用/挂起连接
节点级指标聚合
RequestHandler可以配置为将核心级指标汇总到节点级,除了按核心报告外。如果每个节点有大量核心且对每个节点的聚合指标感兴趣,这很有用。通过在solrconfig.xml的RequestHandler配置中添加 <bool name="aggregateNodeLevelMetricsEnabled">true</bool>
来配置:
1 | <requestHandler name="/select" class="solr.SearchHandler"> |
Jetty注册表
此注册表在 solr.jetty
返回,包含以下信息。使用Metrics API时,可以指定 &group=jetty
来限制仅获取这些指标。
包含的指标:
- 线程和池
- 连接和请求计时器
- 按HTTP类别(1xx、2xx等)的响应计量器
指标配置
可以通过修改 solr.xml
中的 <metrics>
元素来自定义系统中可用的指标。
禁用指标收集
solr.xml
中的 <metrics>
元素支持一个属性 enabled
,接受布尔值:
1 | <metrics enabled="true"> |
- 默认值:
true
,表示正在收集、处理和报告指标 - 禁用效果:
false
值关闭指标收集和处理,内部所有指标提供者被替换为单例无操作实现,有效移除几乎所有与指标收集相关的开销
隐藏系统属性配置
<hiddenSysProps>
部分允许定义被认为是系统敏感的系统属性,不应通过Metrics API公开。
如果此部分未定义,将使用以下默认配置来隐藏密码和认证信息:
1 | <metrics> |
指标供应商配置
<metrics><suppliers>
部分允许定义自己的指标实现并为其配置参数。
Counter供应商
1 | <counter> |
Meter供应商
1 | <meter> |
clock参数:
user
:使用System.nanoTime()
cpu
:使用当前线程的CPU时间
Histogram供应商
1 | <histogram> |
参数说明:
- reservoir:存储器实现的完全限定类名,默认为
com.codahale.metrics.ExponentiallyDecayingReservoir
- size:存储器大小,默认1028
- alpha:衰减参数,仅对
ExponentiallyDecayingReservoir
有效,默认0.015 - window:窗口大小(秒),仅对
SlidingTimeWindowReservoir
有效,默认300秒
Timer供应商
1 | <timer> |
缺失值处理配置
长期指标值在底层值不可用时仍被报告(例如,IndexReader关闭时的”INDEX.sizeInBytes”)。默认情况下,缺失值报告为null值,这可以通过 <missingValues>
元素配置:
1 | <metrics> |
配置选项:
- nullNumber:遇到缺失(null)数值时使用的值
- notANumber:遇到无效数值时使用的值
- nullString:遇到缺失(null)字符串时使用的值
- nullObject:遇到缺失(null)复杂对象时使用的值
线程指标缓存
JVM组中的线程指标计算可能很昂贵,需要遍历所有线程。可以通过设置高缓存过期间隔(秒)来避免每次调用指标API(group=jvm)时都计算:
1 | <solr> |
报告器配置
报告器配置在 solr.xml
文件的 <metrics><reporter>
部分中指定:
1 | <solr> |
报告器通用参数
name(必需):
- 报告器插件的唯一名称
class(必需):
- 插件的完全限定实现类,必须扩展
SolrMetricReporter
group(可选):
- 一个或多个预定义组(如
jvm
、jetty
、node
、core
)
registry(可选):
- 一个或多个有效的完全限定注册表名称
period(可选,默认60秒):
- 报告之间的时间间隔(秒)
prefix(可选,默认空字符串):
- 添加到指标名称的前缀,可能有助于相关Solr实例的逻辑分组
filter(可选):
- 如果不为空,只有以此值开头的指标名称将被报告
JMX报告器
使用 org.apache.solr.metrics.reporters.SolrJmxReporter
类。
1 | <reporter name="jmx" group="jvm,jetty,node,core" class="org.apache.solr.metrics.reporters.SolrJmxReporter"> |
特定参数:
- domain:JMX域名。如果未指定,将使用注册表名称
- serviceUrl:JMX服务器的服务URL。如果未指定,Solr将尝试发现JVM是否有MBean服务器
- agentId:JMX服务器的代理ID。注意
serviceUrl
或agentId
可以指定但不能同时指定
对象名称层次结构(从上到下):
- 注册表名称(如
solr.core.collection1.shard1.replica1
) - 报告器名称
- 请求处理器的类别、范围和名称
- 或来自其他组件的附加名称元素
SLF4J报告器
使用 org.apache.solr.metrics.reporters.SolrSlf4jReporter
类。
1 | <reporter name="slf4j" group="core" class="org.apache.solr.metrics.reporters.SolrSlf4jReporter"> |
特定参数:
- logger:要使用的日志记录器名称。默认为空,这种情况下将使用组名(如果在插件配置中指定)
日志格式示例:
1 | type=COUNTER, name={}, count={} |
Log4j配置示例:
1 | <Configuration> |
Graphite报告器
使用 org.apache.solr.metrics.reporters.SolrGraphiteReporter
类,与 Graphite 集成。
1 | <reporter name="graphite" group="node,jvm" class="org.apache.solr.metrics.reporters.SolrGraphiteReporter"> |
特定参数:
- host(必需):Graphite服务器运行的主机名
- port(必需):服务器端口号
- pickled(默认false):如果为true,使用可能更高效的”pickled” Graphite协议
输出格式(plain-text协议):
1 | dot.separated.metric.name[.and.attribute] value epochTimestamp |
示例输出:
1 | example.solr.node.cores.lazy 0 1482932097 |
核心级指标
索引合并指标
这些指标在每个核心的相应注册表中收集(如 solr.core.collection1....
),在 INDEX
类别下。
基础配置:
1 | <config> |
详细配置:
1 | <config> |
收集的指标:
INDEX.merge.major
:包含至少”majorMergeDocs”(默认512k文档)的合并操作计时器INDEX.merge.minor
:包含少于”majorMergeDocs”的合并操作计时器INDEX.merge.errors
:合并错误计数器INDEX.flush
:索引刷新操作计量器
运行状态测量器:
INDEX.merge.major.running
:运行中的大型合并操作数量INDEX.merge.minor.running
:运行中的小型合并操作数量INDEX.merge.major.running.docs
:大型合并操作中当前合并的文档总数INDEX.merge.minor.running.docs
:小型合并操作中当前合并的文档总数INDEX.merge.major.running.segments
:大型合并操作中当前合并的段数量INDEX.merge.minor.running.segments
:小型合并操作中当前合并的段数量
详细指标(mergeDetails=true):
INDEX.merge.major.docs
:大型合并操作中合并的文档数量计量器INDEX.merge.major.deletedDocs
:大型合并操作中删除的文档数量计量器
Metrics API
admin/metrics
端点提供对所有指标组的所有指标的访问。
查询参数
group
- 默认值:
all
- 说明:要检索的指标组。值
all
检索所有组的所有指标 - 可选值:
jvm
、jetty
、node
、core
- 示例:
group=jvm,core
type
- 默认值:
all
- 说明:要检索的指标类型
- 可选值:
counter
、gauge
、histogram
、meter
、timer
- 示例:
type=timer,counter
prefix
- 默认值:无
- 说明:指标名称的前缀字符,过滤返回以提供字符串开头的指标
- 示例:
prefix=QUERY,UPDATE
regex
- 默认值:无
- 说明:匹配指标名称的正则表达式
- 注意:指标名称中的点分隔符必须转义
- 示例:
regex=QUERY\./select\..*
property
- 默认值:无
- 说明:允许从任何复合指标中只请求此指标
- 示例:
property=p99_ms&property=p999_ms
key
- 默认值:无
- 说明:完全限定的指标名称,指定一个具体的指标实例
- 格式:
registry_name:metric_name:property
- 示例:
key=solr.node:CONTAINER.fs.totalSpace
key=solr.core.collection1:QUERY./select.requestTimes:max_ms
expr
- 默认值:无
- 说明:key选择标准的扩展表示法,支持正则表达式
- 格式:
registry_pattern:metric_pattern:property_pattern
- 示例:
expr=solr\.core\..*:QUERY\..*\.requestTimes:max_ms
expr=solr\.jvm:system\.properties:user\..*
compact
- 默认值:
true
- 说明:当为
false
时,返回更详细的响应格式
API使用示例
请求计数器类型指标:
1 | http://localhost:8983/solr/admin/metrics?type=counter&group=core |
请求以”INDEX”开头的核心组指标:
1 | http://localhost:8983/solr/admin/metrics?wt=xml&prefix=INDEX&group=core |
请求以”.requests”结尾的核心组指标:
1 | http://localhost:8983/solr/admin/metrics?regex=.*\.requests&group=core |
请求特定系统属性:
1 | http://localhost:8983/solr/admin/metrics?key=solr.jvm:system.properties:user.name |
请求查询速率(非直方图):
1 | http://localhost:8983/solr/admin/metrics?expr=solr\.core\..*:QUERY\..*\.requestTimes:.*Rate |
Prometheus格式输出:
1 | http://localhost:8983/solr/admin/metrics?wt=prometheus |
监控最佳实践
指标选择策略
关键性能指标:
- 查询响应时间(
QUERY.*.requestTimes
) - 更新响应时间(
UPDATE.*.requestTimes
) - 错误率(
*.errors
) - 吞吐量(
*.requests
)
- 查询响应时间(
资源使用指标:
- JVM堆使用情况(
jvm.memory.heap.*
) - GC指标(
jvm.gc.*
) - 线程指标(
jvm.threads.*
) - 磁盘使用情况(
CORE.indexDir
)
- JVM堆使用情况(
集群健康指标:
- 核心状态(
node.cores.*
) - 分片状态指标
- 复制延迟指标
- 核心状态(
报告器配置建议
开发环境:
- 主要使用JMX报告器便于调试
- 启用详细的SLF4J日志记录
生产环境:
- 使用Graphite或Prometheus进行长期存储
- 配置适当的过滤器减少噪音
- 设置合理的报告周期(通常60-300秒)
监控告警:
- 基于关键指标设置告警阈值
- 配置多级告警(警告、严重、紧急)
- 建立监控仪表板和可视化
性能优化
指标收集开销:
- 在资源受限环境中考虑禁用某些指标
- 使用过滤器减少不必要的指标收集
- 合理设置缓存间隔
报告效率:
- 避免过于频繁的报告周期
- 使用prefix和filter减少传输数据量
- 选择合适的报告器协议
存储优化:
- 定期清理历史指标数据
- 使用数据聚合减少存储需求
- 配置合适的数据保留策略
通过合理配置和使用Solr的指标监控系统,可以实现对SolrCloud集群的全面监控,及时发现性能问题并进行优化调整,确保系统的稳定性和高效性。