我做了一个Solr的Prometheus导出器

通知

我为 Apache Lucene/Solr 项目贡献了 solr-exporter(https://github.com/mosuka/solr-exporter)。
今后请使用 Apache Solr 中内置的 solr-exporter。
请参考以下网址获取详细信息。
http://lucene.apache.org/solr/guide/monitoring-solr-with-prometheus-and-grafana.html


在介绍了一些可用于监控Apache Solr(以下简称“Solr”)的软件中,它们基本上都利用了JMX功能来监控Solr的指标。但这些软件并不能监控Solr正在索引的数据。

例如,

    • アプリケーションログを保存していたら、エラーがどれくらい、どのシステムで発生しているか

 

    • EC であれば、商品カテゴリー毎の商品数の推移

 

    ユーザー投稿型のサービスであれば、問題のあるキーワードを含むコンテンツがどれだけあるか

如果您想对索引数据进行可视化,可以使用Lucidworks在开源软件中提供的Banana(相当于Kibana3)。这是类似于Elastic提供的Kibana的软件。
然而,如果您想要进行警报处理,就需要使用X-Pack或Yelp在开源软件中提供的ElastAlert等软件。但很难找到一个好用的软件。而且,如果为了监控而增加了很多工具,运维工作会变得非常复杂。

因此,我将监控软件统一为Prometheus和Grafana,并创建了solr-exporter,以便监控Solr的指标和索引。

Solr导出器

通过使用solr-exporter,可以监控和提醒Solr指标和Solr正在索引的数据。下图是连接到独立的Solr时的示意图。当然,也可以连接到SolrCloud。

sample

solr-exporter是使用Java开发的。
选择Java的原因是因为Solr项目提供了SolrJ(Solr客户端库)。
Solr具有类似REST的接口,可以通过HTTP访问,但考虑到故障转移等情况,实现起来很困难。
SolrJ不仅可以连接独立的Solr,还可以使用SolrCloud进行集群,并通过ZooKeeper进行节点发现,连接到正在运行的Solr。
此外,SolrJ是Solr附带的客户端库,因此得到充分的维护,可以放心使用。

连接到Solr的solr-exporter可以使用Solr的监控API,如Metrics API,并对Solr进行全文搜索,并将它们的响应作为Prometheus指标公开。

设置使用YAML格式的文件进行管理。
使用jq命令查询来解析返回的API JSON响应。

创造的背景

我開發solr-exporter的原因如下。

検索エンジンとして Solr の運用ノウハウを持っている・監視システムとして Prometheus に統一・集約したい

想定する実行環境が Kubernetes で、Prometheus は Kubernetes との相性もよさそう

Prometheus は、元 Google のエンジニアが Google 社内監視システムの Borgmon にインスパイアされて開発したもので筋がよさそう
監視システムとして、Solr と同じ Lucene をベースにした検索エンジンである Elasticsearch や、可視化・モニタリングのために Kibana、X-Pack を導入して運用コストを上げたくない

Solr でインデックスしたドキュメント (データ) のモニタリングをしたい

「このキーワードにマッチするドキュメントがどれくらいある」などをモニタリングしたい
Solr の全文検索クエリーを実行したい

Banana や Zeppelin では可視化はできても、アラーティングまでできない

ElastAlert のような、Solr 向けのアラーティングのソフトウェアが欲しい

メトリクスのような時系列データを Lucene の転置インデックスで扱うのに抵抗がある

時系列データには時系列データベースを使用した方がいいのではないか

Solr の Exporter 作ったら、上記の課題を解決できる

从这个角度来说,我个人认为如果没有的话,为什么不自己做一个呢。

安装

从solr-exporter仓库的发布页面下载已编译的存档文件。
在适当的目录中解压并完成安装。

$ cd ~/
$ unzip solr-exporter-0.3.8-bin.zip
$ cd solr-exporter-0.3.8

执行

请在安装目录下执行 ./bin/solr-exporter。

$ ./bin/solr-exporter -p 9983 -b http://localhost:8983/solr -f ./conf/config.yml

在Windows环境中,使用相同目录下的`.\bin\solr-exporter.bat`文件。

> .\bin\solr-exporter.bat -p 9983 -b http://localhost:8983/solr -f .\conf\config.yml

如果在 SolrCloud 模式下组成集群的话,需要按照以下方式指定 ZooKeeper 的连接字符串。

$ ./bin/solr-exporter -p 9983 -z localhost:2181/solr -f ./conf/config.yml

请查看帮助以了解其他命令行选项。

$ ./bin/solr-exporter -h
usage: SolrCollector [-h] [-v] [-p PORT] [-b BASE_URL] [-z ZK_HOST] [-f CONFIG]
                     [-n NUM_THREADS]

Prometheus exporter for Apache Solr.

optional arguments:
  -h, --help             show this help message and exit
  -v, --version          show version
  -p PORT, --port PORT   solr-exporter listen port
  -b BASE_URL, --baseurl BASE_URL
                         specify Solr base URL when connecting  to Solr in standalone mode (for
                         example 'http://localhost:8983/solr')
  -z ZK_HOST, --zkhost ZK_HOST
                         specify  ZooKeeper  connection  string  when  connecting  to  Solr  in
                         SolrCloud mode (for example 'localhost:2181/solr')
  -f CONFIG, --config-file CONFIG
                         specify configuration file
  -n NUM_THREADS, --num-thread NUM_THREADS
                         specify number of threads

设定文件示例

Solr导出器的配置文件是一个YAML文件,内容如下.

请设置一个查询到Solr的请求,并使用jsonQueries解析jq查询的响应。这是为了支持用户在Solr的solrconfig.xml中自由更改请求处理程序的路径,并允许用户自由更改指标名和标签名。有关指标等命名规则,请参考Prometheus的Metric and label naming指南。

ping:
  query:
    path: /admin/ping
  jsonQueries:
    - |-
      . 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: http://lucene.apache.org/solr/guide/7_1/ping.html",
        label_names  : [],
        label_values : [],
        value        : $value
      }

