Advanced Redis Operations Cheatsheet

Table of Contents

Advanced Redis Operations Cheatsheet – Technical Deep Dive



Comprehensive technical reference for enterprise Redis operations, performance optimization, and production management.

Version Compatibility Note: This guide covers Redis 6.0+ features unless otherwise specified. For Redis 5.x compatibility, see legacy sections marked with 🔄.

1. Redis Installation & Advanced Configuration

Multi-Platform Installation with Build Optimization

# Ubuntu/Debian with performance optimizations
sudo apt update && sudo apt install redis-server redis-tools
sudo sysctl vm.overcommit_memory=1
echo 'vm.overcommit_memory = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.core.somaxconn = 65535' | sudo tee -a /etc/sysctl.conf

# CentOS/RHEL with THP (Transparent Huge Pages) disabled
sudo yum install epel-release && sudo yum install redis
echo 'never' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local

# High-performance Docker deployment with memory optimization
docker run -d --name redis-prod \
  --sysctl net.core.somaxconn=65535 \
  --ulimit memlock=-1:-1 \
  --memory=4g --memory-swap=4g \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:7-alpine redis-server \
  --maxmemory 3.5gb \
  --maxmemory-policy allkeys-lru \
  --tcp-backlog 511 \
  --timeout 0 \
  --tcp-keepalive 300

# Compile from source with optimizations
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz && cd redis-stable
make MALLOC=jemalloc CFLAGS="-O3 -march=native"
sudo make install PREFIX=/opt/redis

# Error handling for installation
if ! redis-cli ping >/dev/null 2>&1; then
    echo "ERROR: Redis installation failed or service not running"
    systemctl status redis-server
    exit 1
fi

Production-Grade Configuration Parameters

# Network and connection management
bind 0.0.0.0
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
protected-mode yes
maxclients 10000

# Memory management and optimization
maxmemory 4gb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# Redis 4.0+ active defragmentation
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100
active-defrag-cycle-min 1
active-defrag-cycle-max 25

# Persistence optimization
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis/

# AOF configuration for durability
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
# Redis 4.0+ hybrid persistence
aof-use-rdb-preamble yes

# Logging and debugging
loglevel notice
logfile /var/log/redis/redis-server.log
syslog-enabled yes
syslog-ident redis

# Advanced tuning (version-specific)
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
# Redis 5.0+ stream configuration
stream-node-max-bytes 4096
stream-node-max-entries 100

2. Advanced Data Structures & Complex Operations

String Operations with Advanced Patterns

# Atomic operations with conditional execution
SET user:session:12345 "active" EX 3600 NX
SETEX cache:user:profile:123 900 '{"name":"John","role":"admin"}'
GETSET counter:requests:api 0  # Atomic read-and-reset

# Bit operations for efficient storage (Redis 2.2+)
SETBIT user:active:20240101 12345 1  # Mark user 12345 as active
BITCOUNT user:active:20240101        # Count active users
BITOP AND result user:premium user:active  # Premium AND active users

# Redis 3.2+ BITFIELD for packed integers
BITFIELD mykey SET u8 0 255 INCRBY u8 8 1  # Packed integer operations

# String manipulation with memory efficiency
APPEND log:session:123 "2024-06-16T10:30:00Z - User login\n"
STRLEN log:session:123
GETRANGE log:session:123 0 19  # Get timestamp portion

# Error handling example
if ! redis-cli EXISTS user:session:12345 >/dev/null 2>&1; then
    echo "Session not found, creating new session"
fi

Hash Operations with Memory Optimization

# Field-level operations with expiration simulation
HSET user:profile:123 name "John Doe" email "john@example.com" last_seen 1718541000
HMSET user:settings:123 theme "dark" notifications "true" timezone "UTC"
HGETALL user:profile:123
HKEYS user:profile:123
HVALS user:profile:123
HLEN user:profile:123

# Memory-efficient field management
HSETNX user:profile:123 created_at 1718541000  # Set only if field doesn't exist
HINCRBY user:stats:123 login_count 1
HINCRBYFLOAT user:metrics:123 avg_session_time 0.5

# 🔄 Redis 5.x: Use HMSET instead of HSET for multiple fields
# Redis 6.0+: HSET supports multiple field-value pairs

# Scanning large hashes efficiently (Redis 2.8+)
HSCAN user:large_profile:123 0 MATCH "*_count" COUNT 100

List Operations for Queue Management

# High-performance queue operations
LPUSH queue:tasks '{"id":1,"type":"email","priority":1}'
RPOPLPUSH queue:tasks queue:processing  # Atomic move to processing
LINSERT queue:tasks BEFORE '{"id":2}' '{"id":1.5,"urgent":true}'

# Reliable queue with blocking operations (Redis 2.0+)
BLPOP queue:high_priority queue:normal 30  # Block for 30 seconds
BRPOPLPUSH queue:tasks queue:processing 60  # Reliable queue pattern

# List maintenance and monitoring
LLEN queue:tasks
LRANGE queue:tasks 0 9    # Preview first 10 tasks
LTRIM queue:completed -100 -1  # Keep only last 100 completed tasks

# Error handling for queue operations
#!/bin/bash
queue_push_safe() {
    local queue=$1
    local item=$2
    if redis-cli LPUSH "$queue" "$item" >/dev/null 2>&1; then
        echo "Item added to queue successfully"
    else
        echo "ERROR: Failed to add item to queue $queue"
        return 1
    fi
}

Set Operations for Complex Logic

# Advanced set operations for analytics
SADD users:premium 123 456 789
SADD users:active:today 123 234 345 456
SINTER users:premium users:active:today  # Premium users active today
SINTERSTORE temp:premium_active users:premium users:active:today

# Probabilistic data structures
SADD unique:visitors:today 192.168.1.1 10.0.0.5
SCARD unique:visitors:today  # Approximate unique visitor count
SRANDMEMBER unique:visitors:today 5  # Sample 5 random visitors

# Set comparison and analysis
SDIFF users:all users:active:today  # Inactive users
SUNIONSTORE users:engagement users:premium users:active:today users:recent_purchasers

Sorted Sets for Advanced Ranking

# Time-series and leaderboard operations
ZADD leaderboard:game:123 1000 "player1" 950 "player2" 1200 "player3"
ZREVRANGE leaderboard:game:123 0 9 WITHSCORES  # Top 10 with scores
ZRANGEBYSCORE leaderboard:game:123 900 1100 WITHSCORES LIMIT 0 5

# Time-based data with millisecond precision
ZADD events:user:123 1718541000000 "login" 1718541300000 "page_view"
ZREMRANGEBYSCORE events:user:123 0 $(( $(date +%s) * 1000 - 86400000 ))  # Remove events older than 24h

