使用 Prometheus 和 Grafana 进行监控

如果您使用 PrometheusGrafana 进行指标存储和数据可视化,Solr 提供了 2 种解决方案来收集指标和其他数据

  • Prometheus Exporter

  • 带有 Prometheus 格式的 Metrics API

Prometheus exporter 包含在完整的 Solr 发行版中,位于 prometheus-exporter/ 下。它不包含在 slim Solr 发行版中。

Prometheus exporter (solr-exporter) 允许用户不仅监控来自 Metrics API 的 Solr 指标,还监控来自 刻面 的刻面计数以及对 集合 API 命令和 Ping 请求的响应。

Metrics API 提供了一个 Prometheus 响应写入器,用于以原生方式输出 Solr 指标以进行抓取。它更高效,并且无需运行 Prometheus Exporter,但代价是输出固定,并且在可配置性方面不够灵活。

Prometheus Exporter

此图提供了更详细的视图

image
图 1. solr-exporter 图

运行 solr-exporter 有三个方面

  • 修改 solr-exporter-config.xml 以定义要收集的数据。Solr 具有您可以使用的默认配置,但是如果您想在首次运行导出器之前对其进行修改,请参阅下面的 导出器配置 部分。

  • 从 Solr 内部启动导出器。请参阅下面的 启动导出器 部分。

  • 修改您的 Prometheus 配置以侦听正确的端口。请参阅下面的 Prometheus 配置 部分

启动导出器

您可以通过从 prometheus-exporter/ 目录运行 ./bin/solr-exporter (Linux) 或 .\bin\solr-exporter.cmd (Windows) 来启动 solr-exporter

可以通过指标端点查看 solr-exporter 公开的指标:https://127.0.0.1:8983/solr/admin/metrics

请参阅以下命令,具体取决于您的操作系统和 Solr 操作模式

  • Linux

  • Windows

用户管理 / 单节点
$ cd prometheus-exporter
$ ./bin/solr-exporter -p 9854 -b https://127.0.0.1:8983/solr -f ./conf/solr-exporter-config.xml -n 8
SolrCloud
$ cd prometheus-exporter
$ ./bin/solr-exporter -p 9854 -z localhost:2181/solr -f ./conf/solr-exporter-config.xml -n 16
用户管理 / 单节点
> cd prometheus-exporter
> .\bin\solr-exporter.cmd -p 9854 -b https://127.0.0.1:8983/solr -f .\conf\solr-exporter-config.xml -n 8
SolrCloud
> cd prometheus-exporter
> .\bin\solr-exporter -p 9854 -z localhost:2181/solr -f .\conf\solr-exporter-config.xml -n 16

命令行参数

Prometheus Exporter 的可用参数列表。所有参数都可以通过环境变量提供,而不是通过命令行提供。

h, --help

可选

默认值:无

显示命令行帮助和用法。

-p, --port, $PORT

可选

默认值:8989

Prometheus 监听新数据的端口。此端口将用于配置 Prometheus。它可以是服务器上任何未被占用的端口。

-b, --baseurl, $SOLR_URL

可选

默认值:请参阅描述

