CLOVER🍀

That was when it all began.

PrometheusのRedis Exporterを試す

これは、なにをしたくて書いたもの?

久しぶりに、Prometheusまわりを見ていこうかなと思いまして。ちょっとずつ。

今回は、RedisのExporterを試してみようと思います。

GitHub - oliver006/redis_exporter: Prometheus Exporter for Redis Metrics. Supports Redis 2.x, 3.x, 4.x, 5.x and 6.x

Redis Exporter

RedisのPrometheus向けのExporterです。Redisのメトリクスを、Prometheus向けに公開することができます。

GitHub - oliver006/redis_exporter: Prometheus Exporter for Redis Metrics. Supports Redis 2.x, 3.x, 4.x, 5.x and 6.x

PrometheusのExporterのドキュメントにも、名前があります。

Exporters and integrations | Prometheus

どんな情報がエクスポートされるのか?というところですが、ほとんどの情報は、RedisのINFOコマンドの結果になります。

What's exported

INFO – Redis

加えて、データベースあたりのキーの総数や有効期限切れのキーの数、キーの平均TTLに関する情報なども得られます。

では、使っていってみましょう。

環境

使用しているミドルウェアは、こちら。

  • Redis … 5.0.8
  • Redis Exporter 1.5.1
  • Prometheus … 2.17.1

RedisとRedis Exporterは同じホスト(172.17.0.2)、Prometheusは別のホスト(172.17.0.3)で動作しているものとして、Redisに
クライアントプログラムを書いてアクセスしてみます。

なお、Redisはシングルインスタンスでの構成でパスワードを設定しているものとし、RedisとPrometheusのインストールは省略します。

Redis Exporterのインストール

Redis Exporterは、GitHubからダウンロードして展開すれば、すぐに使うことができます。

$ curl -LO https://github.com/oliver006/redis_exporter/releases/download/v1.5.2/redis_exporter-v1.5.2.linux-amd64.tar.gz
$ tar xf redis_exporter-v1.5.2.linux-amd64.tar.gz
$ cd redis_exporter-v1.5.2.linux-amd64

Redisと同じホストで動かすのと、今回はパスワードを設定しているのでオプションにて指定します。「--redis.password」です。
※パスワードの値は「redispass」です

$ ./redis_exporter -redis.password=redispass

どんなオプションがあるかは、こちらを確認します。

Command line flags

もしくは、ヘルプでもOKです。

$ ./redis_exporter -h
Usage of ./redis_exporter:
  -check-keys string
        Comma separated list of key-patterns to export value and length/size, searched for with SCAN
  -check-single-keys string
        Comma separated list of single keys to export value and length/size
  -config-command string
        What to use for the CONFIG command (default "CONFIG")
  -connection-timeout string
        Timeout for connection to Redis instance (default "15s")
  -debug
        Output verbose debug information
  -export-client-list
        Whether to scrape Client List specific metrics
  -include-system-metrics
        Whether to include system metrics like e.g. redis_total_system_memory_bytes
  -is-tile38
        Whether to scrape Tile38 specific metrics
  -log-format string
        Log format, valid options are txt and json (default "txt")
  -namespace string
        Namespace for metrics (default "redis")
  -ping-on-connect
        Whether to ping the redis instance after connecting
  -redis-only-metrics
        Whether to also export go runtime metrics
  -redis.addr string
        Address of the Redis instance to scrape (default "redis://localhost:6379")
  -redis.password string
        Password of the Redis instance to scrape
  -script string
        Path to Lua Redis script for collecting extra metrics
  -set-client-name
        Whether to set client name to redis_exporter (default true)
  -skip-tls-verification
        Whether to to skip TLS verification
  -tls-client-cert-file string
        Name of the client certificate file (including full path) if the server requires TLS client authentication
  -tls-client-key-file string
        Name of the client key file (including full path) if the server requires TLS client authentication
  -version
        Show version information and exit
  -web.listen-address string
        Address to listen on for web interface and telemetry. (default ":9121")
  -web.telemetry-path string
        Path under which to expose metrics. (default "/metrics")