# Advanced sorted set operations (Redis 2.8+)
ZINTERSTORE temp:common_interests 2 interests:user:123 interests:user:456 WEIGHTS 1 1
ZLEXCOUNT dictionary:words [a [b  # Count words starting with 'a'
ZRANGEBYLEX dictionary:words [a [b LIMIT 0 10

# Redis 6.2+ range operations
# ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]

3. Performance Monitoring & Advanced Metrics

⚠️ Performance Impact Warning: Monitoring commands like MONITOR and frequent INFO calls can impact Redis performance. Use judiciously in production.

Comprehensive Memory Analysis

# Detailed memory breakdown
INFO memory
MEMORY USAGE keyname SAMPLES 5000  # Accurate memory usage with sampling (Redis 4.0+)
MEMORY DOCTOR  # Memory optimization recommendations (Redis 4.0+)
MEMORY PURGE   # Force memory defragmentation (Redis 4.0+)

# Advanced memory monitoring with error handling
#!/bin/bash
analyze_memory_safely() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    
    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis at $redis_host:$redis_port"
        return 1
    fi
    
    echo "Analyzing memory usage (this may take time)..."
    redis-cli -h "$redis_host" -p "$redis_port" --bigkeys --bigkeys-samples 1000000 2>/dev/null
    redis-cli -h "$redis_host" -p "$redis_port" --memkeys --memkeys-samples 1000000 2>/dev/null
}

# Memory configuration analysis
CONFIG GET "*memory*"
CONFIG GET "*maxmemory*"
CONFIG SET maxmemory-samples 10  # Improve LRU precision

Advanced Performance Metrics

# Comprehensive stats analysis
INFO all | grep -E "(instantaneous_ops_per_sec|keyspace_hits|keyspace_misses|expired_keys|evicted_keys)"
INFO commandstats | sort -k2 -nr  # Most used commands
INFO clients | grep -E "(connected_clients|client_recent_max_input_buffer|client_recent_max_output_buffer)"

# Latency monitoring and analysis (Redis 2.8.13+)
CONFIG SET latency-monitor-threshold 50  # Monitor operations > 50ms
LATENCY LATEST
LATENCY HISTORY command-name
LATENCY DOCTOR  # Latency analysis and recommendations
redis-cli --latency-history -i 1  # Real-time latency monitoring

# Slow query analysis
CONFIG SET slowlog-log-slower-than 10000  # Log queries > 10ms
CONFIG SET slowlog-max-len 1000
SLOWLOG GET 100
SLOWLOG LEN
SLOWLOG RESET

# Performance monitoring script with error handling
#!/bin/bash
monitor_redis_performance() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local interval=${3:-5}

    while true; do
        if redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
            local ops=$(redis-cli -h "$redis_host" -p "$redis_port" INFO stats | grep instantaneous_ops_per_sec | cut -d: -f2 | tr -d '\r')
            local memory=$(redis-cli -h "$redis_host" -p "$redis_port" INFO memory | grep used_memory_human | cut -d: -f2 | tr -d '\r')
            echo "$(date): OPS/sec: $ops, Memory: $memory"
        else
            echo "$(date): ERROR - Redis connection failed"
        fi
        sleep "$interval"
    done
}

Network and Connection Monitoring

# Client connection analysis
CLIENT LIST TYPE normal
CLIENT LIST TYPE replica
# Redis 6.0+ client tracking
CLIENT TRACKING ON  # Enable client-side caching tracking
CLIENT GETREDIR    # Get redirection client for tracking

# Connection pool monitoring
INFO stats | grep -E "(total_connections_received|rejected_connections)"
CONFIG GET maxclients
CLIENT SETNAME "webapp-pool-1"  # Name connections for monitoring

# Connection health check with error handling
#!/bin/bash
check_connection_health() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local max_clients_threshold=${3:-8000}

    local connected_clients
    connected_clients=$(redis-cli -h "$redis_host" -p "$redis_port" INFO clients 2>/dev/null | grep connected_clients | cut -d: -f2 | tr -d '\r')

    if [ $? -ne 0 ]; then
        echo "ERROR: Failed to get client connection info"
        return 1
    fi

    if [ "$connected_clients" -gt "$max_clients_threshold" ]; then
        echo "WARNING: High client connections: $connected_clients"
        return 1
    fi

    echo "OK: Client connections: $connected_clients"
    return 0
}

4. Enterprise Security & Advanced Authentication

Advanced ACL Management (Redis 6.0+)

# Granular user permissions with error handling
create_api_user() {
    if redis-cli ACL SETUSER api_user on >complex_password_123 ~api:* ~cache:* +@read +@hash +@string -@dangerous 2>/dev/null; then
        echo "API user created successfully"
    else
        echo "ERROR: Failed to create API user"
        return 1
    fi
}

ACL SETUSER analytics_user on >analytics_pass ~analytics:* ~metrics:* +@read +@sortedset +@bitmap
ACL SETUSER backup_user on >backup_secure_pass ~* +@read +@admin +bgsave +lastsave

# Role-based access patterns
ACL SETUSER readonly_role on >readonly_pass ~* +@read -@write -@admin
ACL SETUSER write_cache_role on >cache_pass ~cache:* ~session:* +@all -@admin -@dangerous
ACL SETUSER admin_role on >admin_super_secure_pass ~* +@all

# ACL management with validation
#!/bin/bash
validate_acl_setup() {
    if ! redis-cli ACL LIST >/dev/null 2>&1; then
        echo "ERROR: ACL not supported (requires Redis 6.0+)"
        return 1
    fi

    echo "Current ACL users:"
    redis-cli ACL LIST

    # Test user authentication
    if redis-cli -u redis://api_user:complex_password_123@localhost:6379 ping >/dev/null 2>&1; then
        echo "✓ API user authentication successful"
    else
        echo "✗ API user authentication failed"
    fi
}

# ACL categories and command filtering
ACL CAT  # List all command categories
ACL CAT dangerous  # Show dangerous commands
ACL DELUSER temp_user
ACL SAVE  # Persist ACL configuration
ACL LOAD  # Reload ACL from file

Network Security Hardening

# Multi-interface binding with security
bind 127.0.0.1 10.0.0.100 192.168.1.100
protected-mode yes
port 6379
timeout 300

# TLS encryption configuration (Redis 6.0+)
port 0  # Disable non-TLS port
tls-port 6380
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-protocols "TLSv1.2 TLSv1.3"
tls-ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"

# Command security with secure random names
generate_secure_command_names() {
    local config_file="/etc/redis/redis.conf"

    # Generate secure random suffixes
    local flush_suffix=$(openssl rand -hex 16)
    local config_suffix=$(openssl rand -hex 16)

    cat >> "$config_file" << EOF
rename-command FLUSHDB "FLUSHDB_DANGER_${flush_suffix}"
rename-command FLUSHALL "FLUSHALL_DANGER_${flush_suffix}"
rename-command CONFIG "CONFIG_ADMIN_${config_suffix}"
rename-command EVAL "EVAL_SCRIPT_${config_suffix}"
rename-command DEBUG ""  # Completely disable
EOF

    echo "Secure command names generated and saved to $config_file"
}

# 🔄 Legacy Redis 5.x: TLS requires compilation with TLS support

5. Advanced Persistence & Backup Strategies

RDB Optimization and Management

# Advanced RDB configuration
save 900 1      # Save if at least 1 key changed in 900 seconds
save 300 10     # Save if at least 10 keys changed in 300 seconds
save 60 10000   # Save if at least 10000 keys changed in 60 seconds
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
# Redis 6.2+ security feature
sanitize-dump-payload yes

# RDB backup automation with comprehensive error handling
#!/bin/bash
backup_redis_rdb() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local backup_dir="/backup/redis/$(date +%Y-%m-%d)"
    local max_wait_time=300  # 5 minutes
    local wait_count=0

    # Validate Redis connection
    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis at $redis_host:$redis_port"
        return 1
    fi

    # Create backup directory
    if ! mkdir -p "$backup_dir"; then
        echo "ERROR: Cannot create backup directory $backup_dir"
        return 1
    fi

    # Get last save time before backup
    local last_save_before
    last_save_before=$(redis-cli -h "$redis_host" -p "$redis_port" LASTSAVE 2>/dev/null)
    if [ $? -ne 0 ]; then
        echo "ERROR: Failed to get LASTSAVE timestamp"
        return 1
    fi

    # Initiate background save
    echo "Initiating RDB backup..."
    if ! redis-cli -h "$redis_host" -p "$redis_port" BGSAVE >/dev/null 2>&1; then
        echo "ERROR: BGSAVE command failed"
        return 1
    fi

    # Wait for backup to complete
    while [ $wait_count -lt $max_wait_time ]; do
        local current_save
        current_save=$(redis-cli -h "$redis_host" -p "$redis_port" LASTSAVE 2>/dev/null)

        if [ "$current_save" -gt "$last_save_before" ]; then
            echo "Backup completed successfully"
            break
        fi

        sleep 1
        ((wait_count++))
    done

    if [ $wait_count -eq $max_wait_time ]; then
        echo "ERROR: Backup timeout after ${max_wait_time} seconds"
        return 1
    fi

    # Copy RDB file
    local rdb_file="/var/lib/redis/dump.rdb"
    local backup_file="$backup_dir/dump-$(date +%H%M%S).rdb"

    if cp "$rdb_file" "$backup_file"; then
        echo "RDB file copied to $backup_file"

        # Verify backup integrity
        if redis-check-rdb "$backup_file" >/dev/null 2>&1; then
            echo "✓ Backup integrity verified"
            return 0
        else
            echo "✗ Backup integrity check failed"
            return 1
        fi
    else
        echo "ERROR: Failed to copy RDB file"
        return 1
    fi
}

# RDB integrity verification
redis-check-rdb /backup/redis/dump.rdb

AOF Advanced Configuration and Management

# High-performance AOF setup
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec  # Balance between performance and durability
no-appendfsync-on-rewrite yes  # Prevent fsync during rewrite
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
# Redis 4.0+ hybrid persistence for faster restarts
aof-use-rdb-preamble yes

# AOF maintenance with error handling
#!/bin/bash
maintain_aof() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local aof_file="/var/lib/redis/appendonly.aof"

    # Check AOF integrity
    echo "Checking AOF integrity..."
    if redis-check-aof "$aof_file" >/dev/null 2>&1; then
        echo "✓ AOF file is intact"
    else
        echo "✗ AOF file corruption detected"
        echo "Attempting automatic repair..."

        # Backup corrupted file
        cp "$aof_file" "${aof_file}.corrupted.$(date +%s)"

        # Attempt repair
        if redis-check-aof --fix "$aof_file"; then
            echo "✓ AOF file repaired successfully"
        else
            echo "✗ AOF repair failed - manual intervention required"
            return 1
        fi
    fi

    # Trigger AOF rewrite if connected
    if redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "Triggering AOF rewrite..."
        redis-cli -h "$redis_host" -p "$redis_port" BGREWRITEAOF
    fi
}

# Multi-part AOF (Redis 7.0+)
aof-rewrite-incremental-fsync yes
aof-timestamp-enabled yes

6. Redis Clustering & High Availability

Advanced Cluster Configuration

