redis-keyspace-stats

Crates.ioredis-keyspace-stats
lib.rsredis-keyspace-stats
version0.5.4
sourcesrc
created_at2020-12-08 01:24:36.725521
updated_at2023-04-21 01:22:53.590563
descriptionAnalyzes your Redis keyspace and returns statistics about it
homepage
repositoryhttps://github.com/scott113341/redis-keyspace-stats
max_upload_size
id320676
size72,174
Scott Hardy (scott113341)

documentation

README

redis-keyspace-stats

This program analyzes your Redis keyspace and returns statistics about it. It's somewhat flexible. Usually, you'll provide glob-style patterns to group keys into bins.

This tool is under development, and some obviously useful features are not yet implemented.

Sampling modes:

  • βœ…Β Β Random sampling
  • 🚧  Random sampling of keys matching a pattern
  • βœ…Β Β Scan all keys
  • 🚧  Scan all keys matching a pattern

Statistics:

  • βœ…Β Β Memory: total, total estimated, 50/90/99th percentiles
  • βœ…Β Β TTL: percent with a TTL, 50/90/99th percentiles
  • βœ…Β Β Data type breakdown

Output formats:

  • βœ…Β Β Summary pretty-printed table to STDOUT
  • 🚧  Summary CSV/TSV
  • 🚧  Summary HTML
  • 🚧  Raw data CSV/TSV

