Redis CLI Validation Guide for Heimdall Cache Performance

This guide explains how to validate and troubleshoot Heimdall's cache behavior using the redis-cli tool. It applies to AWS ElastiCache Redis in both Cluster and Non-Cluster modes.


Table of Contents

  1. Prerequisites
  2. Installing Redis CLI
  3. Connecting to Redis
  4. Basic Cache Status Verification
  5. Cache Performance Validation
  6. Performance Metrics Validation
  7. Cache Invalidation Verification
  8. Performance Benchmarking
  9. Troubleshooting Guide
  10. Security Considerations

Prerequisites

Before using this guide, ensure you have:

  • Network access to your Redis instance
  • Appropriate security group/firewall rules configured
  • Redis endpoint information (hostname/IP and port)
  • Sufficient permissions to connect to Redis
  • Basic familiarity with command-line tools

Note: This guide assumes Heimdall is already configured and running with Redis caching enabled.


Installing Redis CLI

Linux (Ubuntu/Debian)

# Ubuntu/Debian
sudo apt update
sudo apt install redis-tools

# CentOS/RHEL/Amazon Linux
sudo yum install redis

# Or using dnf (newer versions)
sudo dnf install redis

macOS

# Using Homebrew
brew install redis

# Using MacPorts
sudo port install redis

Windows

Option 1: WSL (Recommended)

# Install WSL2 and Ubuntu, then:
sudo apt update
sudo apt install redis-tools

Option 2: Native Windows - Download Redis from: https://github.com/microsoftarchive/redis/releases - Extract and add to PATH, or use Docker:

docker run -it --rm redis:alpine redis-cli -h <redis-host> -p 6379

Docker (All Platforms)

# Quick redis-cli access without installation
docker run -it --rm redis:alpine redis-cli -h <redis-host> -p 6379

# Create alias for convenience
alias redis-cli='docker run -it --rm redis:alpine redis-cli'

Verify Installation

redis-cli --version

Expected Output:

redis-cli 6.x.x or 7.x.x

Connecting to Redis

Non-Cluster Mode

redis-cli -h <primary-endpoint> -p 6379

Cluster Mode

redis-cli -c -h <primary-endpoint> -p 6379

Note: The -c flag enables cluster redirection to handle hash slots. In cluster mode, pub/sub messages are shard-local. The subscriber and publisher must be on the same shard unless using sharded pub/sub.

Connection Parameters for Commands

All commands in this guide can be executed in two ways:

Method 1: Connect first, then run commands

# Connect to Redis instance
redis-cli -h <primary-endpoint> -p 6379
# Then run commands without connection parameters
CLIENT LIST | grep -E "(psub|sub)=[1-9]"

Method 2: Include connection parameters with each command

# Run commands with connection parameters
redis-cli -h <primary-endpoint> -p 6379 CLIENT LIST | grep -E "(psub|sub)=[1-9]"

For this guide: Examples will show Method 2 (connection parameters included) since it's more practical for validation scripts and remote instances.


1. Basic Cache Status Verification

Important: All commands in this section require connection to your Redis instance. Replace <primary-endpoint> with your actual Redis endpoint. For cluster mode, add the -c flag.

1.1 Check Active Connections and Subscriptions

# Verify Heimdall connections to Redis  
redis-cli -h <primary-endpoint> -p 6379 CLIENT LIST | grep -v "cmd=client"

Expected Output:

id=393 addr=172.31.xx.xxx:58234 laddr=172.31.xx.xx:6379 fd=25 name= age=1764 idle=24 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=2568 events=r cmd=info user=default redir=-1 resp=3
id=394 addr=172.31.xx.xxx:58240 laddr=172.31.xx.xx:6379 fd=28 name= age=1764 idle=1764 flags=P db=0 sub=0 psub=4 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=2664 events=r cmd=psubscribe user=default redir=-1 resp=3
id=395 addr=172.31.xx.xxx:58244 laddr=172.31.xx.xx:6379 fd=29 name= age=1764 idle=1764 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=2568 events=r cmd=publish user=default redir=-1 resp=3

Key indicators of healthy Heimdall connections: - Pattern subscriber (id=394): flags=P, psub=4, cmd=psubscribe → Cache invalidation listener - Info connection (id=393): cmd=info → Health monitoring - Publish connection (id=395): cmd=publish → Cache invalidation publisher

# Alternative: Filter to show only subscription connections
redis-cli -h <primary-endpoint> -p 6379 CLIENT LIST | grep -E "(psub|sub)=[1-9]"
# Check total pattern subscription count
redis-cli -h <primary-endpoint> -p 6379 PUBSUB NUMPAT

Expected Output:

(integer) 4

Info: This indicates Heimdall is listening on 4 pattern subscriptions for cache invalidation.