metrics:
  query:
    path: /admin/metrics
    params:
      - group: 'all'
      - type: 'all'
      - prefix: ''
      - property: ''
  jsonQueries:
    ##############################
    # jetty
    ##############################
    # solr_metrics_jetty_response_total
    - |-
      .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://lucene.apache.org/solr/guide/7_1/metrics-reporting.html",
        label_names  : ["status"],
        label_values : [$status],
        value        : $value
      }

... [中略] ...

collections:
  query:
    path: /admin/collections
    params:
      - action: 'CLUSTERSTATUS'
  jsonQueries:
    # solr_collections_live_nodes
    - |-
      .cluster.live_nodes | length as $value|
      {
        name         : "solr_collections_live_nodes",
        type         : "gauge",
        help         : "See following URL: https://lucene.apache.org/solr/guide/7_1/collections-api.html#clusterstatus",
        label_names  : [],
        label_values : [],
        value        : $value
      }

... [中略] ...

queries:
  - query:
      collection: collection1
      path: /select
      params:
        - q: "*:*"
        - start: 0
        - rows: 0
        - json.facet: |-
            {
              category: {
                type: terms,
                field: cat
              }
            }
    jsonQueries:
      # solr_facets_category
      - |-
        .facets.category.buckets[] as $object |
        $object.val as $term |
        $object.count as $value |
        {
          name         : "solr_facets_category",
          type         : "gauge",
          help         : "Category facets",
          label_names  : ["collection", "term"],
          label_values : ["collection1", $term],
          value        : $value
        }

在solr-exporter中,有ping、metrics、collections和queries的配置选项。

    • ping – Solr の Ping を利用し、コア、コレクションが利用可能かのメトリクスを取得

 

    • metrics – Solr の Metrics API を利用して、メトリクスを取得

 

    • collections – Solr の Collections API を利用して、クラスターの情報をメトリクスとして取得

 

    queries – Solr の検索を利用して、検索結果をメトリクスとして取得

将Solr返回的JSON响应,通过下面的格式构建为JSON作为度量标准,并设置jq查询以将其转换为Prometheus格式的数据并公开(暴露)。

{
  "name": "some_metric_name",
  "type": "gauge", 
  "help": "describe metric.",
  "label_names": ["label_name1", "label_name2"],
  "label_values": ["label_value1", "label_value2"],
  "value": 1.0
}

例如,上述的JSON将被转换为以下的Prometheus格式。

# HELP some_metric_name describe metric.
# TYPE some_metric_name gauge
some_metric_name{label_name1 ="label_value1", label_name2 ="label_value2",} 1.0

请执行solr-exporter并访问以下网址以确认Solr的指标是否已暴露:

$ curl -s 'http://localhost:9983/metrics'
# HELP solr_metrics_jetty_response_total See following URL: https://lucene.apache.org/solr/guide/7_1/metrics-reporting.html
# TYPE solr_metrics_jetty_response_total counter
solr_metrics_jetty_response_total{base_url="http://localhost:8983/solr",status="1xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8983/solr",status="2xx",} 516.0
solr_metrics_jetty_response_total{base_url="http://localhost:8983/solr",status="3xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8983/solr",status="4xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8983/solr",status="5xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8984/solr",status="1xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8984/solr",status="2xx",} 517.0
solr_metrics_jetty_response_total{base_url="http://localhost:8984/solr",status="3xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8984/solr",status="4xx",} 0.0
solr_metrics_jetty_response_total{base_url="http://localhost:8984/solr",status="5xx",} 0.0

... [中略] ...