Redis support:

  • βœ…Β Β Over TLS (rediss:// connection strings)
  • βœ…Β Β Logical databases, specified in the connection string (redis://host:port/db)
  • 🚧  Clusters

⚠️ Warnings

  • This is NOT production-grade software (yet?). Use at your own risk.
  • Redis is single-threaded, so be careful about running this against busy production systems. This tool sends commands to Redis in batches (and sleeps between them) to reduce its impact, but caution should still be exercised. Start with a small sample size, like the default -n 100 before running more comprehensive analysis.
  • Use the --sample=all mode with care; the -n option is ignored and ALL keys will be enumerated with SCAN
  • This tool fetches keys, and includes a handful of them in its output. While it's rare to store sensitive information in Redis keys, it's worth noting. Values are never fetched or included in any output.
  • The flags/options/organization/etc of the CLI will change as more sampling modes and other features are added

Installation

For now, there are no published binaries of this tool.

  1. Make sure you have Rust installed, or get it via rustup
  2. Run cargo install redis-keyspace-stats to download + compile the binary

Usage examples

Invoking the CLI with -h (or --help, which is more verbose) will print documentation:

$ redis-keyspace-stats -h
Usage: redis-keyspace-stats [OPTIONS] [PATTERNS]...

Arguments:
  [PATTERNS]...  Glob-style patterns to group keys together

Options:
      --sample <SAMPLE_MODE>             [default: random] [possible values: all, random]
  -n, --samples <N_SAMPLES>              Ignored when --sample=all is specified [default: 100]
      --batch-size <BATCH_SIZE>          [default: 100]
      --batch-sleep-ms <BATCH_SLEEP_MS>  [default: 100]
      --stats <STATS>                    [default: memory,ttl] [possible values: memory, ttl, type]
  -o, --out <OUTPUT_MODE>                [default: table] [possible values: table]
      --url <URL>                        [default: redis://127.0.0.1]
  -h, --help                             Print help
  -V, --version                          Print version

Let's get some quick memory + TTL stats, sampling 50 keys:

$ redis-keyspace-stats --url $REDIS_URL -n 50
Sampled 50 of 128 keys in db0
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Pattern β”‚ Keys           β”‚ Example keys       β”‚ Memory                 β”‚ TTL             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ *       β”‚ 50 counted     β”‚ company:121#memes  β”‚ 360.77 kB (sum)        β”‚ 54.00% have TTL β”‚
β”‚         β”‚ 128 est. total β”‚ user:79#memes      β”‚ 923.57 kB (est. total) β”‚ 2m 47s (p50)    β”‚
β”‚         β”‚                β”‚ user:8#memes       β”‚ 7.75 kB (p50)          β”‚ 3m 57s (p90)    β”‚
β”‚         β”‚                β”‚ user:92#friends    β”‚ 11.9 kB (p90)          β”‚ 4m 13s (p99)    β”‚
β”‚         β”‚                β”‚ company:84#friends β”‚ 12.87 kB (p99)         β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Using what's showing in the "Example keys" column, let's write a few glob-style patterns to bin keys together:

$ redis-keyspace-stats --url $REDIS_URL -n 50 'user:*#messages' 'user:?#*' 'company:*'
Sampled 50 of 128 keys in db0
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Pattern         β”‚ Keys          β”‚ Example keys       β”‚ Memory                 β”‚ TTL              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ user:*#messages β”‚ 8 counted     β”‚ user:27#messages   β”‚ 30.27 kB (sum)         β”‚ 37.50% have TTL  β”‚
β”‚                 β”‚ 20 est. total β”‚ user:34#messages   β”‚ 77.5 kB (est. total)   β”‚ 1m 30s (p50)     β”‚
β”‚                 β”‚               β”‚ user:13#messages   β”‚ 3.4 kB (p50)           β”‚ 3m 25s (p90)     β”‚
β”‚                 β”‚               β”‚ user:58#messages   β”‚ 6.22 kB (p90)          β”‚ 3m 51s (p99)     β”‚
β”‚                 β”‚               β”‚ user:60#messages   β”‚ 6.22 kB (p99)          β”‚                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ user:?#*        β”‚ 2 counted     β”‚ user:3#friends     β”‚ 1.25 kB (sum)          β”‚ 100.00% have TTL β”‚
β”‚                 β”‚ 5 est. total  β”‚ user:8#memes       β”‚ 3.19 kB (est. total)   β”‚ 1m 52s (p50)     β”‚
β”‚                 β”‚               β”‚                    β”‚ 624 B (p50)            β”‚ 2m 39s (p90)     β”‚
β”‚                 β”‚               β”‚                    β”‚ 822.4 B (p90)          β”‚ 2m 50s (p99)     β”‚
β”‚                 β”‚               β”‚                    β”‚ 867.04 B (p99)         β”‚                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ company:*       β”‚ 24 counted    β”‚ company:1#messages β”‚ 162.13 kB (sum)        β”‚ 45.83% have TTL  β”‚
β”‚                 β”‚ 61 est. total β”‚ company:75#memes   β”‚ 415.05 kB (est. total) β”‚ 2m 51s (p50)     β”‚
β”‚                 β”‚               β”‚ company:10#friends β”‚ 7.24 kB (p50)          β”‚ 3m 58s (p90)     β”‚
β”‚                 β”‚               β”‚ company:69#memes   β”‚ 11.85 kB (p90)         β”‚ 4m 2s (p99)      β”‚
β”‚                 β”‚               β”‚ company:6#memes    β”‚ 12.64 kB (p99)         β”‚                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ *               β”‚ 16 counted    β”‚ user:123#memes     β”‚ 149.02 kB (sum)        β”‚ 31.25% have TTL  β”‚
β”‚                 β”‚ 41 est. total β”‚ user:71#friends    β”‚ 381.5 kB (est. total)  β”‚ 2m 10s (p50)     β”‚
β”‚                 β”‚               β”‚ user:25#friends    β”‚ 10.05 kB (p50)         β”‚ 2m 59s (p90)     β”‚
β”‚                 β”‚               β”‚ user:86#memes      β”‚ 12.86 kB (p90)         β”‚ 3m 4s (p99)      β”‚
β”‚                 β”‚               β”‚ user:110#friends   β”‚ 13.29 kB (p99)         β”‚                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Note that the first pattern that matches a key will determine the group.

Development

Testing locally

  • Seed some fake test data via environment variable: RKS_SEED_FAKE_DATA=true cargo run -- --sample=all 'company:*'
  • Starting the redis-cli binary and running monitor can be useful for debugging

Releasing

  1. Bump the version in Cargo.toml
  2. Run cargo test
  3. Commit, add a git tag for the release, and push
  4. Run cargo publish
Commit count: 40

cargo fmt