1.2 Verify Active Cache Keys

# Use SCAN (preferred in production; avoids blocking like KEYS)
redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100

Expected Output:

1) "0"
2) 1) "hdkey:7F1548AD7CC4D8FDA01F787EF48C7862"
   2) "hdkey:0781CCCD3B16C49A7CE30BAF8CD329F0"
   3) "hdkey:4678749E2159093D167CD8895405F1E0"
   4) "hdkey:E821C4B57C482228722661ED6ED1710A"

You should see 4–5 different cache keys for different query types: - JOIN queries - Department queries - Employee queries - Summary queries


2. Cache Performance Validation

2.1 Monitor Cache Hit/Miss Activity

# Monitor all cache-related operations
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "GET|SETEX|hdkey"

Look for: - GET hdkey:* → cache hits - SETEX hdkey:* → cache writes/refreshes - TTL of ~61 seconds on SETEX (or as configured in Heimdall)

2.2 Monitor Cache Miss/Refresh Events Only

# Focus on cache misses and refreshes
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E '"SETEX"' | grep 'hdkey:'

With timestamps for easier analysis:

# Add timestamps to monitor cache refresh patterns
stdbuf -oL -eL redis-cli -h <primary-endpoint> -p 6379 MONITOR | while read -r line; do
  if [[ $line == *'"SETEX"'* && $line == *'hdkey:'* ]]; then
    echo "$(date '+%H:%M:%S') - CACHE MISS/REFRESH: $line"
  fi
done

Pro Tip: Run the SETEX monitor in one terminal and a GET monitor in another terminal for side-by-side analysis:

# Terminal 1: Monitor GET operations (cache hits)
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E '"GET"' | grep 'hdkey:'

# Terminal 2: Monitor SETEX operations (cache misses/refreshes)
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E '"SETEX"' | grep 'hdkey:'

Important: Replace <primary-endpoint> with your actual Redis endpoint in all commands throughout this guide. For cluster mode, add -c flag: redis-cli -c -h <primary-endpoint> -p 6379

This side-by-side view helps correlate cache hits and refreshes in real-time.

2.3 Check Cache Key Details

# Replace with an actual cache key from your system
CACHE_KEY="hdkey:7F1548AD7CC4D8FDA01F787EF48C7862"

# Verify key existence
redis-cli -h <primary-endpoint> -p 6379 EXISTS $CACHE_KEY

# Check remaining time-to-live
redis-cli -h <primary-endpoint> -p 6379 TTL $CACHE_KEY

Expected Results: - EXISTS → 1 (key exists) - TTL → ≤ 61 seconds (or your configured TTL)

2.4 Validate Cache Refresh Patterns

# Monitor cache refresh timing with timestamps
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "SETEX.*hdkey" | while read line; do
  echo "$(date '+%H:%M:%S') - $line"
done

Expected Pattern: - Multiple SETEX operations after write operations - All relevant cache keys refreshed when related data changes


3. Performance Metrics Validation

3.1 Cache Hit Rate Calculation

echo "Monitoring cache operations for 60 seconds..."

# Capture GET operations for analysis
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "GET.*hdkey" > /tmp/redis_gets.log &
MONITOR_PID=$!
sleep 60
kill $MONITOR_PID

TOTAL_GETS=$(wc -l < /tmp/redis_gets.log)
echo "Total cache GET operations: $TOTAL_GETS"

# Clean up
rm -f /tmp/redis_gets.log

Expected Results: - High volume of GET operations matching Heimdall Analytics Cache Hit percentage

3.2 Validate Query-Specific Cache Keys

# Categorize cache operations by query type
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "SETEX.*hdkey" | while read line; do
  if [[ $line == *"departments"* ]] && [[ $line == *"employees"* ]]; then
    echo "JOIN/SUMMARY Query Cache: $line"
  elif [[ $line == *"departments"* ]]; then
    echo "Department Query Cache: $line"  
  elif [[ $line == *"employees"* ]]; then
    echo "Employee Query Cache: $line"
  fi
done

Expected Results: - Different cache keys for different query types - Appropriate refresh patterns based on query complexity


4. Cache Invalidation Verification

4.1 Test Write Operation Impact

echo "=== Before Write Operation ==="
redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100 | sort

# Start monitoring cache invalidation events
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "(DEL|SETEX).*hdkey" &
MONITOR_PID=$!

echo "Perform write operation in your application now..."
sleep 30
kill $MONITOR_PID

echo "=== After Write Operation ==="
redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100 | sort

Expected Results: - Same keys exist but with refreshed values - New SETEX operations with updated payloads

4.2 Validate Cross-Table Cache Invalidation

# Monitor specific cache key behavior
CACHE_KEY=$(redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100 | head -1)