# TYPE solr_collections_shard_leader gauge
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="banana-int",shard="shard1",replica="core_node3",core="banana-int_shard1_replica_n1",base_url="http://localhost:8983/solr",node_name="localhost:8983_solr",type="NRT",} 0.0
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="banana-int",shard="shard1",replica="core_node4",core="banana-int_shard1_replica_n2",base_url="http://localhost:8984/solr",node_name="localhost:8984_solr",type="NRT",} 1.0
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="apache-log",shard="shard1",replica="core_node3",core="apache-log_shard1_replica_n1",base_url="http://localhost:8983/solr",node_name="localhost:8983_solr",type="NRT",} 0.0
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="apache-log",shard="shard1",replica="core_node4",core="apache-log_shard1_replica_n2",base_url="http://localhost:8984/solr",node_name="localhost:8984_solr",type="NRT",} 1.0
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="solr-log",shard="shard1",replica="core_node3",core="solr-log_shard1_replica_n1",base_url="http://localhost:8983/solr",node_name="localhost:8983_solr",type="NRT",} 0.0
solr_collections_shard_leader{zk_host="localhost:2181/solr",collection="solr-log",shard="shard1",replica="core_node4",core="solr-log_shard1_replica_n2",base_url="http://localhost:8984/solr",node_name="localhost:8984_solr",type="NRT",} 1.0
# HELP solr_scrape_duration_seconds Time this Solr scrape took, in seconds.
# TYPE solr_scrape_duration_seconds gauge
solr_scrape_duration_seconds 1.584429789

只要能够输出指标,solr-exporter的准备工作就完成了。

在默认情况下,已经设置了关键指标和Solr搜索查询样例。如果不需要某些指标或想要获取其他指标的搜索结果,可以适当进行修改。

普罗米修斯

我們需要準備 Prometheus 來從這裡拉取 solr-exporter 公開的指標。

安装和配置 Prometheus

请参考 [Prometheus 的安装文档](https://prometheus.io/docs/prometheus/latest/installation/),根据您的环境进行安装。

在安装完成后,请在prometheus.yaml的scrape_configs中添加solr-exporter的信息。

$ vi ./prometheus.yaml
# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

... [中略] ...

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'solr'
    static_configs:
      - targets: ['localhost:9983']

你可以使用solr-exporter从上述获取指标。

普罗米修斯的执行 (Pǔ luó mǐ xiū sī de zhí

使用以下命令启动 Prometheus。

$ ./prometheus --config.file ./prometheus.yml

启动 Prometheus 后,您可以通过以下网址访问 Prometheus 的用户界面。

http://localhost:9090/graph

在状态菜单中点击”Targets”,您可以查看Prometheus正在收集的目标列表。
请确认刚刚注册的solr-exporter是否存在于目标中。如果列表中没有或者出现错误,请确认配置文件内容是否正确。

Screen Shot 2017-12-01 at 17.52.23.png

普罗米修斯收集的度量可以通过图表进行可视化。

Screen Shot 2017-12-01 at 17.54.08.png

不过,还是有点寂寞。因为我准备了 Grafana 的示例仪表板,所以我会尝试显示它。

Grafana – 自动图表化和监控仪表盘软件。

为了更高级地可视化在Prometheus中保存的指标数据,我们将准备Grafana。

安装 Grafana

请参考 “Installing Grafana” 进行 Grafana 的安装,并根据您的环境进行操作。

Grafana 仪表板

一旦启动Grafana后,您可以通过以下URL访问用户界面。

http://localhost:3000
Screen Shot 2017-12-03 at 23.11.00.png

初始管理员账户如下所示。

用户: admin
密码: admin

这次我们准备了一个样本仪表板,并在以下的 URL 上进行了公开:
https://grafana.com/dashboards/3888

您可以通过以下方式导入示例仪表板:
在“仪表板”→“导入”中打开“导入仪表板”对话框。

Screen Shot 2017-12-03 at 23.14.48.png

请在Grafana.com仪表盘上输入3888(示例仪表盘的ID)。

Screen Shot 2017-12-03 at 23.17.10.png

成功导入后,您可以看到以下这样的仪表盘。

solr-dashboard.png

由于这是示例仪表板,您可以自由编辑并创建自己喜欢的仪表板。

整理

Solr的Metrics API的响应格式不一致,机械地直接转换为Prometheus格式非常困难,但是通过使用jq查询,我们可以将不一致的格式统一为一致的格式。

Solr是一款功能齐全且经过验证的全文搜索引擎软件,但其监控和提示功能由于生态系统不完善而较为薄弱。

solr-exporter是一个能够连接先进的监控和提示工具Prometheus的软件,旨在解决Solr在监控和提示方面的弱点。

这是一个实验性的尝试,所以可能会存在一些问题,但如果你感兴趣的话,请试着使用一下。
另外,如果你有任何改进的建议,请务必提出 Pull Request。

在Solr社区中,有一个问题[SOLR-10654]被提出,该问题是关于在Prometheus格式下暴露Metrics API的响应。
同时,还有一项尝试是基于Prometheus格式的OpenMetrics,旨在对Metrics格式进行标准化。
还有一个叫做”Prometheus Advent Calendar 2017″的活动。如果对Prometheus产生了兴趣,请也查看一下这个活动。

TH160_9784774189307.jpg

我认为要提取Solr索引的数据,需要使用Facet、Stats API和搜索查询。《改订第3版》《Apache Solr入门》介绍了搜索查询的书写方式和各种API,请有兴趣的人一定要阅读一下。

广告
将在 10 秒后关闭
bannerAds