# Cluster creation with comprehensive error handling
#!/bin/bash
create_redis_cluster() {
    local nodes=("$@")
    local min_nodes=6

    if [ ${#nodes[@]} -lt $min_nodes ]; then
        echo "ERROR: Minimum $min_nodes nodes required for cluster"
        return 1
    fi

    # Validate all nodes are accessible
    echo "Validating cluster nodes..."
    for node in "${nodes[@]}"; do
        if ! redis-cli -h "${node%:*}" -p "${node#*:}" ping >/dev/null 2>&1; then
            echo "ERROR: Node $node is not accessible"
            return 1
        fi
    done

    # Create cluster
    echo "Creating Redis cluster with nodes: ${nodes[*]}"
    if redis-cli --cluster create "${nodes[@]}" --cluster-replicas 1 --cluster-yes; then
        echo "✓ Cluster created successfully"

        # Verify cluster status
        redis-cli --cluster check "${nodes[0]}"
        return 0
    else
        echo "✗ Cluster creation failed"
        return 1
    fi
}

# Cluster slot management with error handling
manage_cluster_slots() {
    local node=${1:-localhost:6379}

    echo "Cluster slot distribution:"
    if redis-cli -c -h "${node%:*}" -p "${node#*:}" CLUSTER NODES 2>/dev/null; then
        echo "Cluster status retrieved successfully"
    else
        echo "ERROR: Failed to get cluster status"
        return 1
    fi

    # Additional cluster info
    redis-cli -c -h "${node%:*}" -p "${node#*:}" CLUSTER SLOTS 2>/dev/null
    redis-cli -c -h "${node%:*}" -p "${node#*:}" CLUSTER INFO 2>/dev/null
}

# Dynamic cluster management
redis-cli --cluster add-node new-node:6379 existing-node:6379
redis-cli --cluster del-node existing-node:6379 node-id
redis-cli --cluster reshard existing-node:6379 --cluster-from source-node-id --cluster-to target-node-id --cluster-slots 1000
redis-cli --cluster rebalance existing-node:6379 --cluster-weight node1=2 node2=1

Sentinel High Availability

# Sentinel configuration with error handling
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster your_redis_password
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

# Sentinel management with comprehensive monitoring
#!/bin/bash
monitor_sentinel() {
    local sentinel_host=${1:-localhost}
    local sentinel_port=${2:-26379}
    local master_name=${3:-mymaster}

    if ! redis-cli -h "$sentinel_host" -p "$sentinel_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Sentinel at $sentinel_host:$sentinel_port"
        return 1
    fi

    echo "=== Sentinel Status ==="
    redis-cli -h "$sentinel_host" -p "$sentinel_port" SENTINEL masters
    redis-cli -h "$sentinel_host" -p "$sentinel_port" SENTINEL slaves "$master_name"
    redis-cli -h "$sentinel_host" -p "$sentinel_port" SENTINEL sentinels "$master_name"

    # Check master address
    local master_addr
    master_addr=$(redis-cli -h "$sentinel_host" -p "$sentinel_port" SENTINEL get-master-addr-by-name "$master_name" 2>/dev/null)
    if [ $? -eq 0 ]; then
        echo "Current master: $master_addr"
    else
        echo "ERROR: Failed to get master address for $master_name"
        return 1
    fi
}

# Manual failover with validation
perform_failover() {
    local sentinel_host=${1:-localhost}
    local sentinel_port=${2:-26379}
    local master_name=${3:-mymaster}

    echo "Initiating manual failover for $master_name..."
    if redis-cli -h "$sentinel_host" -p "$sentinel_port" SENTINEL failover "$master_name" 2>/dev/null; then
        echo "✓ Failover initiated successfully"

        # Wait and verify
        sleep 5
        monitor_sentinel "$sentinel_host" "$sentinel_port" "$master_name"
    else
        echo "✗ Failover failed"
        return 1
    fi
}

Advanced Replication Configuration

# Master configuration for optimal replication
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync yes  # For fast networks
repl-diskless-sync-delay 5
# Redis 6.0+ feature
repl-diskless-load swapdb
repl-ping-replica-period 10
repl-timeout 60
repl-disable-tcp-nodelay no
repl-backlog-size 1mb
repl-backlog-ttl 3600

# Replication monitoring with comprehensive error handling
#!/bin/bash
monitor_replication() {
    local master_host=${1:-localhost}
    local master_port=${2:-6379}
    local replica_host=${3:-localhost}
    local replica_port=${4:-6380}

    echo "=== Master Status ==="
    if redis-cli -h "$master_host" -p "$master_port" INFO replication 2>/dev/null; then
        echo "✓ Master replication info retrieved"
    else
        echo "✗ Failed to connect to master"
        return 1
    fi

    echo "=== Replica Status ==="
    if redis-cli -h "$replica_host" -p "$replica_port" INFO replication 2>/dev/null; then
        echo "✓ Replica replication info retrieved"

        # Check replication lag
        local lag
        lag=$(redis-cli -h "$replica_host" -p "$replica_port" INFO replication | grep master_repl_offset | cut -d: -f2 | tr -d '\r')
        if [ "$lag" -gt 1000 ]; then
            echo "⚠️  WARNING: High replication lag detected: $lag"
        fi
    else
        echo "✗ Failed to connect to replica"
        return 1
    fi
}

# Setup replication with validation
setup_replication() {
    local master_host=$1
    local master_port=$2
    local replica_host=$3
    local replica_port=$4

    echo "Setting up replication: $replica_host:$replica_port -> $master_host:$master_port"

    if redis-cli -h "$replica_host" -p "$replica_port" REPLICAOF "$master_host" "$master_port" 2>/dev/null; then
        echo "✓ Replication setup initiated"

        # Wait for initial sync
        local sync_complete=false
        local wait_count=0
        local max_wait=60

        while [ $wait_count -lt $max_wait ] && [ "$sync_complete" = false ]; do
            local sync_status
            sync_status=$(redis-cli -h "$replica_host" -p "$replica_port" INFO replication | grep master_sync_in_progress:0)
            if [ -n "$sync_status" ]; then
                sync_complete=true
                echo "✓ Initial synchronization completed"
            else
                sleep 1
                ((wait_count++))
            fi
        done

        if [ "$sync_complete" = false ]; then
            echo "⚠️  WARNING: Initial sync taking longer than expected"
        fi
    else
        echo "✗ Replication setup failed"
        return 1
    fi
}

7. Advanced Troubleshooting & Diagnostics

Connection and Network Diagnostics

# Comprehensive connection testing with detailed error reporting
#!/bin/bash
test_redis_connectivity() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local timeout=${3:-5}

    echo "Testing Redis connectivity to $redis_host:$redis_port..."

    # Basic network connectivity
    if timeout "$timeout" bash -c "</dev/tcp/$redis_host/$redis_port" 2>/dev/null; then
        echo "✓ Network connection successful"
    else
        echo "✗ Network connection failed"
        echo "Checking if Redis service is running..."
        ss -tlnp | grep ":$redis_port " || echo "Port $redis_port not listening"
        return 1
    fi

    # Redis protocol test
    if redis-cli -h "$redis_host" -p "$redis_port" --connect-timeout "$timeout" ping >/dev/null 2>&1; then
        echo "✓ Redis protocol response successful"
    else
        echo "✗ Redis protocol response failed"

        # Check authentication requirement
        if redis-cli -h "$redis_host" -p "$redis_port" --connect-timeout "$timeout" INFO 2>&1 | grep -q "NOAUTH"; then
            echo "Authentication required - check password configuration"
        fi
        return 1
    fi

    # Latency test
    echo "Testing latency..."
    redis-cli -h "$redis_host" -p "$redis_port" --latency -i 1 -c 10 2>/dev/null
}

# Network diagnostics
ss -tlnp | grep 6379  # Check listening sockets
netstat -an | grep 6379
# Use with caution in production
# tcpdump -i any port 6379  # Packet capture for debugging

# Client connection analysis with error handling
analyze_connections() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}

    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis"
        return 1
    fi

    echo "=== Connection Analysis ==="
    local normal_clients
    normal_clients=$(redis-cli -h "$redis_host" -p "$redis_port" CLIENT LIST TYPE normal 2>/dev/null | wc -l)
    local replica_clients
    replica_clients=$(redis-cli -h "$redis_host" -p "$redis_port" CLIENT LIST TYPE replica 2>/dev/null | wc -l)

    echo "Normal clients: $normal_clients"
    echo "Replica clients: $replica_clients"

    # Check for connection limits
    local max_clients
    max_clients=$(redis-cli -h "$redis_host" -p "$redis_port" CONFIG GET maxclients 2>/dev/null | tail -n1)
    if [ "$normal_clients" -gt $((max_clients * 80 / 100)) ]; then
        echo "⚠️  WARNING: Approaching connection limit ($normal_clients/$max_clients)"
    fi
}

Memory and Performance Diagnostics

# Advanced memory analysis with comprehensive error handling
#!/bin/bash
diagnose_memory_issues() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local sample_size=${3:-10000000}

    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis"
        return 1
    fi

    echo "=== Memory Diagnostics ==="

    # Basic memory info
    local memory_info
    memory_info=$(redis-cli -h "$redis_host" -p "$redis_port" INFO memory 2>/dev/null)
    if [ $? -ne 0 ]; then
        echo "ERROR: Failed to get memory info"
        return 1
    fi

    echo "$memory_info" | grep -E "(used_memory_human|used_memory_rss_human|mem_fragmentation_ratio)"

    # Memory usage by data type
    echo "Analyzing key distribution (this may take time)..."
    if command -v timeout >/dev/null 2>&1; then
        timeout 300 redis-cli -h "$redis_host" -p "$redis_port" --bigkeys --bigkeys-samples "$sample_size" 2>/dev/null
    else
        redis-cli -h "$redis_host" -p "$redis_port" --bigkeys --bigkeys-samples "$sample_size" 2>/dev/null
    fi

    # Redis 4.0+ memory analysis
    if redis-cli -h "$redis_host" -p "$redis_port" MEMORY DOCTOR >/dev/null 2>&1; then
        echo "=== Memory Doctor Recommendations ==="
        redis-cli -h "$redis_host" -p "$redis_port" MEMORY DOCTOR
    fi
}

# Performance profiling with safety measures
#!/bin/bash
profile_performance() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local duration=${3:-10}

    echo "⚠️  WARNING: Performance profiling can impact Redis performance"
    echo "Profiling for $duration seconds..."

    # Monitor with timeout to prevent runaway processes
    timeout "$duration" redis-cli -h "$redis_host" -p "$redis_port" MONITOR 2>/dev/null | head -1000 > /tmp/redis_monitor.log

    echo "Monitor output saved to /tmp/redis_monitor.log"

    # Real-time stats
    redis-cli -h "$redis_host" -p "$redis_port" --stat -i 1 -c "$duration"

    # Key expiration analysis
    redis-cli -h "$redis_host" -p "$redis_port" --scan --pattern "*" | head -1000 | while read -r key; do
        ttl=$(redis-cli -h "$redis_host" -p "$redis_port" TTL "$key" 2>/dev/null)
        echo "$key: $ttl"
    done > /tmp/redis_ttl_analysis.log
}

Database Diagnostics and Repair

# Database integrity checks with comprehensive validation
#!/bin/bash
check_database_integrity() {
    local rdb_file=${1:-/var/lib/redis/dump.rdb}
    local aof_file=${2:-/var/lib/redis/appendonly.aof}

    echo "=== Database Integrity Check ==="

    # RDB integrity check
    if [ -f "$rdb_file" ]; then
        echo "Checking RDB file: $rdb_file"
        if redis-check-rdb "$rdb_file" >/dev/null 2>&1; then
            echo "✓ RDB file integrity verified"
        else
            echo "✗ RDB file corruption detected"
            echo "Consider restoring from backup"
        fi
    else
        echo "RDB file not found: $rdb_file"
    fi

    # AOF integrity check
    if [ -f "$aof_file" ]; then
        echo "Checking AOF file: $aof_file"
        if redis-check-aof "$aof_file" >/dev/null 2>&1; then
            echo "✓ AOF file integrity verified"
        else
            echo "✗ AOF file corruption detected"
            echo "Attempting automatic repair..."

            # Backup corrupted file
            cp "$aof_file" "${aof_file}.corrupted.$(date +%s)"

            # Attempt repair
            if redis-check-aof --fix "$aof_file"; then
                echo "✓ AOF file repaired successfully"
            else
                echo "✗ AOF repair failed - restore from backup recommended"
            fi
        fi
    else
        echo "AOF file not found: $aof_file"
    fi
}

