Solr のモニタリングに使える API

[Apache Solr](http://lucene.apache.org/solr/) (以下「Solr」)をプロダクション環境などにデプロイ後、どれくらいリソースを消費しているか、パフォーマンスに問題がないか、またはノードがダウンしていないかなど、モニタリングを行う上で有用な API をまとめます。

Solr は SolrCloud モードでクラスターを構成することが可能で、ノード障害が発生しても、別のノードが処理を引き継ぎ、サービス停止が発生しないように運用することが可能です。
しかし、ノードの障害に気づけないと、いつのまにか、たくさんのノードが障害を起こしていることがあります。

<img width="1484" alt="solr_admin.png" src="https://qiita-image-store.s3.amazonaws.com/0/58291/2393ba82-d267-e205-1351-5ba264de76ee.png">


上の図はストレージの枯渇に気がつかず、久しぶりに Solr の Admin UI を表示したらこんなことになっていたというものです。
このような悲惨な状態にならないように、日頃から Solr のモニタリングをしておくことをお勧めします。

# モニタリングに使える API
Solr では、稼働状況を確認するための API が 提供されており、[Apache Solr Reference Guide](https://lucene.apache.org/solr/guide/) でいくつか紹介されています。

- [Ping](https://lucene.apache.org/solr/guide/7_1/ping.html)
- [MBean Request Handler](https://lucene.apache.org/solr/guide/7_1/mbean-request-handler.html)
- [CoreAdmin API STATUS action](https://lucene.apache.org/solr/guide/7_1/coreadmin-api.html#coreadmin-status)
- [Index Replication details command](https://lucene.apache.org/solr/guide/7_1/index-replication.html)
- [Collections API CLUSTERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#clusterstatus)
- [Collections API OVERSEERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#overseerstatus)
- [Metrics API](https://lucene.apache.org/solr/guide/7_1/metrics-reporting.html#metrics-api)

# Ping

[Ping](https://lucene.apache.org/solr/guide/7_1/ping.html) はとてもシンプルで、指定したコア/コレクションが応答可能か確認するための API となっています。

スタンドアローンの Solr に対しては次のような HTTP リクエストでコアが応答可能か確認できます。

```text
http://localhost:8983/solr/<core-name>/admin/ping
```

SolrCloud モードの場合はコレクション名を指定し、`distrib=true` をパラメータに追加します。

```text
http://localhost:8983/solr/<collection-name>/admin/ping?distrib=true
```

レスポンスは次のような JSON が返ります。

```json
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":1506,
    "params":{
      "q":"{!lucene}*:*",
      "distrib":"true",
      "df":"_text_",
      "rows":"10",
      "echoParams":"all"}},
  "status":"OK"}
```

`status` が `OK` となっていれば、指定したコア/コレクションは応答可能ということになります。

詳細はドキュメントの [Ping](https://lucene.apache.org/solr/guide/7_1/ping.html) を確認してください。


# MBean Request Handler

[MBean Request Handler](https://lucene.apache.org/solr/guide/7_1/mbean-request-handler.html) は、Solr の統計情報を出力します。
各リクエストハンドラーへのリクエスト数や、エラー回数、インデックスのサイズ、ドキュメント数などが確認できます。

次のような HTTP リクエストでコアの MBean を取得できます。

```text
http://localhost:8983/solr/<core-name>/admin/mbeans?stats=true
```

レスポンスは次のような JSON が返ります。

```json
{
  "responseHeader":{
    "status":0,
    "QTime":7},
  "solr-mbeans":[
    "CONTAINER",{},
    "ADMIN",{
      "/admin/mbeans":{
        "class":"org.apache.solr.handler.admin.SolrInfoMBeanHandler",
        "description":"Get Info (and statistics) for registered SolrInfoMBeans",
        "stats":{
          "ADMIN./admin/mbeans.serverErrors.count":0,
          "ADMIN./admin/mbeans.clientErrors.count":0,
          "ADMIN./admin/mbeans.requestTimes.meanRate":2.9815887592227186E-4,
          "ADMIN./admin/mbeans.requests":2,
          "ADMIN./admin/mbeans.handlerStart":1511964233187,
          "ADMIN./admin/mbeans.timeouts.count":0,
          "ADMIN./admin/mbeans.errors.count":0,
          "ADMIN./admin/mbeans.totalTime":28479507}},

  ... [中略] ...

    "OTHER",{
      "elevator":{
        "class":"elevator",
        "description":"Query Boosting -- boost particular documents for a given query",
        "stats":null},
      "stats":{
        "class":"stats",
        "description":"Calculate Statistics",
        "stats":null},
      "debug":{
        "class":"debug",
        "description":"Debug Information",
        "stats":null}}]}
```

Master/Slave 構成や、SolrCloud で運用されている場合は、各ノード毎にリクエストする必要があります。

詳細はドキュメントの [MBean Request Handler](https://lucene.apache.org/solr/guide/7_1/mbean-request-handler.html) を確認してください。

# CoreAdmin API STATUS action

[CoreAdmin API STATUS action](https://lucene.apache.org/solr/guide/7_1/coreadmin-api.html#coreadmin-status) アクションは、コアの情報を出力します。

インデックスのサイズ、ドキュメント数などが確認できます。

次のような HTTP リクエストでコアのステータスを取得できます。

```
http://localhost:8983/solr/admin/cores
```

レスポンスは次のような JSON が返ります。

```json
{
  "responseHeader":{
    "status":0,
    "QTime":2079},
  "initFailures":{},
  "status":{
    "apache-log_shard1_replica_n1":{
      "name":"apache-log_shard1_replica_n1",
      "instanceDir":"/opt/solr/solr-7.1.0/server/solr1/apache-log_shard1_replica_n1",
      "dataDir":"/opt/solr/solr-7.1.0/server/solr1/apache-log_shard1_replica_n1/data/",
      "config":"solrconfig.xml",
      "schema":"managed-schema",
      "startTime":"2017-11-29T14:03:52.581Z",
      "uptime":3449240,
      "lastPublished":"active",
      "configVersion":0,
      "cloud":{
        "collection":"apache-log",
        "shard":"shard1",
        "replica":"core_node3"},
      "index":{
        "numDocs":104,
        "maxDoc":104,
        "deletedDocs":0,
        "indexHeapUsageBytes":-1,
        "version":989,
        "segmentCount":2,
        "current":false,
        "hasDeletions":false,
        "directory":"org.apache.lucene.store.NRTCachingDirectory:NRTCachingDirectory(MMapDirectory@/opt/solr/solr-7.1.0/server/solr1/apache-log_shard1_replica_n1/data/index lockFactory=org.apache.lucene.store.NativeFSLockFactory@31be8e67; maxCacheMB=48.0 maxMergeSizeMB=4.0)",
        "segmentsFile":"segments_40",
        "segmentsFileSizeInBytes":682,
        "userData":{
          "commitTimeMSec":"1511967656559",
          "commitCommandVer":"0"},
        "lastModified":"2017-11-29T15:00:56.559Z",
        "sizeInBytes":318362,
        "size":"310.9 KB"}},

  ... [中略] ...
```

Master/Slave 構成や、SolrCloud で運用されている場合は、各ノード毎にリクエストする必要があります。

詳細はドキュメントの [CoreAdmin API STATUS action](https://lucene.apache.org/solr/guide/7_1/coreadmin-api.html#coreadmin-status) を確認してください。

# Index Replication details command

[Index Replication details command](https://lucene.apache.org/solr/guide/7_1/index-replication.html) は Solr を Master/Slave 構成や、SolrCloud モードで運用している場合、インデックスのレプリケーション状況の情報を出力します。

コアのインデックスファイルのリストや、インデックスのバージョンなどが取得できます。  
次のような HTTP リクエストでコアのレプリケーション状況を取得できます。

```
http://localhost:8983/solr/<core-name>/replication?command=details
```

レスポンスは次のような JSON が返ります。

```json
{
  "responseHeader":{
    "status":0,
    "QTime":4},
  "details":{
    "indexSize":"8.76 MB",
    "indexPath":"/opt/solr/solr-7.1.0/server/solr1/solr-log_shard1_replica_n1/data/index/",
    "commits":[[
        "indexVersion",1511967754165,
        "generation",206,
        "filelist",["_c7.dii",
          "_c7.dim",
          "_c7.fdt",
          "_c7.fdx",
          "_c7.fnm",
          "_c7.nvd",
          "_c7.nvm",
          "_c7.si",
          "_c7_Lucene50_0.doc",

... [中略] ...

          "_cm_Lucene70_0.dvd",
          "_cm_Lucene70_0.dvm",
          "segments_5q"]]],
    "isMaster":"true",
    "isSlave":"false",
    "indexVersion":1511967754165,
    "generation":206,
    "master":{
      "replicateAfter":["commit"],
      "replicationEnabled":"true",
      "replicableVersion":1511967754165,
      "replicableGeneration":206}}}
```

Master/Slave 構成や、SolrCloud で運用されている場合は、各ノード毎にリクエストする必要があります。

詳細はドキュメントの [Index Replication details command](https://lucene.apache.org/solr/guide/7_1/index-replication.html) を確認してください。

# Collections API CLUSTERSTATUS action

[Collections API CLUSTERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#clusterstatus) は Solr を SolrCloud モードで運用している場合、SolrCloud のクラスターの状態を出力します。

コレクションやシャード、レプリカのステータス、どれがリーダーノードかなどの情報を取得できます。  
次のような HTTP リクエストでクラスターの状態を取得できます。

```
http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS
```

```json
{
  "responseHeader":{
    "status":0,
    "QTime":793},
  "cluster":{
    "collections":{
      "banana-int":{
        "pullReplicas":"0",
        "replicationFactor":"2",
        "shards":{"shard1":{
            "range":"80000000-7fffffff",
            "state":"active",
            "replicas":{
              "core_node3":{
                "core":"banana-int_shard1_replica_n1",
                "base_url":"http://localhost:8983/solr",
                "node_name":"localhost:8983_solr",
                "state":"active",
                "type":"NRT"},
              "core_node4":{
                "core":"banana-int_shard1_replica_n2",
                "base_url":"http://localhost:8984/solr",
                "node_name":"localhost:8984_solr",
                "state":"active",
                "type":"NRT",
                "leader":"true"}}}},
        "router":{"name":"compositeId"},
        "maxShardsPerNode":"-1",
        "autoAddReplicas":"false",
        "nrtReplicas":"1",
        "tlogReplicas":"0",
        "znodeVersion":482,
        "configName":"banana-int"},

... [中略] ...

    "live_nodes":["localhost:8983_solr",
      "localhost:8984_solr"]}}
```

詳細はドキュメントの [Collections API CLUSTERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#clusterstatus) を確認してください。

# Collections API OVERSEERSTATUS action

[Collections API OVERSEERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#overseerstatus) は Solr を SolrCloud モードで運用している場合、SolrCloud のOverseerの状態を出力します。

Overseer ノードの状態やクラスター情報の更新状況などの情報を取得できます。  
次のような HTTP リクエストで Overseer の状態を取得できます。

```
http://localhost:8983/solr/admin/collections?action=OVERSEERSTATUS
```

```json
{
  "responseHeader":{
    "status":0,
    "QTime":769},
  "leader":"localhost:8984_solr",
  "overseer_queue_size":0,
  "overseer_work_queue_size":0,
  "overseer_collection_queue_size":2,
  "overseer_operations":[
    "leader",{
      "requests":6,
      "errors":0,
      "avgRequestsPerSecond":0.012809448246649296,
      "5minRateRequestsPerSecond":0.13193458362278854,
      "15minRateRequestsPerSecond":0.36198174053303417,
      "avgTimePerRequest":0.38434356339969716,
      "medianRequestTime":0.235248,
      "75thPcRequestTime":0.374476,
      "95thPcRequestTime":0.960796,
      "99thPcRequestTime":0.960796,
      "999thPcRequestTime":0.960796},

... [中略] ...

  "collection_queue":[
    "peektopn_wait2000",{
      "avgRequestsPerSecond":0.4987677447859391,
      "5minRateRequestsPerSecond":0.47614991717626287,
      "15minRateRequestsPerSecond":0.43906724443449646,
      "avgTimePerRequest":1997.8122285841457,
      "medianRequestTime":2001.880367,
      "75thPcRequestTime":2003.766613,
      "95thPcRequestTime":2005.199509,
      "99thPcRequestTime":2005.226677,
      "999thPcRequestTime":2005.226677}]}
```

詳細はドキュメントの [Collections API OVERSEERSTATUS action](https://lucene.apache.org/solr/guide/7_1/collections-api.html#overseerstatus) を確認してください。


# Metrics API

[Metrics API](https://lucene.apache.org/solr/guide/7_1/metrics-reporting.html#metrics-api) は JMX、Node、Core、Jetty のメトリクスを出力します。

CoreAdmin API や、MBean Request Handler の出力する情報に加え、CPU やメモリなどのマシンデータを含めて取得することができます。

次のような HTTP リクエストでコアのメトリクスを取得できます。

```
http://localhost:8983/solr/admin/metrics
```

```json
{
  "responseHeader":{
    "status":0,
    "QTime":491},
  "metrics":{
    "solr.jetty":{
      "org.eclipse.jetty.server.handler.DefaultHandler.1xx-responses":{
        "count":0,
        "meanRate":0.0,
        "1minRate":0.0,
        "5minRate":0.0,
        "15minRate":0.0},
      "org.eclipse.jetty.server.handler.DefaultHandler.2xx-responses":{
        "count":1782,
        "meanRate":0.48328878934129726,
        "1minRate":0.5433836790153476,
        "5minRate":0.5417225683542973,
        "15minRate":0.5236725556084993},
      "org.eclipse.jetty.server.handler.DefaultHandler.3xx-responses":{
        "count":11,
        "meanRate":0.0029832641212806797,
        "1minRate":5.557889866309525E-4,
        "5minRate":0.01149649944222499,
        "15minRate":0.008303209993972665},
      "org.eclipse.jetty.server.handler.DefaultHandler.4xx-responses":{
        "count":1,
        "meanRate":2.712058278071136E-4,
        "1minRate":0.0019911254902870547,
        "5minRate":0.002179257839786804,
        "15minRate":9.643462532427122E-4},
      "org.eclipse.jetty.server.handler.DefaultHandler.5xx-responses":{
        "count":1,
        "meanRate":2.712058284133342E-4,
        "1minRate":6.535204052771162E-5,
        "5minRate":0.001100375015670387,
        "15minRate":7.679100748119E-4},

... [中略] ...

      "UPDATE.updateHandler.optimizes":{
        "count":0,
        "meanRate":0.0,
        "1minRate":0.0,
        "5minRate":0.0,
        "15minRate":0.0},
      "UPDATE.updateHandler.rollbacks":{
        "count":0,
        "meanRate":0.0,
        "1minRate":0.0,
        "5minRate":0.0,
        "15minRate":0.0},
      "UPDATE.updateHandler.softAutoCommits":0,
      "UPDATE.updateHandler.splits":{
        "count":0,
        "meanRate":0.0,
        "1minRate":0.0,
        "5minRate":0.0,
        "15minRate":0.0}}}}
```

Master/Slave 構成や、SolrCloud で運用されている場合は、各ノード毎にリクエストする必要があります。

詳細はドキュメントの [Metrics Reporting](https://lucene.apache.org/solr/guide/7_1/metrics-reporting.html) を確認してください。

# まとめ

これらの API を使用して Solr の状態を監視し、未然に問題を検知しすることができます。
Solr を健全な状態を維持することの役に立つはずです。  
Solr の出力するメトリクスについては、[Apache Solr Reference Guide](https://lucene.apache.org/solr/guide/) にまとまっていますので、[Performance Statistics Reference](https://lucene.apache.org/solr/guide/7_1/performance-statistics-reference.html) を参照してください。

![TH160_9784774189307.jpg](https://qiita-image-store.s3.amazonaws.com/0/58291/b6d09ffb-aea6-d4cb-988b-f9d7994d3bfe.jpeg)

Metrics API 以外については、[［改訂第3版］Apache Solr入門](http://gihyo.jp/book/2017/978-4-7741-8930-7) でも解説されているので、興味ある方は是非読んでみてください。