Solr 基本 URL(例如 https://127.0.0.1:8983/solr),当 Solr 在用户管理的集群或单节点安装中运行时。 如果您正在运行 SolrCloud,请不要指定此参数。 如果未定义 -b 参数和 -z 参数,则默认值为 -b https://127.0.0.1:8983/solr

-z, --zk-host, $ZK_HOST

可选

默认值:请参阅描述

ZooKeeper 连接字符串(例如 localhost:9983localhost:2181/solr),当 Solr 正在运行 SolrCloud 时。如果您正在运行用户管理的集群或单节点安装,请不要指定此参数。如果未定义 -b 参数和 -z 参数,则使用 -b 参数的默认值。

-f, --config-file, $CONFIG_FILE

可选

默认值:prometheus-exporter/conf/solr-exporter-config.xml

定义要读取的 Solr 指标的配置文件的路径。

-n, --num-threads, $NUM_THREADS

可选

默认值:1

线程数。solr-exporter 为 Solr 的请求创建线程池。 可以通过增加线程数来改善请求延迟。

-s, --scrape-interval, $SCRAPE_INTERVAL

可选

默认值:60

从 Solr 收集指标的间隔秒数。 solr-exporter 每隔几秒从 Solr 收集指标,此设置控制收集频率。 这些指标会被缓存,并且无论 Prometheus 配置为从该工具拉取指标的频率如何,都会返回这些指标。 可以通过减少抓取间隔来提高指标的新鲜度,但不要将其设置为非常低的值,因为指标收集可能代价高昂,并且可能会执行任意搜索以 ping Solr。

-i, --cluster-id, $CLUSTER_ID

可选

默认值:请参阅描述

要监视的集群的唯一 ID。此 ID 将作为标签 cluster_id 添加到所有指标,如果您操作多个向同一 Prometheus 实例报告的 Solr 集群,则可以在 Grafana 仪表板中将其用作过滤器。如果省略此选项,则默认情况下将使用 baseUrlzkHost 的哈希值作为 ID。

-u, --credentials, $CREDENTIALS

可选

默认值:无

username:password 格式指定凭据。示例:--credentials solr:SolrRocks

-ssl, --ssl-enabled, $SSL_ENABLED

可选

默认值:false

启用与 Solr 的 mTLS 连接。 需要以下环境变量:SOLR_SSL_KEY_STORE、SOLR_SSL_KEY_STORE_PASSWORD、SOLR_SSL_TRUST_STORE、SOLR_SSL_TRUST_STORE_PASSWORD。示例:--ssl-enabled 环境变量与 Solr 用于启用 mTLS 的环境变量相同。

环境变量选项

Prometheus Exporter 提供的 ./bin 脚本通过以下环境变量支持自定义 java 选项

JAVA_HEAP

可选

默认值:512m

设置初始 (Xms) 和最大 (Xmx) Java 堆大小。

JAVA_MEM

可选

默认值:无

自定义 Java 内存设置(例如,-Xms1g -Xmx2g)。如果提供了 JAVA_HEAP,则忽略此设置。

GC_TUNE

可选

默认值:-XX:+UseG1GC

自定义 Java 垃圾回收设置。

JAVA_OPTS

可选

默认值:无

额外的 JVM 选项。

ZK_CREDS_AND_ACLS

可选

默认值:无

连接到受 ACL 保护的 ZooKeeper 主机的凭据。有关此变量中应包含的内容的更多信息,请参阅Solr CLI 中的 ZooKeeper ACL部分或以下从安全的 SolrCloud 获取指标示例。

CLASSPATH_PREFIX

可选

默认值:无

启动 solr-exporter 时要加载的额外库的位置。

所有命令行参数在使用 ./bin 脚本时都可以通过环境变量提供。

从安全的 SolrCloud 获取指标

可以使用环境变量将您的 SolrCloud 安全配置注入到 solr-exporter 中,方式类似于其他使用 SolrJ 的客户端。这是可行的,因为主脚本会拾取环境变量选项并将它们传递给 Java 进程。

以下示例假定一个受基本身份验证插件SSLZooKeeper 访问控制保护的 SolrCloud 实例。

假设您有一个包含 Solr 基本身份验证凭据的文件 basicauth.properties

httpBasicAuthUser=myUser
httpBasicAuthPassword=myPassword

然后,您可以按如下方式启动 Exporter(Linux)。

$ cd prometheus-exporter
$ export JAVA_OPTS="-Djavax.net.ssl.trustStore=truststore.p12 -Djavax.net.ssl.trustStorePassword=truststorePassword -Dsolr.httpclient.builder.factory=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory -Dsolr.httpclient.config=basicauth.properties"
$ export ZK_CREDS_AND_ACLS="-DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider -DzkDigestUsername=readonly-user -DzkDigestPassword=zkUserPassword"
$ export CLASSPATH_PREFIX="../server/solr-webapp/webapp/WEB-INF/lib/commons-codec-1.11.jar"
$ ./bin/solr-exporter -p 9854 -z zk1:2181,zk2:2181,zk3:2181 -f ./conf/solr-exporter-config.xml -n 16
注意

Exporter 需要 commons-codec 库用于 SSL/基本身份验证,但它没有自带。因此,该示例重用了 Solr Web 应用中的该库。当然,您可以使用其他来源。

Exporter 配置

solr-exporter 的配置定义了从 Solr 获取的数据。 这包括指标,但也包括对 PingRequestHandler、Collections API 的查询,以及对任何查询请求处理程序的查询。

默认的示例配置位于 prometheus-exporter/conf/solr-exporter-config.xml 中。以下是其稍作缩短的版本

<config>

  <rules>

    <ping>
      <lst name="request">
        <lst name="query">
          <str name="path">/admin/ping</str>
        </lst>
        <arr name="jsonQueries">
          <str>
            . as $object | $object |
            (if $object.status == "OK" then 1.0 else 0.0 end) as $value |
            {
              name         : "solr_ping",
              type         : "GAUGE",
              help         : "See following URL: https://solr.apache.org/guide/solr/latest/deployment-guide/ping.html",
              label_names  : [],
              label_values : [],
              value        : $value
            }
          </str>
        </arr>
      </lst>
    </ping>

    <metrics>
      <lst name="request">
        <lst name="query">
          <str name="path">/admin/metrics</str>
          <lst name="params">
            <str name="group">all</str>
            <str name="type">all</str>
            <str name="prefix"></str>
            <str name="property"></str>
          </lst>
        </lst>
        <arr name="jsonQueries">
          <!--
            jetty metrics
          -->
          <str>
            .metrics["solr.jetty"] | to_entries | .[] | select(.key | startswith("org.eclipse.jetty.server.handler.DefaultHandler")) | select(.key | endswith("xx-responses")) as $object |
            $object.key | split(".") | last | split("-") | first as $status |
            $object.value.count as $value |
            {
            name         : "solr_metrics_jetty_response_total",
            type         : "COUNTER",
            help         : "See following URL: https://solr.apache.org/guide/solr/latest/deployment-guide/metrics-reporting.html",
            label_names  : ["status"],
            label_values : [$status],
            value        : $value
            }
          </str>
...
        </arr>
      </lst>
    </metrics>

    <collections>
      <lst name="request">
        <lst name="query">
          <str name="path">/admin/collections</str>
          <lst name="params">
            <str name="action">CLUSTERSTATUS</str>
          </lst>
        </lst>
        <arr name="jsonQueries">
          <str>
            .cluster.live_nodes | length as $value|
            {
              name         : "solr_collections_live_nodes",
              type         : "GAUGE",
              help         : "See following URL: https://solr.apache.org/guide/solr/latest/deployment-guide/cluster-node-management.html#clusterstatus",
              label_names  : [],
              label_values : [],
              value        : $value
            }
          </str>
...
        </arr>
      </lst>
    </collections>

    <search>
      <lst name="request">
        <lst name="query">
          <str name="collection">collection1</str>
          <str name="path">/select</str>
          <lst name="params">
            <str name="q">*:*</str>
            <str name="start">0</str>
            <str name="rows">0</str>
            <str name="json.facet">
              {
                category: {
                  type: terms,
                  field: cat
                }
              }
            </str>
          </lst>
        </lst>
        <arr name="jsonQueries">
          <str>
            .facets.category.buckets[] as $object |
            $object.val as $term |
            $object.count as $value |
            {
              name         : "solr_facets_category",
              type         : "GAUGE",
              help         : "Category facets",
              label_names  : ["term"],
              label_values : [$term],
              value        : $value
            }
          </str>
        </arr>
      </lst>
    </search>

  </rules>

</config>

配置标签和元素

solr-exporter 的工作原理是根据配置文件中的定义向 Solr 发出请求,抓取响应,并将其转换为 Prometheus 可以理解的 JSON 结构。配置文件定义了要请求的元素、如何抓取它们以及将提取的数据放置在 JSON 模板中的位置。

solr-exporter 配置文件始终以两个简单的元素开头和结尾

<config>
  <rules>

  </rules>
</config>

在这些元素之间,定义了 solr-exporter 应请求的数据。有几种可能的请求类型

<ping>

抓取对 Ping 请求的响应。

<metrics>

抓取对 Metrics API 请求的响应。

<collections>

抓取对 Collections API 请求的响应。

<search>

抓取对 query 请求的响应。

在这些类型的每一种中,我们需要定义查询以及如何处理响应。为此,我们定义了两个额外的元素

<query>

定义用于请求的查询参数。此部分使用几个附加属性来定义您的查询

collection

可选

默认值:无

要对其发出查询的集合。仅用于 SolrCloud 集群。

core

可选

默认值:无

要对其发出查询的核心。仅用于用户管理的集群或单节点安装。

path

可选

默认值:无

将发送请求的查询端点的路径。示例包括 admin/metrics/selectadmin/collections

params

可选

默认值:无

其他查询参数。这些参数将因请求类型和端点而异。例如,如果使用 Metrics 端点,则可以添加参数以将查询限制为特定组和/或前缀。如果您使用 Collections API,则您要使用的命令将是一个参数。

<jsonQueries>

这是一个定义一个或多个 jq 语法 JSON 查询的数组。有关如何构造这些查询的更多详细信息,请参阅jq 用户手册

jq 查询必须输出以下格式的 JSON

{
  "name": "solr_ping",
  "type": "GAUGE",
  "help": "See following URL: https://solr.apache.org/guide/solr/latest/deployment-guide/ping.html",
  "label_names": ["base_url","core"],
  "label_values": ["https://127.0.0.1:8983/solr","collection1"],
  "value": 1.0
}

请参阅下面的公开格式部分,了解有关每个属性中应包含哪些信息,以及如何为 Prometheus 转换上述示例的信息。

公开格式

solr-exporter 将 JSON 转换为以下公开格式

# TYPE <name> <type>
# HELP <name> <help>
<name>{<label_names[0]>=<label_values[0]>,<label_names[1]>=<labelvalues[1]>,...} <value>

应设置以下参数

name

要设置的指标名称。有关更多详细信息,请参阅Prometheus 命名最佳实践

type

指标的类型,可以是 COUNTERGAUGESUMMARYHISTOGRAMUNTYPED。有关更多详细信息,请参阅Prometheus 指标类型

help

指标的帮助文本。

label_names

指标的标签名称。有关更多详细信息,请参阅Prometheus 命名最佳实践

label_values

指标的标签值。有关更多详细信息,请参阅Prometheus 命名最佳实践

value

指标的值。值必须设置为 Double 类型。

例如,solr-exporter 将上一节中的 JSON 转换为以下内容

# TYPE solr_ping gauge
# HELP solr_ping See following URL: https://solr.apache.org/guide/solr/latest/deployment-guide/ping.html
solr_ping{base_url="https://127.0.0.1:8983/solr",core="collection1"} 1.0

Prometheus 配置

Prometheus 是一个单独的服务器,您需要下载并部署它。有关更多信息,请访问 Prometheus 入门页面。

为了让 Prometheus 知道 solr-exporter,必须将侦听地址添加到 Prometheus 服务器的 prometheus.yml 配置文件中,如本例所示

scrape_configs:
  - job_name: 'solr'
    static_configs:
      - targets: ['localhost:9854']

如果您已经有一个 scrape_configs 部分,则可以在同一部分中添加 job_name 和其他值。

当您将设置应用于 Prometheus 时,它将开始从 solr-exporter 拉取 Solr 的指标。

您可以通过浏览到 https://127.0.0.1:9090 并在 Prometheus GUI 中查询 solr_ping 指标来测试 Prometheus 服务器、solr-exporter 和 Solr 是否协同工作

image
图 2. Prometheus Solr Ping 表达式

示例 Grafana 仪表板

要使用 Grafana 进行可视化,必须单独下载和部署它。有关更多信息,请访问 Grafana 文档站点。 Grafana 使用来自多个来源的数据,包括您之前设置的 Prometheus 服务器。

在以下 JSON 文件中提供了一个 Grafana 示例仪表板:prometheus-exporter/conf/grafana-solr-dashboard.json。您可以将其与您的其他 Grafana 仪表板配置一起放置,并根据您为 solr-exporter 配置所做的任何自定义进行修改。

您可以使用仪表板 ID 12456 通过 Grafana.com 使用“导入”功能直接导入 Solr 仪表板 via grafana.com

此屏幕截图显示了它的外观

image
图 3. Grafana 仪表板

具有 Prometheus 格式的 Metrics API

通过利用 Metrics API 并将 wt 参数设置为 prometheus,可以从 Solr 直接以原生方式获得 Prometheus 指标

localhost:8983/solr/admin/metrics?wt=prometheus

使用 prometheus 参数的 Metrics API 不提供任何可配置性,并且 Prometheus 输出是固定的。任何指标聚合和/或筛选都必须在 Grafana 或 Prometheus 服务器上完成。

Prometheus 配置

与 Prometheus Exporter 一样,需要为 Prometheus 服务器配置 prometheus.yml 以接收指标。区别在于,它必须改为直接从每个 Solr 运行的主机/端口抓取带有 wt=prometheus 参数的 Metrics API,如本例所示

scrape_configs:
  - job_name: 'solr'
    metrics_path: "/solr/admin/metrics"
    static_configs:
      - targets: ['localhost:8983', 'localhost:7574']
    params:
      wt: ['prometheus']