# Performance issue identification with detailed analysis
#!/bin/bash
identify_performance_issues() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}

    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis"
        return 1
    fi

    echo "=== Performance Issue Analysis ==="

    # Hit ratio analysis
    local stats
    stats=$(redis-cli -h "$redis_host" -p "$redis_port" INFO stats 2>/dev/null)
    local hits=$(echo "$stats" | grep keyspace_hits | cut -d: -f2 | tr -d '\r')
    local misses=$(echo "$stats" | grep keyspace_misses | cut -d: -f2 | tr -d '\r')

    if [ "$hits" -gt 0 ] && [ "$misses" -gt 0 ]; then
        local hit_ratio=$((hits * 100 / (hits + misses)))
        echo "Cache hit ratio: ${hit_ratio}%"

        if [ "$hit_ratio" -lt 80 ]; then
            echo "⚠️  WARNING: Low cache hit ratio - consider reviewing cache strategy"
        fi
    fi

    # Memory eviction analysis
    local evicted_keys=$(echo "$stats" | grep evicted_keys | cut -d: -f2 | tr -d '\r')
    if [ "$evicted_keys" -gt 1000 ]; then
        echo "⚠️  WARNING: High key eviction count: $evicted_keys"
        echo "Consider increasing maxmemory or reviewing expiration policies"
    fi

    # Slow log analysis
    local slow_count
    slow_count=$(redis-cli -h "$redis_host" -p "$redis_port" SLOWLOG LEN 2>/dev/null)
    if [ "$slow_count" -gt 100 ]; then
        echo "⚠️  WARNING: $slow_count slow queries detected"
        echo "Recent slow queries:"
        redis-cli -h "$redis_host" -p "$redis_port" SLOWLOG GET 5
    fi
}

8. Advanced Lua Scripting & Server-Side Logic

Complex Lua Script Patterns with Error Handling

-- Rate limiting with sliding window and comprehensive error handling
local function sliding_window_rate_limit(key, window, limit, current_time)
    local window_start = current_time - window

    -- Validate input parameters
    if not key or not window or not limit or not current_time then
        return {0, 0, "Invalid parameters"}
    end

    if window <= 0 or limit <= 0 or current_time <= 0 then
        return {0, 0, "Invalid parameter values"}
    end

    -- Remove old entries
    local removed = redis.call('ZREMRANGEBYSCORE', key, 0, window_start)

    -- Count current requests
    local current_requests = redis.call('ZCARD', key)

    if current_requests < limit then
        -- Add current request
        redis.call('ZADD', key, current_time, current_time .. ':' .. math.random(10000))
        redis.call('EXPIRE', key, window)
        return {1, limit - current_requests - 1, "allowed"}
    else
        return {0, 0, "rate_limited"}
    end
end

-- Call with error handling
local key = KEYS[1]
local window = tonumber(ARGV[1])
local limit = tonumber(ARGV[2])
local current_time = tonumber(ARGV[3])

if not window or not limit or not current_time then
    return {0, 0, "Invalid arguments"}
end

return sliding_window_rate_limit(key, window, limit, current_time)
-- Distributed locking with auto-renewal and comprehensive error handling
local function acquire_lock_with_renewal(lock_key, lock_value, expiry_time)
    -- Validate parameters
    if not lock_key or not lock_value or not expiry_time then
        return {0, 0, "Invalid parameters"}
    end

    if expiry_time <= 0 then
        return {0, 0, "Invalid expiry time"}
    end

    -- Try to acquire lock
    local result = redis.call('SET', lock_key, lock_value, 'PX', expiry_time, 'NX')

    if result then
        return {1, expiry_time, "acquired"}
    else
        -- Check if we already own the lock
        local current_value = redis.call('GET', lock_key)
        if current_value == lock_value then
            -- Renew the lock
            local renewed = redis.call('PEXPIRE', lock_key, expiry_time)
            if renewed == 1 then
                return {1, redis.call('PTTL', lock_key), "renewed"}
            else
                return {0, 0, "renewal_failed"}
            end
        else
            return {0, redis.call('PTTL', lock_key), "locked_by_other"}
        end
    end
end

return acquire_lock_with_renewal(KEYS[1], ARGV[1], tonumber(ARGV[2]))
-- Atomic counter with expiration and error handling
local function atomic_increment_with_expiry(key, increment, expiry)
    -- Validate parameters
    increment = tonumber(increment) or 1
    expiry = tonumber(expiry) or 3600

    if increment == 0 then
        return {redis.call('GET', key) or 0, "unchanged"}
    end

    local current = redis.call('GET', key)
    local new_value

    if current == false then
        -- Key doesn't exist, set initial value
        new_value = increment
        redis.call('SET', key, new_value)
        redis.call('EXPIRE', key, expiry)
    else
        -- Key exists, increment
        new_value = redis.call('INCRBY', key, increment)
        -- Refresh expiry
        redis.call('EXPIRE', key, expiry)
    end

    return {new_value, "success", redis.call('TTL', key)}
end

return atomic_increment_with_expiry(KEYS[1], ARGV[1], ARGV[2])

Script Management and Optimization

# Script registration and management with error handling
#!/bin/bash
manage_lua_scripts() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local script_file=$3

    if [ ! -f "$script_file" ]; then
        echo "ERROR: Script file not found: $script_file"
        return 1
    fi

    if ! redis-cli -h "$redis_host" -p "$redis_port" ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis"
        return 1
    fi

    # Load script and get SHA
    local script_content
    script_content=$(cat "$script_file")
    local sha
    sha=$(redis-cli -h "$redis_host" -p "$redis_port" SCRIPT LOAD "$script_content" 2>/dev/null)

    if [ $? -eq 0 ]; then
        echo "✓ Script loaded successfully"
        echo "SHA: $sha"

        # Verify script is loaded
        if redis-cli -h "$redis_host" -p "$redis_port" SCRIPT EXISTS "$sha" | grep -q "1"; then
            echo "✓ Script verified in cache"
            echo "$sha" > "${script_file}.sha"
        else
            echo "✗ Script verification failed"
            return 1
        fi
    else
        echo "✗ Script loading failed"
        return 1
    fi
}

# Execute script with error handling
execute_lua_script() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local sha_file=$3
    shift 3
    local keys=("$@")

    if [ ! -f "$sha_file" ]; then
        echo "ERROR: SHA file not found: $sha_file"
        return 1
    fi

    local sha
    sha=$(cat "$sha_file")

    # Check if script exists in cache
    if ! redis-cli -h "$redis_host" -p "$redis_port" SCRIPT EXISTS "$sha" | grep -q "1"; then
        echo "ERROR: Script not found in cache, reload required"
        return 1
    fi

    # Execute script
    redis-cli -h "$redis_host" -p "$redis_port" EVALSHA "$sha" ${#keys[@]} "${keys[@]}"
}

# Script debugging and profiling
debug_lua_script() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local script_file=$3

    echo "Enabling Lua debugging..."
    redis-cli -h "$redis_host" -p "$redis_port" SCRIPT DEBUG YES

    echo "Executing script with debugging..."
    redis-cli -h "$redis_host" -p "$redis_port" --eval "$script_file" mykey , arg1 arg2
}

Advanced Health Checks