接続先はデフォルト(redis://localhost:6379)で大丈夫ですが、明示する場合はこんな感じです。

$ ./redis_exporter -redis.addr=redis://localhost:6379 -redis.password=redispass
$ ./redis_exporter -redis.addr=redis://172.17.0.2:6379 -redis.password=redispass

また、オプションの書き方なんですが、ドキュメントにないのですが「--redis.password」のような形でも動いたりします。

$ ./redis_exporter --redis.password=redispass

では、メトリクスを取得するURLにアクセスしてみましょう。起動時のログに、アクセス先が書かれています。

INFO[0000] Redis Metrics Exporter v1.5.2    build date: 2020-03-16-20:52:04    sha1: 18080da36b0a97595d308cfb4bdf92eb1e396c44    Go: go1.14    GOOS: linux    GOARCH: amd64 
INFO[0000] Providing metrics at :9121/metrics  

curlで確認。

$ curl -s localhost:9121/metrics | tail -n 30
# HELP redis_replica_resyncs_full replica_resyncs_full metric
# TYPE redis_replica_resyncs_full gauge
redis_replica_resyncs_full 0
# HELP redis_replication_backlog_bytes replication_backlog_bytes metric
# TYPE redis_replication_backlog_bytes gauge
redis_replication_backlog_bytes 1.048576e+06
# HELP redis_second_repl_offset second_repl_offset metric
# TYPE redis_second_repl_offset gauge
redis_second_repl_offset -1
# HELP redis_slave_expires_tracked_keys slave_expires_tracked_keys metric
# TYPE redis_slave_expires_tracked_keys gauge
redis_slave_expires_tracked_keys 0
# HELP redis_slowlog_last_id Last id of slowlog
# TYPE redis_slowlog_last_id gauge
redis_slowlog_last_id 1
# HELP redis_slowlog_length Total slowlog
# TYPE redis_slowlog_length gauge
redis_slowlog_length 2
# HELP redis_start_time_seconds Start time of the Redis instance since unix epoch in seconds.
# TYPE redis_start_time_seconds gauge
redis_start_time_seconds 1.586856762e+09
# HELP redis_target_scrape_request_errors_total Errors in requests to the exporter
# TYPE redis_target_scrape_request_errors_total counter
redis_target_scrape_request_errors_total 0
# HELP redis_up Information about the Redis instance
# TYPE redis_up gauge
redis_up 1
# HELP redis_uptime_in_seconds uptime_in_seconds metric
# TYPE redis_uptime_in_seconds gauge
redis_uptime_in_seconds 1762

取得できてそうです。

メトリクスを取得しているのは、このあたり。

https://github.com/oliver006/redis_exporter/blob/v1.5.2/exporter.go#L1275-L1295

各メトリクスのうち、HELPを見るとINFOメトリクスとある程度はマッピングが取れそうです。

$ curl -s localhost:9121/metrics | grep memory_used
# HELP redis_memory_used_bytes memory_used_bytes metric
# TYPE redis_memory_used_bytes gauge
redis_memory_used_bytes 862304
# HELP redis_memory_used_dataset_bytes memory_used_dataset_bytes metric
# TYPE redis_memory_used_dataset_bytes gauge
redis_memory_used_dataset_bytes 16234
# HELP redis_memory_used_lua_bytes memory_used_lua_bytes metric
# TYPE redis_memory_used_lua_bytes gauge
redis_memory_used_lua_bytes 37888
# HELP redis_memory_used_overhead_bytes memory_used_overhead_bytes metric
# TYPE redis_memory_used_overhead_bytes gauge
redis_memory_used_overhead_bytes 846070
# HELP redis_memory_used_peak_bytes memory_used_peak_bytes metric
# TYPE redis_memory_used_peak_bytes gauge
redis_memory_used_peak_bytes 881456
# HELP redis_memory_used_rss_bytes memory_used_rss_bytes metric
# TYPE redis_memory_used_rss_bytes gauge
redis_memory_used_rss_bytes 4.521984e+06
# HELP redis_memory_used_scripts_bytes memory_used_scripts_bytes metric
# TYPE redis_memory_used_scripts_bytes gauge
redis_memory_used_scripts_bytes 0
# HELP redis_memory_used_startup_bytes memory_used_startup_bytes metric
# TYPE redis_memory_used_startup_bytes gauge
redis_memory_used_startup_bytes 791352

redis-cliでも、INFOコマンドを実行。

$ bin/redis-cli -a redispass
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> INFO

used_memoryの部分だけ抜粋。

# Memory
used_memory:862232
used_memory_human:842.02K
used_memory_rss:4534272
used_memory_rss_human:4.32M
used_memory_peak:881456
used_memory_peak_human:860.80K
used_memory_peak_perc:97.82%
used_memory_overhead:846070
used_memory_startup:791352
used_memory_dataset:16162
used_memory_dataset_perc:22.80%
〜省略〜

他にもレプリケーションクラスタリングに関するメトリクスもありますが、今回はそのあたりの確認はパス。

クライアントプログラムからRedisにアクセスする

キーに関するメトリクスを確認するために、ちょっとクライアントプログラムからアクセスしてみましょう。

Pythonで、簡単なプログラムを書いてみます。

環境の情報。

$ python3 -V
Python 3.6.9


$ pip3 -V
pip 9.0.1 from /path/to/venv/lib/python3.6/site-packages (python 3.6)

redis-pyをインストール。

$ pip3 install redis

redis-pyのバージョン。

$ pip3 freeze | grep redis
redis==3.4.1

Redisに100件データを登録し、100件取得し、100件ミスさせるプログラムを作成。 app.py

import redis

redis_client = redis.Redis(host = '172.17.0.2', port = 6379,  password = 'redispass', decode_responses = True)

for i in range(100):
    redis_client.set(f'key{i}', f'value{i}')

for i in range(100):
    assert redis_client.get(f'key{i}') == f'value{i}'

for i in range(100, 200):
    assert redis_client.get(f'key{i}') is None

実行。

$ python3 app.py

メトリクスの方を見てみましょう。まずは、ヒット件数、ミス件数から。

$ curl -s localhost:9121/metrics | grep keyspace | grep -E 'hit|miss'
# HELP redis_keyspace_hits_total keyspace_hits_total metric
# TYPE redis_keyspace_hits_total counter
redis_keyspace_hits_total 100
# HELP redis_keyspace_misses_total keyspace_misses_total metric
# TYPE redis_keyspace_misses_total counter
redis_keyspace_misses_total 100

データベースあたりのキーの数。

$ curl -s localhost:9121/metrics | grep redis_db_keys
# HELP redis_db_keys Total number of keys by DB
# TYPE redis_db_keys gauge
redis_db_keys{db="db0"} 100
redis_db_keys{db="db1"} 0
redis_db_keys{db="db10"} 0
redis_db_keys{db="db11"} 0
redis_db_keys{db="db12"} 0
redis_db_keys{db="db13"} 0
redis_db_keys{db="db14"} 0
redis_db_keys{db="db15"} 0
redis_db_keys{db="db2"} 0
redis_db_keys{db="db3"} 0
redis_db_keys{db="db4"} 0
redis_db_keys{db="db5"} 0
redis_db_keys{db="db6"} 0
redis_db_keys{db="db7"} 0
redis_db_keys{db="db8"} 0
redis_db_keys{db="db9"} 0
# HELP redis_db_keys_expiring Total number of expiring keys by DB
# TYPE redis_db_keys_expiring gauge
redis_db_keys_expiring{db="db0"} 0
redis_db_keys_expiring{db="db1"} 0
redis_db_keys_expiring{db="db10"} 0
redis_db_keys_expiring{db="db11"} 0
redis_db_keys_expiring{db="db12"} 0
redis_db_keys_expiring{db="db13"} 0
redis_db_keys_expiring{db="db14"} 0
redis_db_keys_expiring{db="db15"} 0
redis_db_keys_expiring{db="db2"} 0
redis_db_keys_expiring{db="db3"} 0
redis_db_keys_expiring{db="db4"} 0
redis_db_keys_expiring{db="db5"} 0
redis_db_keys_expiring{db="db6"} 0
redis_db_keys_expiring{db="db7"} 0
redis_db_keys_expiring{db="db8"} 0
redis_db_keys_expiring{db="db9"} 0

OKそうですね。

Prometheusからメトリクスを取得してみる

最後に、PrometheusからRedis Exporterが公開しているメトリクスを取り込んでみましょう。

prometheus.ymlを、こんな感じで作成。
prometheus.yml

global:
  scrape_interval:     5s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 5s # Evaluate rules every 15 seconds. The default is every 1 minute.

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  - job_name: 'redis'
    static_configs:
    - targets: ['172.17.0.2:9121']

Prometheusを起動して、Webコンソールで確認。

f:id:Kazuhira:20200414193104p:plain

f:id:Kazuhira:20200414193139p:plain

Prometheus側でも、Redis Exporterから取得したメトリクスが確認できました、と。