echo "Monitoring key: $CACHE_KEY"
echo "Before: TTL=$(redis-cli -h <primary-endpoint> -p 6379 TTL $CACHE_KEY)"

# Track all operations on this specific key
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep "$CACHE_KEY" | while read line; do
  echo "$(date '+%H:%M:%S') - Cache activity: $line"
done

Expected Results: - Key gets refreshed (SETEX) after writes to related tables - Proper invalidation cascading across dependent queries


5. Performance Benchmarking

5.1 Measure Cache Response Times

# Get a sample cache key for testing
CACHE_KEY=$(redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100 | head -1)

echo "Testing response times for key: $CACHE_KEY"
echo "Response times (in milliseconds):"

for i in {1..10}; do
  start_time=$(date +%s%N)
  redis-cli -h <primary-endpoint> -p 6379 GET "$CACHE_KEY" > /dev/null
  end_time=$(date +%s%N)
  duration=$(( (end_time - start_time) / 1000000 ))
  echo "Response time: ${duration}ms"
done

Expected Results: - Sub-millisecond (0–2 ms) response times for local network - Consistent latency across multiple requests

5.2 Validate Cache vs Database Performance

# Monitor cache hit/miss patterns with timestamps
redis-cli -h <primary-endpoint> -p 6379 MONITOR | while read line; do
  if [[ $line == *"GET"* ]] && [[ $line == *"hdkey"* ]]; then
    echo "$(date '+%H:%M:%S') - CACHE HIT: $line"
  elif [[ $line == *"SETEX"* ]] && [[ $line == *"hdkey"* ]]; then  
    echo "$(date '+%H:%M:%S') - CACHE MISS/REFRESH: $line"
  fi
done

Expected Results: - Many GET operations (hits) versus fewer SETEX operations (misses/refreshes) - Higher ratio indicates better cache performance


6. Troubleshooting Guide

6.1 Low Cache Hit Rate (<50%)

Diagnosis:

# Check for excessive invalidation
redis-cli -h <primary-endpoint> -p 6379 MONITOR | grep -E "(DEL|EXPIRE).*hdkey"

Common Causes: - Too many DEL operations = over-invalidation - Check cache rules and invalidation mappings - Verify TTL consistency

# Check TTL values across all cache keys
redis-cli -h <primary-endpoint> -p 6379 SCAN 0 MATCH "hdkey:*" COUNT 100 | xargs -I {} redis-cli -h <primary-endpoint> -p 6379 TTL {}

6.2 No Cache Activity

Diagnosis:

# Test Redis connectivity
redis-cli -h <primary-endpoint> -p 6379 PING
# Should return: PONG

# Check for active Heimdall connections (same as section 1.1)
redis-cli -h <primary-endpoint> -p 6379 CLIENT LIST | grep -v "cmd=client"
# Should show pattern subscriber (flags=P, psub=4, cmd=psubscribe)

Common Causes: - Network connectivity issues - Heimdall not configured for Redis - Redis authentication problems

6.3 Performance Issues

Diagnosis:

# Check Redis memory usage
redis-cli -h <primary-endpoint> -p 6379 INFO memory | grep used_memory_human

# Monitor Redis latency
redis-cli -h <primary-endpoint> -p 6379 --latency -i 1

Common Causes: - High memory usage causing swapping - Network latency issues - Redis instance under-provisioned

6.4 Common Issues and Solutions

Connection Timeout

  • Symptoms: Can't connect to Redis, connection refused errors
  • Solution: Check security groups, network ACLs, and firewall rules

Authentication Failure

  • Symptoms: AUTH errors, permission denied messages
  • Solution: Verify Redis AUTH token configuration and credentials

Cluster Redirection Errors

  • Symptoms: MOVED responses, slot redirection messages
  • Solution: Use -c flag for cluster mode: redis-cli -c -h <endpoint> -p 6379

High Latency

  • Symptoms: Slow response times, timeouts
  • Solution: Check network connectivity, Redis instance resources, and memory usage

Cache Misses

  • Symptoms: Low hit rates, frequent cache refreshes
  • Solution: Review cache invalidation rules, TTL settings, and query patterns

7. Security Considerations

Warning: When monitoring Redis operations, be aware of the following security considerations:

  • Sensitive Data: The MONITOR command can expose cached data. Use in development/testing environments only.
  • Production Safety: Avoid running MONITOR in production for extended periods as it can impact performance.
  • Network Security: Ensure Redis access is properly secured with appropriate firewall rules.
  • Authentication: Use Redis AUTH if available and store credentials securely.
  • Log Management: Do not log sensitive cache contents to persistent storage.

Document Version: 1.0
Feedback: Please report any issues or suggestions for this guide to the Heimdall documentation team.