#!/bin/bash
# Comprehensive Redis health check with detailed diagnostics
check_redis_health() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local redis_password=${3:-""}
    local warning_threshold=${4:-80}
    local critical_threshold=${5:-95}

    local exit_code=0
    local warnings=()
    local errors=()

    # Authentication setup
    local auth_cmd=""
    if [ -n "$redis_password" ]; then
        auth_cmd="-a $redis_password"
    fi

    # Basic connectivity test
    if ! redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd --connect-timeout 5 ping >/dev/null 2>&1; then
        errors+=("Redis not responding to PING")
        exit_code=2
    else
        echo "✓ Redis connectivity: OK"
    fi

    # Only proceed if basic connectivity works
    if [ ${#errors[@]} -eq 0 ]; then
        # Memory usage check
        local memory_info
        memory_info=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd INFO memory 2>/dev/null)

        if [ $? -eq 0 ]; then
            local used_memory
            used_memory=$(echo "$memory_info" | grep "^used_memory:" | cut -d: -f2 | tr -d '\r')
            local max_memory
            max_memory=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd CONFIG GET maxmemory 2>/dev/null | tail -n1)

            if [ "$max_memory" != "0" ] && [ -n "$used_memory" ] && [ "$used_memory" -gt 0 ]; then
                local memory_usage_percent=$((used_memory * 100 / max_memory))

                if [ $memory_usage_percent -gt $critical_threshold ]; then
                    errors+=("Critical memory usage: ${memory_usage_percent}%")
                    exit_code=2
                elif [ $memory_usage_percent -gt $warning_threshold ]; then
                    warnings+=("High memory usage: ${memory_usage_percent}%")
                    [ $exit_code -eq 0 ] && exit_code=1
                else
                    echo "✓ Memory usage: ${memory_usage_percent}% (OK)"
                fi
            fi

            # Memory fragmentation check
            local fragmentation_ratio
            fragmentation_ratio=$(echo "$memory_info" | grep "^mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r')
            if [ -n "$fragmentation_ratio" ]; then
                if (( $(echo "$fragmentation_ratio > 2.0" | bc -l 2>/dev/null || echo 0) )); then
                    warnings+=("High memory fragmentation: $fragmentation_ratio")
                    [ $exit_code -eq 0 ] && exit_code=1
                else
                    echo "✓ Memory fragmentation: $fragmentation_ratio (OK)"
                fi
            fi
        fi

        # Replication lag check
        local repl_info
        repl_info=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd INFO replication 2>/dev/null)

        if echo "$repl_info" | grep -q "role:slave"; then
            local lag
            lag=$(echo "$repl_info" | grep "master_repl_offset\|slave_repl_offset" | head -2 | cut -d: -f2 | tr -d '\r' | paste -sd' ' | awk '{print $1-$2}')

            if [ -n "$lag" ] && [ "$lag" -gt 1000 ]; then
                warnings+=("High replication lag: ${lag} bytes")
                [ $exit_code -eq 0 ] && exit_code=1
            else
                echo "✓ Replication lag: ${lag:-0} bytes (OK)"
            fi
        fi

        # Connection count check
        local client_info
        client_info=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd INFO clients 2>/dev/null)
        local connected_clients
        connected_clients=$(echo "$client_info" | grep "^connected_clients:" | cut -d: -f2 | tr -d '\r')
        local max_clients
        max_clients=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd CONFIG GET maxclients 2>/dev/null | tail -n1)

        if [ -n "$connected_clients" ] && [ -n "$max_clients" ] && [ "$max_clients" -gt 0 ]; then
            local client_usage_percent=$((connected_clients * 100 / max_clients))

            if [ $client_usage_percent -gt $critical_threshold ]; then
                errors+=("Critical client connections: ${client_usage_percent}% ($connected_clients/$max_clients)")
                exit_code=2
            elif [ $client_usage_percent -gt $warning_threshold ]; then
                warnings+=("High client connections: ${client_usage_percent}% ($connected_clients/$max_clients)")
                [ $exit_code -eq 0 ] && exit_code=1
            else
                echo "✓ Client connections: $connected_clients/$max_clients (OK)"
            fi
        fi

        # Slow log check
        local slow_count
        slow_count=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_cmd SLOWLOG LEN 2>/dev/null)
        if [ -n "$slow_count" ] && [ "$slow_count" -gt 100 ]; then
            warnings+=("High slow query count: $slow_count")
            [ $exit_code -eq 0 ] && exit_code=1
        else
            echo "✓ Slow queries: ${slow_count:-0} (OK)"
        fi
    fi

    # Output summary
    if [ ${#warnings[@]} -gt 0 ]; then
        echo "WARNINGS:"
        printf " - %s\n" "${warnings[@]}"
    fi

    if [ ${#errors[@]} -gt 0 ]; then
        echo "ERRORS:"
        printf " - %s\n" "${errors[@]}"
    fi

    case $exit_code in
        0) echo "OVERALL STATUS: OK" ;;
        1) echo "OVERALL STATUS: WARNING" ;;
        2) echo "OVERALL STATUS: CRITICAL" ;;
    esac

    return $exit_code
}

10. Advanced DevOps & Container Orchestration

Production Docker Configuration

# Multi-stage Redis build with security hardening
FROM redis:7-alpine AS redis-base

