我做了一个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。
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是否存在于目标中。如果列表中没有或者出现错误,请确认配置文件内容是否正确。
普罗米修斯收集的度量可以通过图表进行可视化。
不过,还是有点寂寞。因为我准备了 Grafana 的示例仪表板,所以我会尝试显示它。
Grafana – 自动图表化和监控仪表盘软件。
为了更高级地可视化在Prometheus中保存的指标数据,我们将准备Grafana。
安装 Grafana
请参考 “Installing Grafana” 进行 Grafana 的安装,并根据您的环境进行操作。
Grafana 仪表板
一旦启动Grafana后,您可以通过以下URL访问用户界面。
http://localhost:3000
初始管理员账户如下所示。
用户: admin
密码: admin
这次我们准备了一个样本仪表板,并在以下的 URL 上进行了公开:
https://grafana.com/dashboards/3888
您可以通过以下方式导入示例仪表板:
在“仪表板”→“导入”中打开“导入仪表板”对话框。
请在Grafana.com仪表盘上输入3888(示例仪表盘的ID)。
成功导入后,您可以看到以下这样的仪表盘。
由于这是示例仪表板,您可以自由编辑并创建自己喜欢的仪表板。
整理
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产生了兴趣,请也查看一下这个活动。
我认为要提取Solr索引的数据,需要使用Facet、Stats API和搜索查询。《改订第3版》《Apache Solr入门》介绍了搜索查询的书写方式和各种API,请有兴趣的人一定要阅读一下。