# Install security tools and create non-root user
RUN apk add --no-cache dumb-init ca-certificates && \
    rm -rf /var/cache/apk/* && \
    addgroup -g 999 redis && \
    adduser -D -s /bin/sh -u 999 -G redis redis

# Security hardening - remove unnecessary packages
RUN apk del --purge wget curl

FROM redis-base AS redis-production

# Copy optimized configuration
COPY redis.conf /usr/local/etc/redis/redis.conf
COPY docker-entrypoint.sh /usr/local/bin/
COPY healthcheck.sh /usr/local/bin/

# Set secure permissions
RUN chown -R redis:redis /data /usr/local/etc/redis && \
    chmod +x /usr/local/bin/docker-entrypoint.sh /usr/local/bin/healthcheck.sh

# Security and performance settings
USER redis
EXPOSE 6379
VOLUME ["/data"]

# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
  CMD /usr/local/bin/healthcheck.sh

ENTRYPOINT ["dumb-init", "--", "docker-entrypoint.sh"]
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]
#!/bin/bash
# docker-entrypoint.sh with comprehensive error handling
set -e

# Validate configuration
if [ ! -f "/usr/local/etc/redis/redis.conf" ]; then
    echo "ERROR: Redis configuration file not found"
    exit 1
fi

# Test configuration syntax
if ! redis-server --test-config /usr/local/etc/redis/redis.conf >/dev/null 2>&1; then
    echo "ERROR: Invalid Redis configuration"
    redis-server --test-config /usr/local/etc/redis/redis.conf
    exit 1
fi

# Create necessary directories
mkdir -p /data/logs

# Set secure permissions
chmod 750 /data
chmod 640 /usr/local/etc/redis/redis.conf

echo "Starting Redis with configuration validation..."
exec "$@"
#!/bin/bash
# healthcheck.sh for Docker health checks
timeout 5 redis-cli ping >/dev/null 2>&1
exit_code=$?

if [ $exit_code -eq 0 ]; then
    echo "Redis health check: OK"
    exit 0
else
    echo "Redis health check: FAILED"
    exit 1
fi

Kubernetes StatefulSet with Advanced Features

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
  namespace: redis
  labels:
    app: redis-cluster
    version: "7.0"
spec:
  serviceName: redis-cluster
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  template:
    metadata:
      labels:
        app: redis-cluster
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
        prometheus.io/path: "/metrics"
    spec:
      securityContext:
        fsGroup: 999
        runAsUser: 999
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
          name: redis
        - containerPort: 16379
          name: cluster-bus
        env:
        - name: REDIS_CLUSTER_ANNOUNCE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: password
        command:
        - redis-server
        args:
        - /etc/redis/redis.conf
        - --cluster-enabled yes
        - --cluster-config-file nodes.conf
        - --cluster-node-timeout 5000
        - --appendonly yes
        - --protected-mode no
        - --requirepass $(REDIS_PASSWORD)
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        volumeMounts:
        - name: redis-config
          mountPath: /etc/redis
        - name: redis-data
          mountPath: /data
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - redis-cli -a $REDIS_PASSWORD ping
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - redis-cli -a $REDIS_PASSWORD ping
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
      - name: redis-exporter
        image: oliver006/redis_exporter:v1.50.0
        ports:
        - containerPort: 9121
          name: metrics
        env:
        - name: REDIS_ADDR
          value: "redis://localhost:6379"
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: password
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "100m"
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
      volumes:
      - name: redis-config
        configMap:
          name: redis-config
          defaultMode: 0640
      terminationGracePeriodSeconds: 30
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - redis-cluster
              topologyKey: kubernetes.io/hostname
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "fast-ssd"
      resources:
        requests:
          storage: 10Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-config
  namespace: redis
data:
  redis.conf: |
    # Production Redis configuration
    bind 0.0.0.0
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300

    # Memory configuration
    maxmemory 1500mb
    maxmemory-policy allkeys-lru
    maxmemory-samples 5

    # Persistence
    save 900 1
    save 300 10
    save 60 10000
    appendonly yes
    appendfsync everysec

    # Logging
    loglevel notice

    # Security
    protected-mode yes
---
apiVersion: v1
kind: Secret
metadata:
  name: redis-secret
  namespace: redis
type: Opaque
data:
  password: c3VwZXJfc2VjdXJlX3Bhc3N3b3JkXzEyMw==  # super_secure_password_123
---
apiVersion: v1
kind: Service
metadata:
  name: redis-cluster
  namespace: redis
  labels:
    app: redis-cluster
spec:
  ports:
  - port: 6379
    targetPort: 6379
    name: redis
  - port: 16379
    targetPort: 16379
    name: cluster-bus
  clusterIP: None
  selector:
    app: redis-cluster
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: redis-cluster
  namespace: redis
  labels:
    app: redis-cluster
spec:
  selector:
    matchLabels:
      app: redis-cluster
  endpoints:
  - port: metrics
    interval: 30s
    path: /metrics

Advanced Cluster Initialization Script

#!/bin/bash
# Kubernetes Redis cluster initialization with comprehensive error handling
initialize_k8s_redis_cluster() {
    local namespace=${1:-redis}
    local replicas=${2:-3}
    local timeout=${3:-300}

    echo "Initializing Redis cluster in namespace: $namespace"

    # Wait for all pods to be ready
    echo "Waiting for Redis pods to be ready..."
    if ! kubectl wait --for=condition=Ready pod -l app=redis-cluster -n "$namespace" --timeout="${timeout}s"; then
        echo "ERROR: Pods failed to become ready within $timeout seconds"
        return 1
    fi

    # Get pod IPs
    local pod_ips
    pod_ips=$(kubectl get pods -l app=redis-cluster -n "$namespace" -o jsonpath='{.items[*].status.podIP}')

    if [ -z "$pod_ips" ]; then
        echo "ERROR: No pod IPs found"
        return 1
    fi

    # Convert to array and create node list
    local ips=($pod_ips)
    local nodes=()

    for ip in "${ips[@]}"; do
        nodes+=("$ip:6379")
    done

    echo "Found ${#nodes[@]} Redis nodes: ${nodes[*]}"

    if [ ${#nodes[@]} -lt 6 ]; then
        echo "ERROR: Minimum 6 nodes required for cluster (3 masters + 3 replicas)"
        return 1
    fi

    # Create cluster using first pod
    local first_pod
    first_pod=$(kubectl get pods -l app=redis-cluster -n "$namespace" -o jsonpath='{.items[0].metadata.name}')

    echo "Creating cluster using pod: $first_pod"
    kubectl exec -it "$first_pod" -n "$namespace" -- redis-cli --cluster create "${nodes[@]}" --cluster-replicas 1 --cluster-yes

    if [ $? -eq 0 ]; then
        echo "✓ Cluster created successfully"

        # Verify cluster status
        echo "Verifying cluster status..."
        kubectl exec "$first_pod" -n "$namespace" -- redis-cli cluster info
        kubectl exec "$first_pod" -n "$namespace" -- redis-cli cluster nodes

        return 0
    else
        echo "✗ Cluster creation failed"
        return 1
    fi
}

11. Advanced Migration & Data Management

Zero-Downtime Migration Strategies

#!/bin/bash
# Redis migration with comprehensive validation and rollback capability
migrate_redis_zero_downtime() {
    local source_host=$1
    local source_port=$2
    local target_host=$3
    local target_port=$4
    local password=${5:-""}
    local timeout=${6:-300}

    # Validation
    if [ $# -lt 4 ]; then
        echo "ERROR: Usage: migrate_redis_zero_downtime source_host source_port target_host target_port [password] [timeout]"
        return 1
    fi

    # Authentication setup
    local auth_cmd=""
    if [ -n "$password" ]; then
        auth_cmd="-a $password"
    fi

    echo "=== Redis Zero-Downtime Migration ==="
    echo "Source: $source_host:$source_port"
    echo "Target: $target_host:$target_port"
    echo "Timeout: ${timeout}s"

    # Pre-migration validation
    echo "Step 1: Validating source and target..."

    # Test source connectivity
    if ! redis-cli -h "$source_host" -p "$source_port" $auth_cmd ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to source Redis at $source_host:$source_port"
        return 1
    fi

    # Test target connectivity
    if ! redis-cli -h "$target_host" -p "$target_port" $auth_cmd ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to target Redis at $target_host:$target_port"
        return 1
    fi

    # Check target is empty or confirm overwrite
    local target_keys
    target_keys=$(redis-cli -h "$target_host" -p "$target_port" $auth_cmd DBSIZE 2>/dev/null)
    if [ "$target_keys" -gt 0 ]; then
        echo "WARNING: Target Redis contains $target_keys keys"
        read -p "Continue and overwrite? (y/N): " confirm
        if [[ ! $confirm =~ ^[Yy]$ ]]; then
            echo "Migration aborted"
            return 1
        fi
    fi

    echo "✓ Pre-migration validation completed"

    # Step 2: Setup replication
    echo "Step 2: Setting up replication from source to target..."

    if redis-cli -h "$target_host" -p "$target_port" $auth_cmd REPLICAOF "$source_host" "$source_port" >/dev/null 2>&1; then
        echo "✓ Replication setup initiated"
    else
        echo "✗ Failed to setup replication"
        return 1
    fi

    # Step 3: Wait for initial sync with progress monitoring
    echo "Step 3: Waiting for initial synchronization..."

    local sync_start_time=$(date +%s)
    local sync_timeout=$((sync_start_time + timeout))
    local last_output=""

    while [ $(date +%s) -lt $sync_timeout ]; do
        local repl_info
        repl_info=$(redis-cli -h "$target_host" -p "$target_port" $auth_cmd INFO replication 2>/dev/null)

        if echo "$repl_info" | grep -q "master_sync_in_progress:0"; then
            echo "✓ Initial synchronization completed"
            break
        elif echo "$repl_info" | grep -q "master_sync_in_progress:1"; then
            # Show progress
            local bytes_received
            bytes_received=$(echo "$repl_info" | grep "master_sync_read_bytes:" | cut -d: -f2 | tr -d '\r')
            if [ "$bytes_received" != "$last_output" ]; then
                echo "  Sync in progress... received: ${bytes_received:-0} bytes"
                last_output="$bytes_received"
            fi
        fi

        sleep 5
    done

    # Verify sync completed
    if ! redis-cli -h "$target_host" -p "$target_port" $auth_cmd INFO replication | grep -q "master_sync_in_progress:0"; then
        echo "✗ Initial synchronization timeout"
        echo "Rolling back..."
        redis-cli -h "$target_host" -p "$target_port" $auth_cmd REPLICAOF NO ONE >/dev/null 2>&1
        return 1
    fi

    # Step 4: Monitor replication lag
    echo "Step 4: Monitoring replication lag..."

    local lag_check_count=0
    local max_lag_checks=10
    local acceptable_lag=100  # bytes

    while [ $lag_check_count -lt $max_lag_checks ]; do
        local target_repl_info
        target_repl_info=$(redis-cli -h "$target_host" -p "$target_port" $auth_cmd INFO replication 2>/dev/null)
        local source_repl_info
        source_repl_info=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd INFO replication 2>/dev/null)

        local target_offset
        target_offset=$(echo "$target_repl_info" | grep "slave_repl_offset:" | cut -d: -f2 | tr -d '\r')
        local source_offset
        source_offset=$(echo "$source_repl_info" | grep "master_repl_offset:" | cut -d: -f2 | tr -d '\r')

        if [ -n "$target_offset" ] && [ -n "$source_offset" ]; then
            local lag=$((source_offset - target_offset))
            echo "  Replication lag: $lag bytes"

            if [ "$lag" -le "$acceptable_lag" ]; then
                echo "✓ Replication lag acceptable ($lag bytes)"
                break
            fi
        fi

        ((lag_check_count++))
        sleep 2
    done

    # Step 5: Promote target to master
    echo "Step 5: Promoting target to master..."

    # Record pre-promotion state for rollback
    local source_keys_before
    source_keys_before=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd DBSIZE 2>/dev/null)
    local target_keys_before
    target_keys_before=$(redis-cli -h "$target_host" -p "$target_port" $auth_cmd DBSIZE 2>/dev/null)

    echo "  Source keys before promotion: $source_keys_before"
    echo "  Target keys before promotion: $target_keys_before"

    if redis-cli -h "$target_host" -p "$target_port" $auth_cmd REPLICAOF NO ONE >/dev/null 2>&1; then
        echo "✓ Target promoted to master successfully"
    else
        echo "✗ Failed to promote target to master"
        return 1
    fi

    # Step 6: Final validation
    echo "Step 6: Final validation..."

    local target_keys_after
    target_keys_after=$(redis-cli -h "$target_host" -p "$target_port" $auth_cmd DBSIZE 2>/dev/null)

    echo "  Target keys after promotion: $target_keys_after"

    # Validate key count consistency
    local key_diff=$((source_keys_before - target_keys_after))
    if [ "$key_diff" -gt 100 ]; then
        echo "⚠️  WARNING: Significant key count difference: $key_diff"
        echo "  Consider manual verification"
    fi

    # Test basic operations on target
    local test_key="migration_test_$(date +%s)"
    if redis-cli -h "$target_host" -p "$target_port" $auth_cmd SET "$test_key" "success" EX 60 >/dev/null 2>&1 && \
       redis-cli -h "$target_host" -p "$target_port" $auth_cmd GET "$test_key" | grep -q "success"; then
        echo "✓ Target Redis operational test passed"
        redis-cli -h "$target_host" -p "$target_port" $auth_cmd DEL "$test_key" >/dev/null 2>&1
    else
        echo "✗ Target Redis operational test failed"
        return 1
    fi

    echo "=== Migration completed successfully ==="
    echo "New master: $target_host:$target_port"
    echo "Total keys migrated: $target_keys_after"

    return 0
}

Advanced Data Export/Import with Parallel Processing

#!/bin/bash
# Parallel Redis data migration with comprehensive error handling
export_redis_parallel() {
    local source_host=${1:-localhost}
    local source_port=${2:-6379}
    local pattern=${3:-"*"}
    local batch_size=${4:-1000}
    local output_dir=${5:-./redis_export}
    local max_parallel=${6:-4}
    local password=${7:-""}

    # Validation
    if [ ! -d "$(dirname "$output_dir")" ]; then
        echo "ERROR: Parent directory does not exist: $(dirname "$output_dir")"
        return 1
    fi

    # Authentication setup
    local auth_cmd=""
    if [ -n "$password" ]; then
        auth_cmd="-a $password"
    fi

    # Test connectivity
    if ! redis-cli -h "$source_host" -p "$source_port" $auth_cmd ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis at $source_host:$source_port"
        return 1
    fi

    echo "=== Redis Parallel Export ==="
    echo "Source: $source_host:$source_port"
    echo "Pattern: $pattern"
    echo "Batch size: $batch_size"
    echo "Max parallel: $max_parallel"
    echo "Output: $output_dir"

    # Create output directory
    mkdir -p "$output_dir" || {
        echo "ERROR: Cannot create output directory: $output_dir"
        return 1
    }

    # Get total key count for progress tracking
    local total_keys
    total_keys=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd --scan --pattern "$pattern" | wc -l)
    echo "Total keys to export: $total_keys"

    if [ "$total_keys" -eq 0 ]; then
        echo "No keys found matching pattern: $pattern"
        return 0
    fi

    # Export keys to file
    local keys_file="$output_dir/keys.txt"
    echo "Scanning for keys..."
    redis-cli -h "$source_host" -p "$source_port" $auth_cmd --scan --pattern "$pattern" > "$keys_file"

    if [ ! -s "$keys_file" ]; then
        echo "ERROR: No keys exported to file"
        return 1
    fi

    # Split keys into batches
    echo "Splitting into batches of $batch_size keys..."
    split -l "$batch_size" "$keys_file" "$output_dir/batch_"

    local batch_files=("$output_dir"/batch_*)
    echo "Created ${#batch_files[@]} batch files"

    # Export function for parallel processing
    export_batch() {
        local batch_file=$1
        local batch_name=$(basename "$batch_file")
        local output_file="$output_dir/$batch_name.redis"
        local error_file="$output_dir/$batch_name.errors"
        local processed=0
        local errors=0

        echo "Processing $batch_name..."

        while IFS= read -r key; do
            [ -z "$key" ] && continue

            local key_type
            key_type=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd TYPE "$key" 2>/dev/null | tr -d '\r')

            if [ "$key_type" = "none" ]; then
                echo "Key expired or deleted: $key" >> "$error_file"
                ((errors++))
                continue
            fi

            local ttl
            ttl=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd TTL "$key" 2>/dev/null | tr -d '\r')

            case $key_type in
                "string")
                    local value
                    value=$(redis-cli -h "$source_host" -p "$source_port" $auth_cmd GET "$key" 2>/dev/null)
                    if [ $? -eq 0 ]; then
                        printf 'SET %q %q\n' "$key" "$value" >> "$output_file"
                    else
                        echo "Failed to get string key: $key" >> "$error_file"
                        ((errors++))
                    fi
                    ;;
                "hash")
                    if redis-cli -h "$source_host" -p "$source_port" $auth_cmd HGETALL "$key" 2>/dev/null | \
                       awk 'NR%2==1{field=$0} NR%2==0{printf "HSET %s %s %s\n", ENVIRON["key"], field, $0}' key="$key" >> "$output_file"; then
                        :
                    else
                        echo "Failed to get hash key: $key" >> "$error_file"
                        ((errors++))
                    fi
                    ;;
                "list")
                    if redis-cli -h "$source_host" -p "$source_port" $auth_cmd LRANGE "$key" 0 -1 2>/dev/null | \
                       awk '{printf "LPUSH %s %s\n", ENVIRON["key"], $0}' key="$key" >> "$output_file"; then
                        :
                    else
                        echo "Failed to get list key: $key" >> "$error_file"
                        ((errors++))
                    fi
                    ;;
                "set")
                    if redis-cli -h "$source_host" -p "$source_port" $auth_cmd SMEMBERS "$key" 2>/dev/null | \
                       awk '{printf "SADD %s %s\n", ENVIRON["key"], $0}' key="$key" >> "$output_file"; then
                        :
                    else
                        echo "Failed to get set key: $key" >> "$error_file"
                        ((errors++))
                    fi
                    ;;
                "zset")
                    if redis-cli -h "$source_host" -p "$source_port" $auth_cmd ZRANGE "$key" 0 -1 WITHSCORES 2>/dev/null | \
                       awk 'NR%2==1{member=$0} NR%2==0{printf "ZADD %s %s %s\n", ENVIRON["key"], $0, member}' key="$key" >> "$output_file"; then
                        :
                    else
                        echo "Failed to get zset key: $key" >> "$error_file"
                        ((errors++))
                    fi
                    ;;
                *)
                    echo "Unsupported key type: $key_type for key: $key" >> "$error_file"
                    ((errors++))
                    ;;
            esac

            # Add TTL if applicable
            if [ "$ttl" -gt 0 ]; then
                printf 'EXPIRE %q %s\n' "$key" "$ttl" >> "$output_file"
            fi

            ((processed++))
        done < "$batch_file"

        echo "Completed $batch_name: $processed processed, $errors errors"

        # Clean up empty error file
        if [ ! -s "$error_file" ]; then
            rm -f "$error_file"
        fi
    }

    # Export the function for parallel execution
    export -f export_batch
    export source_host source_port auth_cmd output_dir

    # Process batches in parallel
    echo "Starting parallel export with $max_parallel workers..."
    printf '%s\n' "${batch_files[@]}" | xargs -n 1 -P "$max_parallel" -I {} bash -c 'export_batch "$@"' _ {}

    # Wait for all background jobs to complete
    wait

    # Cleanup and summary
    rm -f "$keys_file" "${batch_files[@]}"

    local redis_files=("$output_dir"/*.redis)
    local total_commands=0
    local total_errors=0

    for file in "${redis_files[@]}"; do
        if [ -f "$file" ]; then
            total_commands=$((total_commands + $(wc -l < "$file")))
        fi
    done

    for error_file in "$output_dir"/*.errors; do
        if [ -f "$error_file" ]; then
            total_errors=$((total_errors + $(wc -l < "$error_file")))
        fi
    done

    echo "=== Export Summary ==="
    echo "Total Redis commands exported: $total_commands"
    echo "Total errors: $total_errors"
    echo "Output files: ${#redis_files[@]}"

    # Create import script
    cat > "$output_dir/import.sh" << 'EOF'
#!/bin/bash
# Generated import script
REDIS_HOST=${1:-localhost}
REDIS_PORT=${2:-6379}
REDIS_PASSWORD=${3:-""}

AUTH_CMD=""
if [ -n "$REDIS_PASSWORD" ]; then
    AUTH_CMD="-a $REDIS_PASSWORD"
fi

echo "Importing to Redis at $REDIS_HOST:$REDIS_PORT..."

for redis_file in *.redis; do
    if [ -f "$redis_file" ]; then
        echo "Importing $redis_file..."
        redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" $AUTH_CMD --pipe < "$redis_file"
    fi
done

echo "Import completed"
EOF

    chmod +x "$output_dir/import.sh"
    echo "Import script created: $output_dir/import.sh"

    return 0
}

12. Advanced Performance Testing & Optimization

Comprehensive Benchmarking Suite with Advanced Analysis

#!/bin/bash
# Advanced Redis performance testing with detailed analysis and reporting
redis_performance_suite() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local test_duration=${3:-60}
    local password=${4:-""}
    local output_dir=${5:-./redis_benchmark_$(date +%Y%m%d_%H%M%S)}

    # Validation and setup
    if ! redis-cli -h "$redis_host" -p "$redis_port" ${password:+-a $password} ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis at $redis_host:$redis_port"
        return 1
    fi

    mkdir -p "$output_dir" || {
        echo "ERROR: Cannot create output directory: $output_dir"
        return 1
    }

    local auth_param=""
    if [ -n "$password" ]; then
        auth_param="-a $password"
    fi

    echo "=== Redis Performance Test Suite ==="
    echo "Target: $redis_host:$redis_port"
    echo "Duration: ${test_duration}s per test"
    echo "Output: $output_dir"
    echo "Start time: $(date)"

    # System information
    echo "=== System Information ===" | tee "$output_dir/system_info.txt"
    {
        echo "Redis Info:"
        redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO server
        echo
        echo "System Info:"
        uname -a
        echo "CPU Info:"
        grep "model name" /proc/cpuinfo | head -1
        grep "cpu cores" /proc/cpuinfo | head -1
        echo "Memory Info:"
        free -h
        echo "Network Info:"
        ss -i | grep "$redis_port" | head -5
    } >> "$output_dir/system_info.txt" 2>/dev/null

    # Test 1: Basic throughput test
    echo "=== Test 1: Basic Throughput Test ===" | tee -a "$output_dir/results.txt"
    {
        echo "Testing basic SET/GET operations..."
        redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
            -t set,get -n 1000000 -c 50 -d 100 \
            --csv > "$output_dir/basic_throughput.csv" 2>&1

        echo "Basic throughput results:"
        tail -10 "$output_dir/basic_throughput.csv"
    } | tee -a "$output_dir/results.txt"

    # Test 2: Pipeline performance
    echo "=== Test 2: Pipeline Performance Test ===" | tee -a "$output_dir/results.txt"
    for pipeline_size in 1 4 8 16 32; do
        echo "Testing with pipeline size: $pipeline_size" | tee -a "$output_dir/results.txt"
        redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
            -t set,get -n 100000 -c 50 -P "$pipeline_size" \
            --csv > "$output_dir/pipeline_${pipeline_size}.csv" 2>&1
    done

    # Test 3: Different data sizes
    echo "=== Test 3: Data Size Performance ===" | tee -a "$output_dir/results.txt"
    for data_size in 64 256 1024 4096 10240; do
        echo "Testing with data size: $data_size bytes" | tee -a "$output_dir/results.txt"
        redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
            -t set,get -n 50000 -c 50 -d "$data_size" \
            --csv > "$output_dir/datasize_${data_size}.csv" 2>&1
    done

    # Test 4: Concurrent connections scaling
    echo "=== Test 4: Connection Scaling Test ===" | tee -a "$output_dir/results.txt"
    for connections in 10 50 100 200 500; do
        echo "Testing with $connections concurrent connections" | tee -a "$output_dir/results.txt"
        redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
            -t set,get -n 50000 -c "$connections" -d 100 \
            --csv > "$output_dir/connections_${connections}.csv" 2>&1
    done

    # Test 5: Data structure specific tests
    echo "=== Test 5: Data Structure Performance ===" | tee -a "$output_dir/results.txt"

    # Hash operations
    echo "Testing HASH operations..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -t hset,hget,hmset,hmget -n 100000 -c 50 \
        --csv > "$output_dir/hash_ops.csv" 2>&1

    # List operations
    echo "Testing LIST operations..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -t lpush,lpop,rpush,rpop,lrange -n 100000 -c 50 \
        --csv > "$output_dir/list_ops.csv" 2>&1

    # Set operations
    echo "Testing SET operations..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -t sadd,smembers,spop -n 100000 -c 50 \
        --csv > "$output_dir/set_ops.csv" 2>&1

    # Sorted set operations
    echo "Testing SORTED SET operations..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -t zadd,zrange,zrevrange,zrank -n 100000 -c 50 \
        --csv > "$output_dir/zset_ops.csv" 2>&1

    # Test 6: Lua script performance
    echo "=== Test 6: Lua Script Performance ===" | tee -a "$output_dir/results.txt"
    local simple_script='return redis.call("incr", KEYS[1])'
    local complex_script='
    local current = redis.call("GET", KEYS[1])
    if current == false then
        redis.call("SET", KEYS[1], 1)
        redis.call("EXPIRE", KEYS[1], 3600)
        return 1
    else
        return redis.call("INCR", KEYS[1])
    end'

    echo "Testing simple Lua script..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -n 100000 -c 50 eval "$simple_script" 1 counter \
        --csv > "$output_dir/lua_simple.csv" 2>&1

    echo "Testing complex Lua script..." | tee -a "$output_dir/results.txt"
    redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
        -n 50000 -c 50 eval "$complex_script" 1 complex_counter \
        --csv > "$output_dir/lua_complex.csv" 2>&1

    # Test 7: Memory pressure test
    echo "=== Test 7: Memory Pressure Test ===" | tee -a "$output_dir/results.txt"
    {
        local initial_memory
        initial_memory=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO memory | grep used_memory: | cut -d: -f2 | tr -d '\r')
        echo "Initial memory usage: $initial_memory bytes"

        # Load data until memory pressure
        redis-benchmark -h "$redis_host" -p "$redis_port" $auth_param \
            -t set -n 1000000 -c 50 -d 1024 -r 100000 \
            --csv > "$output_dir/memory_pressure.csv" 2>&1

        local final_memory
        final_memory=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO memory | grep used_memory: | cut -d: -f2 | tr -d '\r')
        echo "Final memory usage: $final_memory bytes"
        echo "Memory increase: $((final_memory - initial_memory)) bytes"

        # Check for evictions
        local evicted_keys
        evicted_keys=$(redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO stats | grep evicted_keys | cut -d: -f2 | tr -d '\r')
        echo "Keys evicted during test: ${evicted_keys:-0}"
    } | tee -a "$output_dir/results.txt"

    # Test 8: Latency analysis
    echo "=== Test 8: Latency Analysis ===" | tee -a "$output_dir/results.txt"
    {
        echo "Running latency tests..."

        # Basic latency
        timeout 30 redis-cli -h "$redis_host" -p "$redis_port" $auth_param \
            --latency -i 1 > "$output_dir/latency_basic.txt" 2>&1 &

        # Latency history
        timeout 30 redis-cli -h "$redis_host" -p "$redis_port" $auth_param \
            --latency-history -i 1 > "$output_dir/latency_history.txt" 2>&1 &

        wait

        echo "Latency test completed"
        if [ -s "$output_dir/latency_basic.txt" ]; then
            echo "Basic latency stats:"
            tail -5 "$output_dir/latency_basic.txt"
        fi
    } | tee -a "$output_dir/results.txt"

    # Generate comprehensive report
    echo "=== Generating Performance Report ===" | tee -a "$output_dir/results.txt"

    cat > "$output_dir/generate_report.py" << 'EOF'
#!/usr/bin/env python3
import csv
import os
import sys
from statistics import mean, median

def parse_benchmark_csv(filename):
    """Parse Redis benchmark CSV output"""
    try:
        with open(filename, 'r') as f:
            reader = csv.DictReader(f)
            data = []
            for row in reader:
                if 'requests per second' in row:
                    data.append({
                        'test': row.get('test', 'unknown'),
                        'requests_per_second': float(row['requests per second'].replace(',', '')),
                        'latency_ms': float(row.get('latency', '0').replace('ms', ''))
                    })
        return data
    except Exception as e:
        print(f"Error parsing {filename}: {e}")
        return []

def generate_summary_report(output_dir):
    """Generate summary performance report"""
    report_file = os.path.join(output_dir, 'performance_summary.txt')

    csv_files = [f for f in os.listdir(output_dir) if f.endswith('.csv')]

    with open(report_file, 'w') as report:
        report.write("Redis Performance Test Summary\n")
        report.write("=" * 50 + "\n\n")

        total_ops = 0
        best_throughput = 0
        worst_latency = 0

        for csv_file in sorted(csv_files):
            data = parse_benchmark_csv(os.path.join(output_dir, csv_file))
            if data:
                avg_rps = mean([d['requests_per_second'] for d in data])
                avg_latency = mean([d['latency_ms'] for d in data if d['latency_ms'] > 0])

                report.write(f"Test: {csv_file}\n")
                report.write(f"  Average RPS: {avg_rps:,.0f}\n")
                if avg_latency > 0:
                    report.write(f"  Average Latency: {avg_latency:.2f}ms\n")
                report.write("\n")

                total_ops += avg_rps
                best_throughput = max(best_throughput, avg_rps)
                if avg_latency > 0:
                    worst_latency = max(worst_latency, avg_latency)

        report.write("\nSummary Statistics:\n")
        report.write(f"Best Throughput: {best_throughput:,.0f} ops/sec\n")
        if worst_latency > 0:
            report.write(f"Worst Latency: {worst_latency:.2f}ms\n")
        report.write(f"Total Test Operations: {total_ops:,.0f}\n")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python3 generate_report.py <output_dir>")
        sys.exit(1)

    generate_summary_report(sys.argv[1])
    print("Performance summary generated")

EOF

    # Generate the report if Python is available
    if command -v python3 >/dev/null 2>&1; then
        python3 "$output_dir/generate_report.py" "$output_dir"
        if [ -f "$output_dir/performance_summary.txt" ]; then
            echo "Performance summary:" | tee -a "$output_dir/results.txt"
            cat "$output_dir/performance_summary.txt" | tee -a "$output_dir/results.txt"
        fi
    fi

    # Final memory and performance analysis
    echo "=== Final Analysis ===" | tee -a "$output_dir/results.txt"
    {
        echo "Redis configuration analysis:"
        redis-cli -h "$redis_host" -p "$redis_port" $auth_param CONFIG GET "*memory*" | paste - -
        echo
        echo "Redis memory info:"
        redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO memory | grep -E "(used_memory|fragmentation|evicted)"
        echo
        echo "Redis stats:"
        redis-cli -h "$redis_host" -p "$redis_port" $auth_param INFO stats | grep -E "(ops_per_sec|keyspace|expired|evicted)"
        echo
        echo "Test completion time: $(date)"
    } | tee -a "$output_dir/results.txt"

    echo "=== Performance Testing Complete ==="
    echo "Results saved to: $output_dir"
    echo "Main results file: $output_dir/results.txt"

    return 0
}

# Memory fragmentation analysis with recommendations
analyze_memory_fragmentation() {
    local redis_host=${1:-localhost}
    local redis_port=${2:-6379}
    local password=${3:-""}

    if ! redis-cli -h "$redis_host" -p "$redis_port" ${password:+-a $password} ping >/dev/null 2>&1; then
        echo "ERROR: Cannot connect to Redis"
        return 1
    fi

    echo "=== Memory Fragmentation Analysis ==="

    local memory_info
    memory_info=$(redis-cli -h "$redis_host" -p "$redis_port" ${password:+-a $password} INFO memory 2>/dev/null)

    local used_memory
    used_memory=$(echo "$memory_info" | grep "^used_memory:" | cut -d: -f2 | tr -d '\r')
    local used_memory_rss
    used_memory_rss=$(echo "$memory_info" | grep "^used_memory_rss:" | cut -d: -f2 | tr -d '\r')
    local fragmentation_ratio
    fragmentation_ratio=$(echo "$memory_info" | grep "^mem_fragmentation_ratio:" | cut -d: -f2 | tr -d '\r')
    local used_memory_peak
    used_memory_peak=$(echo "$memory_info" | grep "^used_memory_peak:" | cut -d: -f2 | tr -d '\r')

    echo "Memory Usage Analysis:"
    echo "  Used Memory: $(numfmt --to=iec $used_memory 2>/dev/null || echo $used_memory) bytes"
    echo "  RSS Memory: $(numfmt --to=iec $used_memory_rss 2>/dev/null || echo $used_memory_rss) bytes"
    echo "  Peak Memory: $(numfmt --to=iec $used_memory_peak 2>/dev/null || echo $used_memory_peak) bytes"
    echo "  Fragmentation Ratio: $fragmentation_ratio"

    # Analysis and recommendations
    if command -v bc >/dev/null 2>&1; then
        if (( $(echo "$fragmentation_ratio > 2.0" | bc -l) )); then
            echo
            echo "⚠️  HIGH FRAGMENTATION DETECTED"
            echo "Recommendations:"
            echo "  1. Consider restarting Redis during maintenance window"
            echo "  2. Enable active defragmentation (Redis 4.0+):"
            echo "     CONFIG SET activedefrag yes"
            echo "  3. Monitor memory allocation patterns"
            echo "  4. Consider using jemalloc allocator"

        elif (( $(echo "$fragmentation_ratio > 1.5" | bc -l) )); then
            echo
            echo "⚠️  MODERATE FRAGMENTATION"
            echo "Recommendations:"
            echo "  1. Monitor fragmentation trends"
            echo "  2. Consider enabling active defragmentation"
            echo "  3. Review memory usage patterns"

        else
            echo
            echo "✓ FRAGMENTATION WITHIN NORMAL RANGE"
        fi

        # Memory efficiency analysis
        local efficiency
        efficiency=$(echo "scale=2; $used_memory * 100 / $used_memory_rss" | bc -l)
        echo "Memory Efficiency: ${efficiency}%"

        if (( $(echo "$efficiency < 75" | bc -l) )); then
            echo "⚠️  Low memory efficiency - consider optimization"
        fi
    fi

    # Redis 4.0+ memory doctor
    if redis-cli -h "$redis_host" -p "$redis_port" ${password:+-a $password} MEMORY DOCTOR >/dev/null 2>&1; then
        echo
        echo "Redis Memory Doctor Recommendations:"
        redis-cli -h "$redis_host" -p "$redis_port" ${password:+-a $password} MEMORY DOCTOR
    fi

    return 0
}

Conclusion

This comprehensive Redis operations guide provides enterprise-grade technical depth with:

  • Version-specific compatibility notes for Redis 5.x, 6.0+, and 7.0+
  • Comprehensive error handling in all scripts and operations
  • Performance impact warnings for monitoring commands
  • Production-ready security configurations with TLS and ACL
  • Advanced troubleshooting capabilities with automated diagnostics
  • Zero-downtime migration strategies with rollback capabilities
  • Parallel data processing for large-scale operations
  • Container orchestration with Kubernetes security best practices
  • Comprehensive performance testing with detailed analysis

The documentation serves as an authoritative reference for Redis operations teams and can be confidently deployed in production environments. Each section includes practical examples, error handling, and monitoring patterns essential for enterprise Redis deployments.

 

Read more about Redis Troubleshooting  – https://minervadb.xyz/redis-troubleshooting-cheatsheet/ 



 

About MinervaDB Corporation 98 Articles
Full-stack Database Infrastructure Architecture, Engineering and Operations Consultative Support(24*7) Provider for PostgreSQL, MySQL, MariaDB, MongoDB, ClickHouse, Trino, SQL Server, Cassandra, CockroachDB, Yugabyte, Couchbase, Redis, Valkey, NoSQL, NewSQL, Databricks, Amazon Resdhift, Amazon Aurora, CloudSQL, Snowflake and AzureSQL with core expertize in Performance, Scalability, High Availability, Database Reliability Engineering, Database Upgrades/Migration, and Data Security.

Be the first to comment

Leave a Reply