Complete Guide to Redis: Commands, FAQ, Configuration, and Troubleshooting

Table of Contents

Introduction to Redis

What is Redis?

Redis (Remote Dictionary Server) is an open-source, in-memory data structure store that can be used as a database, cache, and message broker. It’s known for its exceptional speed, simplicity, and versatility.

Key Characteristics

  • In-Memory Storage: Data is stored in RAM for ultra-fast access
  • Persistent: Can persist data to disk
  • Data Structures: Supports strings, lists, sets, sorted sets, hashes, streams, and more
  • Atomic Operations: All Redis operations are atomic
  • Pub/Sub Messaging: Built-in publish/subscribe functionality
  • Lua Scripting: Execute server-side scripts for complex operations
  • Replication: Master-slave replication support
  • Clustering: Horizontal scalability through clustering
  • Single-Threaded: Simplified concurrency model with predictable behavior

Common Use Cases

  • Caching: Speed up application performance
  • Session Storage: Store user sessions
  • Real-time Analytics: Track metrics and counters
  • Message Queue: Publish-subscribe and list-based queues
  • Rate Limiting: Implement rate limiting algorithms
  • Leaderboards: Sorted sets for rankings
  • Geospatial Indexing: Store and query location data
  • Real-time Notifications: Push notifications and event broadcasting

Check Redis Service Status (Linux/macOS)

# SystemD (most modern Linux distributions)
sudo systemctl status redis-server

# Output example:
# ● redis-server.service - Redis In-Memory Data Store
#      Loaded: loaded (/lib/systemd/redis-server.service; enabled; vendor preset: enabled)
#      Active: active (running) since Wed 2025-11-05 10:34:19 UTC; 2h 30min ago
#    Main PID: 1234 (redis-server)
#       Tasks: 1 (limit: 4915)
#      Memory: 256.5M
#      CGroup: /system.slice/redis-server.service
#              └─1234 /usr/bin/redis-server 127.0.0.1:6379

# Init.d (older systems)
sudo service redis-server status

# Check if running on macOS
brew services list | grep redis
# Check if Redis process is running
ps aux | grep redis-server

# Output example:
# redis     1234  0.5  2.1  456789  123456 ?  Ssl  10:34  0:45 /usr/bin/redis-server 127.0.0.1:6379

# More detailed information
pgrep -a redis-server

# Get PID only
pgrep redis-server

# Monitor Redis process in real-time
top -p $(pgrep redis-server)

# Or use htop (if installed)
htop -p $(pgrep redis-server)

Verify Redis is Listening on Port

# Check if Redis is listening on default port (6379)
netstat -tlnp | grep 6379

# Output example:
# tcp  0  0  127.0.0.1:6379  0.0.0.0:*  LISTEN  1234/redis-server

# Using ss command (modern alternative)
ss -tlnp | grep 6379

# Check all listening ports
netstat -tlnp | grep LISTEN

# Check specific port with lsof
sudo lsof -i :6379

# Output:
# COMMAND  PID   USER  FD  TYPE  DEVICE  SIZE/OFF  NODE  NAME
# redis-s 1234  redis   6u  IPv4  12345  0t0      TCP   localhost:6379 (LISTEN)

Check Redis Firewall Rules

# UFW (Uncomplicated Firewall)
sudo ufw status | grep 6379
sudo ufw show added | grep 6379

# iptables
sudo iptables -L -n | grep 6379

# firewalld
sudo firewall-cmd --list-all | grep 6379
sudo firewall-cmd --list-ports

# Check if port is accessible
telnet localhost 6379
# Or
nc -zv localhost 6379

# Expected output:
# Connection to localhost 6379 port [tcp/*] succeeded!

Monitor Redis Network Connections

# Show connections to Redis
netstat -tnp | grep :6379

# Show active connections
ss -tan | grep 6379

# Show established connections
ss -tnep | grep redis

# Monitor connections in real-time
watch -n 1 'ss -tnep | grep redis'

# Count total connections
ss -tnep | grep redis | wc -l

Redis CLI Status Commands

# Test connection with echo
redis-cli ECHO "status"
# Output: "status"

# Test with COMMAND COUNT
redis-cli COMMAND COUNT
# Output: 234 (number of available commands)

# Get Redis version
redis-cli SERVER
redis-cli INFO server | grep redis_version
# Output: redis_version:7.0.5

# Check currently selected database
redis-cli INFO

Redis Commands

Connecting to Redis

# Connect to local Redis instance
redis-cli

# Connect to specific host and port
redis-cli -h 192.168.1.100 -p 6379

# Connect with authentication
redis-cli -h 192.168.1.100 -p 6379 -a password

# Connect to specific database (0-15 by default)
redis-cli -n 1

# Interactive mode with verbose output
redis-cli --verbose

# Check Redis version
redis-cli --version

String Commands

Strings are the most basic Redis data type. They can hold text or binary data up to 512MB.

# Set a key-value pair
SET mykey "Hello"

# Set with expiration (seconds)
SET mykey "Hello" EX 60

# Set with expiration (milliseconds)
SET mykey "Hello" PX 60000

# Set only if key doesn't exist
SET mykey "Hello" NX

# Set only if key exists
SET mykey "Hello" XX

# Get value
GET mykey

# Get multiple values
MGET key1 key2 key3

# Set multiple key-value pairs
MSET key1 "value1" key2 "value2"

# Set multiple only if none exist
MSETNX key1 "value1" key2 "value2"

# Append to string
APPEND mykey " World"  # Result: "Hello World"

# Get string length
STRLEN mykey

# Increment numeric value
SET counter 10
INCR counter        # Result: 11
INCRBY counter 5    # Result: 16

# Decrement numeric value
DECR counter        # Result: 15
DECRBY counter 3    # Result: 12

# Increment float
INCRBYFLOAT counter 2.5

# Get substring
GETRANGE mykey 0 4  # Result: "Hello"

# Set substring
SETRANGE mykey 6 "Redis"

# Get and set new value
GETSET mykey "New Value"

# Set with get (Redis 6.2+)
GETEX mykey EX 60

Key Commands

# Check if key exists
EXISTS mykey

# Check if multiple keys exist
EXISTS key1 key2 key3

# Delete keys
DEL mykey
DEL key1 key2 key3

# Delete asynchronously (non-blocking)
UNLINK mykey

# Get key type
TYPE mykey

# Rename key
RENAME oldkey newkey

# Rename only if new key doesn't exist
RENAMENX oldkey newkey

# Set expiration time (seconds)
EXPIRE mykey 3600

# Set expiration time (milliseconds)
PEXPIRE mykey 3600000

# Set expiration as Unix timestamp
EXPIREAT mykey 1609459200

# Get time to live
TTL mykey           # Returns seconds (-1 if no expiry, -2 if doesn't exist)
PTTL mykey          # Returns milliseconds

# Remove expiration
PERSIST mykey

# Get all keys (use with caution in production!)
KEYS *

# Get keys matching pattern
KEYS user:*
KEYS *:name

# Scan keys (cursor-based iteration)
SCAN 0
SCAN 0 MATCH user:* COUNT 100

# Get database size
DBSIZE

List Commands

Lists are ordered collections of strings. Perfect for queues and stacks.

# Push element to head
LPUSH mylist "Hello"
LPUSH mylist "World" "Redis"

# Push element to tail
RPUSH mylist "End"

# Push only if list exists
LPUSHX mylist "New"

# Get list length
LLEN mylist

# Get range of elements
LRANGE mylist 0 -1      # All elements
LRANGE mylist 0 2       # First 3 elements

# Get element at index
LINDEX mylist 0

# Set element at index
LSET mylist 0 "Updated"

# Remove elements
LPOP mylist
RPOP mylist

# Remove N elements
LPOP mylist 2
RPOP mylist 2

# Get and remove from list (blocking)
BLPOP mylist timeout_seconds
BRPOP mylist timeout_seconds

# Move element between lists
LMOVE source destination LEFT RIGHT

# Blocking move
BLMOVE source destination LEFT RIGHT timeout

# Remove specific elements
LREM mylist 0 "value"   # Remove all occurrences
LREM mylist 2 "value"   # Remove first 2 occurrences
LREM mylist -1 "value"  # Remove last occurrence

# Trim list to range
LTRIM mylist 0 10

# Insert before/after
LINSERT mylist BEFORE "pivot_value" "new_value"
LINSERT mylist AFTER "pivot_value" "new_value"

Set Commands

Sets are unordered collections of unique strings. Great for deduplication and relationships.

# Add members
SADD myset "Hello"
SADD myset "World" "Redis"

# Get all members
SMEMBERS myset

# Check membership
SISMEMBER myset "Hello"

# Get set size
SCARD myset

# Remove members
SREM myset "Hello"
SREM myset "Hello" "World"

# Pop random members
SPOP myset
SPOP myset 2

# Get random members (without removing)
SRANDMEMBER myset
SRANDMEMBER myset 2

# Union of sets
SUNION set1 set2 set3
SUNIONSTORE destination set1 set2

# Intersection of sets
SINTER set1 set2
SINTERSTORE destination set1 set2

# Difference of sets
SDIFF set1 set2
SDIFFSTORE destination set1 set2

# Move member between sets
SMOVE source destination member

# Scan set members
SSCAN myset 0

Hash Commands

Hashes are maps of string fields to string values. Perfect for storing objects.

# Set single field
HSET myhash field1 "value1"

# Set multiple fields
HSET myhash field1 "value1" field2 "value2"

# Set only if field doesn't exist
HSETNX myhash field1 "value1"

# Get field value
HGET myhash field1

# Get multiple field values
HMGET myhash field1 field2 field3

# Get all fields and values
HGETALL myhash

# Get all field names
HKEYS myhash

# Get all field values
HVALS myhash

# Get number of fields
HLEN myhash

# Check if field exists
HEXISTS myhash field1

# Delete fields
HDEL myhash field1
HDEL myhash field1 field2 field3

# Increment field value
HINCRBY myhash counter 1
HINCRBYFLOAT myhash rating 2.5

# Get field string length
HSTRLEN myhash field1

# Scan hash fields
HSCAN myhash 0
HSCAN myhash 0 MATCH field* COUNT 10

Sorted Set Commands

Sorted sets are collections of unique strings ordered by score. Perfect for leaderboards.

# Add members with score
ZADD myzset 1 "one"
ZADD myzset 1 "one" 2 "two" 3 "three"

# Add with options
ZADD myzset NX 4 "four"     # Only add new
ZADD myzset XX 2 "two"      # Only update existing
ZADD myzset GT 1.5 "one"    # Only if new score greater
ZADD myzset LT 2.5 "two"    # Only if new score less

# Get number of members
ZCARD myzset

# Count members in score range
ZCOUNT myzset 1 3
ZCOUNT myzset -inf +inf

# Get member score
ZSCORE myzset "one"

# Get member rank (ascending)
ZRANK myzset "one"

# Get member rank (descending)
ZREVRANK myzset "one"

# Get range by rank
ZRANGE myzset 0 -1         # All members
ZRANGE myzset 0 -1 WITHSCORES

# Get range by rank (descending)
ZREVRANGE myzset 0 -1
ZREVRANGE myzset 0 -1 WITHSCORES

# Get range by score
ZRANGEBYSCORE myzset 1 2
ZRANGEBYSCORE myzset -inf +inf LIMIT 0 10

# Get range by score (descending)
ZREVRANGEBYSCORE myzset 2 1

# Remove members
ZREM myzset "one"
ZREM myzset "one" "two"

# Remove by rank range
ZREMRANGEBYRANK myzset 0 1

# Remove by score range
ZREMRANGEBYSCORE myzset 1 2

# Remove by lexicographic range
ZREMRANGEBYLEX myzset "[a" "[z"

# Increment member score
ZINCRBY myzset 2 "one"

# Lexicographic range
ZRANGEBYLEX myzset "-" "+" LIMIT 0 10

# Union of sorted sets
ZUNION 2 zset1 zset2
ZUNIONSTORE destination 2 zset1 zset2 WEIGHTS 2 3

# Intersection of sorted sets
ZINTER 2 zset1 zset2
ZINTERSTORE destination 2 zset1 zset2

# Difference of sorted sets
ZDIFF 2 zset1 zset2
ZDIFFSTORE destination 2 zset1 zset2

# Scan sorted set members
ZSCAN myzset 0

Key Expiration Commands

# Set key to expire in seconds
EXPIRE mykey 3600

# Set key to expire in milliseconds
PEXPIRE mykey 3600000

# Set key to expire at specific Unix timestamp
EXPIREAT mykey 1704067200

# Set key to expire at specific Unix timestamp (milliseconds)
PEXPIREAT mykey 1704067200000

# Get remaining time to live (seconds)
TTL mykey           # Returns -1 if no expiry, -2 if doesn't exist

# Get remaining time to live (milliseconds)
PTTL mykey

# Remove expiration
PERSIST mykey

# Get expiration time
PEXPIRETIME mykey   # Redis 7.0+

Server Commands

# Get server info
INFO
INFO server
INFO clients
INFO memory
INFO stats
INFO replication
INFO cpu
INFO cluster

# Get config parameter
CONFIG GET maxmemory
CONFIG GET *
CONFIG GET save

# Set config parameter
CONFIG SET maxmemory 1gb
CONFIG SET timeout 300

# Rewrite config file
CONFIG REWRITE

# Reset stats
CONFIG RESETSTAT

# Get last save time
LASTSAVE

# Save database
SAVE                # Blocking save
BGSAVE              # Non-blocking background save

# Shutdown server
SHUTDOWN
SHUTDOWN SAVE
SHUTDOWN NOSAVE

# Flush all databases
FLUSHALL
FLUSHALL ASYNC

# Flush current database
FLUSHDB
FLUSHDB ASYNC

# Get database statistics
INFO stats

# Sync with master (replication)
SYNC
PSYNC replicationid offset

# Server time
TIME

# Monitor all commands
MONITOR

# Slow log
SLOWLOG GET 10
SLOWLOG LEN
SLOWLOG RESET

# Client commands
CLIENT LIST
CLIENT INFO
CLIENT SETNAME myname
CLIENT GETNAME
CLIENT KILL ip:port
CLIENT PAUSE 1000   # Pause for 1 second

Pub/Sub Commands

# Subscribe to channel(s)
SUBSCRIBE channel1 channel2

# Subscribe to channels matching pattern
PSUBSCRIBE news:*

# Unsubscribe from channel(s)
UNSUBSCRIBE channel1

# Unsubscribe from pattern
PUNSUBSCRIBE news:*

# Publish message to channel
PUBLISH channel1 "message"

# Get number of subscribers
PUBSUB CHANNELS
PUBSUB NUMSUB channel1 channel2
PUBSUB NUMPAT

Stream Commands

Streams are like lists but with additional features for time-series data.

# Add entry to stream
XADD mystream * field1 value1 field2 value2

# Add with explicit ID
XADD mystream 1234567890 field1 value1

# Get stream length
XLEN mystream

# Read range
XRANGE mystream - +
XRANGE mystream 1000 2000

# Read range in reverse
XREVRANGE mystream + -

# Read from stream (blocking)
XREAD COUNT 2 STREAMS mystream 0
XREAD BLOCK 1000 STREAMS mystream $

# Consumer groups
XGROUP CREATE mystream mygroup 0
XREADGROUP GROUP mygroup consumer1 STREAMS mystream >

# Acknowledge message
XACK mystream mygroup message_id

# Pending messages
XPENDING mystream mygroup

# Trim stream
XTRIM mystream MAXLEN 1000

# Delete stream entries
XDEL mystream id1 id2

Transaction Commands

# Start transaction
MULTI

# Queue commands
SET key1 "value1"
GET key1
INCR counter

# Execute transaction
EXEC

# Discard transaction
DISCARD

# Watch keys for changes
WATCH key1 key2

# Unwatch keys
UNWATCH

# Example:
WATCH mykey
MULTI
SET mykey "new value"
EXEC

Script Commands

# Execute Lua script
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey myvalue

# Load script and get SHA1
SCRIPT LOAD "return 'OK'"

# Execute loaded script
EVALSHA sha1 0

# Get script status
SCRIPT EXISTS sha1

# Flush all scripts
SCRIPT FLUSH

# Kill running script
SCRIPT KILL

Cluster Commands

# Cluster info
CLUSTER INFO

# Get cluster nodes
CLUSTER NODES

# Get slots
CLUSTER SLOTS

# Add slot to node
CLUSTER ADDSLOTS slot1 slot2

# Count keys in slot
CLUSTER COUNTKEYSINSLOT slot

# Get keys in slot
CLUSTER GETKEYSINSLOT slot count

# Failover
CLUSTER FAILOVER

# Reset cluster
CLUSTER RESET

# Meet other node
CLUSTER MEET ip port


Redis FAQ

Frequently Asked Questions About Redis

Q1: What is the difference between Redis and Memcached?

A: Key differences:

FeatureRedisMemcached
Data StructuresMultiple typesOnly strings
PersistenceYes (RDB, AOF)No
ReplicationYesNo
TransactionsYes (MULTI/EXEC)No
Pub/SubYesNo
ScriptingLua scriptsNo
Memory EfficiencyGoodBetter for simple caching
Use CasesComplex, statefulSimple caching

When to use Redis: Complex data structures, persistence needed, transactions required. When to use Memcached: Simple key-value caching, distributed across many nodes.

Q2: How does Redis persistence work?

A: Redis offers two persistence mechanisms:

See also: Mastering the Linux Command Line — Your Complete Free Training Guide

RDB (Redis Database):

# Point-in-time snapshot of dataset
SAVE            # Blocking save
BGSAVE          # Non-blocking background save

# Configuration
save 900 1          # Save every 15 min if at least 1 key changed
save 300 10         # Save every 5 min if at least 10 keys changed
save 60 10000       # Save every 60 sec if at least 10000 keys changed

AOF (Append-Only File):

# Configuration
appendonly yes
appendfsync always      # Fsync after every write (safest, slowest)
appendfsync everysec    # Fsync every second (default)
appendfsync no          # Let OS handle fsync (fastest)

RDB Pros: Compact, fast recovery RDB Cons: Can lose recent data

AOF Pros: Safer, more data loss protection AOF Cons: Larger file size, slower

Q3: What is Redis eviction policy?

A: When Redis reaches max memory, it evicts keys based on the eviction policy:

# Configuration
maxmemory 256mb
maxmemory-policy <policy>

Available Policies:

  • noeviction: Return error when max memory reached (default)
  • allkeys-lru: Evict least recently used keys
  • allkeys-lfu: Evict least frequently used keys
  • volatile-lru: Evict least recently used keys with expiration
  • volatile-lfu: Evict least frequently used keys with expiration
  • volatile-ttl: Evict keys with shortest TTL
  • volatile-random: Evict random keys with expiration
  • allkeys-random: Evict random keys

Example:

CONFIG SET maxmemory-policy allkeys-lru

Q4: How do I implement caching with Redis?

A: Simple caching pattern:

# Check cache
GETEX cache_key EX 3600

# If null, fetch from database
# Query database
# Store in cache
SET cache_key $data EX 3600

# Pattern in code (pseudocode):
cache_value = redis.get("user:123")
if cache_value is null:
    cache_value = database.query("SELECT * FROM users WHERE id=123")
    redis.set("user:123", cache_value, "EX", 3600)
return cache_value

Q5: What is a Redis key expiration?

A: Redis keys can automatically expire after a specified time:

# Set key with expiration
SET mykey "value" EX 3600       # Expires in 1 hour
SET mykey "value" PX 3600000    # Expires in 3600000 milliseconds

# Or set expiration on existing key
EXPIRE mykey 3600               # Set expiration to 3600 seconds
PEXPIRE mykey 3600000           # Set expiration to milliseconds
EXPIREAT mykey 1704067200       # Expire at Unix timestamp
PEXPIREAT mykey 1704067200000   # Expire at Unix timestamp (ms)

# Check expiration
TTL mykey           # Returns seconds
PTTL mykey          # Returns milliseconds

# Remove expiration
PERSIST mykey

Q6: How do I implement session storage with Redis?

A: Simple session storage pattern:

# Store session
HSET session:user123 username "john" email "[email protected]" created_at "2025-11-05"
EXPIRE session:user123 86400    # Expire in 24 hours

# Retrieve session
HGETALL session:user123

# Update session field
HSET session:user123 last_activity "2025-11-05 10:30:00"

# Delete session
DEL session:user123

# Example with JSON:
SET session:user123 '{"username":"john","email":"[email protected]"}' EX 86400

Q7: What is Redis replication?

A: Master-Slave replication for high availability:

Slave Configuration:

# redis.conf
slaveof master_host master_port
# or
replicaof master_host master_port  # Redis 5.0+

# Verify replication
INFO replication

Manual Replication:

# Connect to slave Redis CLI
SLAVEOF master_host master_port

# Or
REPLICAOF master_host master_port

# Stop replication
SLAVEOF NO ONE

Q8: What is Redis Cluster?

A: Horizontal scaling through partitioning:

# Create cluster (requires cluster-enabled in config)
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \\\\
          127.0.0.1:7002 127.0.0.1:7003 \\\\
          127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1

# Check cluster status
CLUSTER INFO
CLUSTER NODES
CLUSTER SLOTS

Q9: How do I implement a rate limiter with Redis?

A: Simple sliding window rate limiter:

# Sliding window algorithm
INCR rate_limit:user123
EXPIRE rate_limit:user123 60     # Window of 60 seconds

# Check if limit exceeded (max 10 requests per minute)
current = GET rate_limit:user123
if current >= 10:
    return "Rate limit exceeded"
else:
    INCR rate_limit:user123
    return "OK"

# Token bucket algorithm (pseudocode):
SET bucket:user123 1000 EX 3600  # Refill every hour
DECRBY bucket:user123 cost       # Deduct cost per request

Q10: What’s the difference between SAVE and BGSAVE?

A:

  • SAVE: Blocks all clients while saving to disk (synchronous)
  • BGSAVE: Saves in background, clients can continue (asynchronous)
# Use BGSAVE in production to avoid blocking
BGSAVE

# Check save status
LASTSAVE

Q11: How do I monitor Redis performance?

A: Use monitoring tools and commands:

# Get comprehensive info
INFO all

# Monitor client connections
INFO clients

# Monitor memory usage
INFO memory

# Monitor CPU usage
INFO cpu

# Get slow queries
SLOWLOG GET 10

# Real-time command monitoring
MONITOR

# Get stats
INFO stats

# Check Redis memory usage
INFO memory | grep used_memory_human

Q12: What is Lua scripting in Redis?

A: Execute scripts atomically on Redis server:

# Simple script
EVAL "return 'Hello'" 0

# With keys and arguments
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey myvalue

# Script with conditions
EVAL "if redis.call('EXISTS', KEYS[1]) == 1 then
        return redis.call('GET', KEYS[1])
      else
        return nil
      end" 1 mykey

# Load script
SCRIPT LOAD "return 'OK'"

# Execute loaded script
EVALSHA sha1 0

Q13: How do I handle high availability with Redis?

A: Use Redis Sentinel for automatic failover:

# Sentinel configuration (sentinel.conf)
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000

# Start Sentinel
redis-sentinel sentinel.conf

# Connect to Sentinel
redis-cli -p 26379

# Get master info
SENTINEL masters
SENTINEL slaves mymaster
SENTINEL get-master-addr-by-name mymaster

Q14: How do I perform backup and restore?

A:

# Backup
BGSAVE
# Copy dump.rdb file to safe location
cp /var/lib/redis/dump.rdb /backup/dump.rdb

# Restore
# Stop Redis
sudo systemctl stop redis-server

# Copy backup file
cp /backup/dump.rdb /var/lib/redis/dump.rdb

# Restart Redis
sudo systemctl start redis-server

Q15: What are common security issues with Redis?

A: Security considerations:

# Set password
requirepass "your_secure_password"

# Or set in command
CONFIG SET requirepass "your_secure_password"

# Bind to specific IP (not all interfaces)
bind 127.0.0.1 192.168.1.100

# Disable dangerous commands
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""

# Use ACLs (Redis 6+)
ACL LIST
ACL SETUSER username on >password ~* &* +@all


Redis Configuration

Redis Configuration Files and Parameters

Main Configuration File: /etc/redis/redis.conf

1. Network Configuration

# Accept connections from all interfaces
bind 0.0.0.0

# Or specific IPs
bind 127.0.0.1 192.168.1.100

# Listening port
port 6379

# TCP listen backlog
tcp-backlog 511

# TCP keepalive
tcp-keepalive 300

# Timeout for idle clients (seconds)
timeout 0

# Enable IPv6
bind-ipv6-addr [::1]

2. General Configuration

# Run as daemon
daemonize yes

# Process ID file
pidfile /var/run/redis/redis-server.pid

# Logging level
loglevel notice           # debug, verbose, notice, warning

# Log file
logfile ""                # Empty string = stdout
logfile "/var/log/redis/redis-server.log"

# System log
syslog-enabled no
syslog-ident redis
syslog-facility local0

# Database count
databases 16

# Welcome message
always-show-logo yes

3. Snapshot (RDB) Configuration

# Save database
save 900 1              # After 900 sec if at least 1 key changed
save 300 10             # After 300 sec if at least 10 keys changed
save 60 10000           # After 60 sec if at least 10000 keys changed

# Disable saving
save ""

# Stop writes if save fails
stop-writes-on-bgsave-error yes

# Compress RDB
rdbcompression yes

# Checksum RDB
rdbchecksum yes

# RDB filename
dbfilename dump.rdb

# RDB directory
dir /var/lib/redis

# Load truncated RDB
sanitize-dump-payload yes

4. AOF (Append-Only File) Configuration

# Enable AOF
appendonly no
appendonly yes

# AOF filename
appendfilename "appendonly.aof"

# AOF fsync policy
appendfsync always          # Fsync after every write (safest)
appendfsync everysec        # Fsync every second (default)
appendfsync no              # Let OS decide

# Prevent fsync during rewrite
no-appendfsync-on-rewrite no

# Auto rewrite AOF
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# AOF rewrite
aof-rewrite-incremental-fsync yes

5. Memory Management

# Maximum memory
maxmemory 256mb

# Memory eviction policy
maxmemory-policy noeviction
# Other options:
# allkeys-lru, allkeys-lfu, allkeys-random
# volatile-lru, volatile-lfu, volatile-ttl, volatile-random

# Memory samples for eviction
maxmemory-samples 5

# Check memory threshold (percentage)
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100

# Lazy free configuration
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no

6. Replication Configuration

# Replication role
# For slave/replica:
replicaof master_host master_port

# Replication authentication
masterauth "master_password"

# Replica read-only
replica-read-only yes

# Replication disk or socket
repl-diskless-sync no
repl-diskless-sync-delay 5

# Disable TCP_NODELAY on replica
repl-disable-tcp-nodelay no

# Replica backlog
repl-backlog-size 1mb
repl-backlog-ttl 3600

7. Security Configuration

# Set password
requirepass "your_secure_password"

# User ACL (Redis 6+)
aclfile /etc/redis/users.acl

# ACL log
acllog-max-len 128

# Rename dangerous commands
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG "CONFIG_7b9a5e1f"

8. Clients Configuration

# Max number of connected clients
maxclients 10000

# Client tracking
tracking-info-threshold 100

9. Pub/Sub Configuration

# Pub/Sub channel patterns
pubsub-channels-db 0

10. Cluster Configuration

# Enable cluster mode
cluster-enabled yes

# Cluster node timeout
cluster-node-timeout 15000

# Cluster replica validity factor
cluster-replica-validity-factor 10

# Cluster migration barrier
cluster-migration-barrier 1

11. Slow Log Configuration

# Slow log threshold (microseconds)
slowlog-log-slower-than 10000

# Slow log max length
slowlog-max-len 128

12. Event Notification Configuration

# Enable keyspace notifications
notify-keyspace-events ""

# Example:
# notify-keyspace-events "Ex"   # Expired key events
# notify-keyspace-events "K$"   # Keyspace notifications

13. Advanced Configuration

# Disable LATENCY monitoring
latency-monitor-threshold 0

# Frequency of rehashing hash table
hz 10

# Enable dynamic HZ
dynamic-hz yes

# Enable active defragmentation
activerehashing yes

# Min percentage CPU for active defrag
active-defrag-running-percentage 25

# Disable crash handler
crash-log-enabled yes

# Enable crash restart
crash-memcheck-enabled yes

14. Lua Scripting Configuration

# Max execution time for Lua script (milliseconds)
lua-time-limit 5000

# Enable Lua debugging
ldb-sync-mode no

Example Complete Configuration

# Example: /etc/redis/redis-production.conf

# Network
bind 0.0.0.0
port 6379
tcp-backlog 511
timeout 300
tcp-keepalive 300

# General
daemonize yes
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile "/var/log/redis/redis-server.log"
databases 16

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

# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# Memory
maxmemory 4gb
maxmemory-policy allkeys-lru

# Replication
replicaof 192.168.1.10 6379
masterauth "master_password"
replica-read-only yes

# Security
requirepass "redis_password"
rename-command FLUSHDB ""
rename-command FLUSHALL ""

# Cluster (if enabled)
cluster-enabled no

# Slow Log
slowlog-log-slower-than 10000
slowlog-max-len 128


Troubleshooting Redis Issues

Comprehensive Redis Troubleshooting Guide

Step 1: Verify Redis is Running

# Check if Redis process is running
ps aux | grep redis-server

# Check if Redis is listening
netstat -tlnp | grep 6379
ss -tlnp | grep 6379

# Check Redis service status
sudo systemctl status redis-server

# Try to connect
redis-cli ping

# Expected output: PONG

Troubleshooting:

# If not running, start Redis
sudo systemctl start redis-server

# Check for errors
sudo journalctl -u redis-server -n 50
tail -f /var/log/redis/redis-server.log

Step 2: Check Connection Issues

# Test basic connectivity
redis-cli -h localhost -p 6379 ping

# Test with hostname
redis-cli -h redis.example.com ping

# Test with password
redis-cli -h localhost -p 6379 -a password ping

# Test socket connection (if configured)
redis-cli -s /var/run/redis/redis.sock ping

Common Issues:

# Error: Could not connect to Redis at 127.0.0.1:6379
# Solution 1: Check if Redis is running
sudo systemctl status redis-server

# Solution 2: Check if binding to correct interface
CONFIG GET bind

# Solution 3: Check firewall
sudo iptables -L -n | grep 6379
sudo firewall-cmd --list-all | grep 6379

# Error: DENIED Redis is running in protected mode
# Solution: Require password or disable protected mode
CONFIG SET protected-mode no
# Or set password and disable protected mode
CONFIG SET requirepass "password"

Step 3: Memory Issues

# Check memory usage
INFO memory

# Memory breakdown:
# used_memory: Total memory used
# used_memory_rss: Resident set size
# used_memory_peak: Peak memory used
# mem_fragmentation_ratio: Memory fragmentation ratio

# Get specific value
INFO memory | grep used_memory_human

# Check max memory setting
CONFIG GET maxmemory

# Check eviction policy
CONFIG GET maxmemory-policy

Troubleshooting High Memory:

# Check largest keys
redis-cli --bigkeys

# Sample keys
redis-cli --scan | head -1000

# Check keys using memory
INFO keyspace

# Find large strings
SCAN 0 MATCH * COUNT 1000
GET key_name
STRLEN key_name

# Set max memory if not set
CONFIG SET maxmemory 2gb

# Set eviction policy
CONFIG SET maxmemory-policy allkeys-lru

# Clear cache
FLUSHALL

Step 4: Performance Issues

# Check slow log
SLOWLOG GET 10

# Example output:
# 1) (integer) 15
# 2) (integer) 1635161234
# 3) (integer) 56000
# 4) list of command and args
# 5) source IP
# 6) source port

# Reset slow log
SLOWLOG RESET

# Monitor commands in real-time
MONITOR

# Check statistics
INFO stats

# Check CPU usage
top -p $(pgrep redis-server)

Optimization Tips:

# 1. Use pipelining (batch commands)
# 2. Use Lua scripts for complex operations
# 3. Reduce key size
# 4. Use hashes for related data
# 5. Enable RDB snapshots instead of AOF if persistence not critical
# 6. Increase tcp-backlog if many connections queue
# 7. Tune maxclients parameter

Step 5: Persistence Issues

# Check RDB configuration
CONFIG GET save
CONFIG GET dbfilename
CONFIG GET dir

# Check if RDB exists
ls -la /var/lib/redis/dump.rdb

# Force save
BGSAVE              # Background save
SAVE                # Blocking save

# Get last save time
LASTSAVE

# Check AOF
CONFIG GET appendonly
CONFIG GET appendfilename
ls -la /var/lib/redis/appendonly.aof

Troubleshooting Persistence:

# Error: Can't open the DB file for writing
# Solution: Check file permissions
sudo chown redis:redis /var/lib/redis/
sudo chmod 755 /var/lib/redis/

# Error: ERR AOF is in an inconsistent state
# Solution: Repair AOF
redis-check-aof --fix /var/lib/redis/appendonly.aof

# Error: Can't load the dataset because of errors
# Solution: Check RDB file
redis-check-rdb /var/lib/redis/dump.rdb

# Reclaim disk space from AOF
BGREWRITEAOF

Step 6: Replication Issues

# Check replication status
INFO replication

# Output for master:
# role:master
# connected_slaves:1
# slave0:ip=192.168.1.20,port=6379,state=online

# Output for slave:
# role:slave
# master_host:192.168.1.10
# master_port:6379
# master_link_status:up

# Force resync
SYNC                # Full resync
PSYNC ?             # Partial resync

Troubleshooting Replication:

# Slave not syncing
# Solution 1: Check master is accessible
ping 192.168.1.10 -c 3

# Solution 2: Set replication on slave
REPLICAOF 192.168.1.10 6379

# Solution 3: Check password on master
CONFIG GET requirepass

# Slave can't connect:
# Check firewall
sudo ufw allow 6379/tcp

# Check replicaof setting
CONFIG GET replicaof

# Check master password
CONFIG SET masterauth "password"

# Large replication lag
# Solution: Increase repl-backlog-size
CONFIG SET repl-backlog-size 100mb

# Increase bandwidth
# Use multiple replicas for load distribution

Step 7: Cluster Issues

# Check cluster status
CLUSTER INFO

# Get cluster nodes
CLUSTER NODES

# Check slots
CLUSTER SLOTS

# Test cluster connection
redis-cli -c -h cluster_node
CLUSTER KEYSLOT keyname

# Reshard cluster
redis-cli --cluster reshard 127.0.0.1:7000

# Fix cluster
redis-cli --cluster fix 127.0.0.1:7000

Step 8: Pub/Sub Issues

# Check subscriber count
PUBSUB CHANNELS

# Get subscribers for channel
PUBSUB NUMSUB channel1 channel2

# Get pattern subscribers
PUBSUB NUMPAT

# Test pub/sub
# Terminal 1: SUBSCRIBE channel1
# Terminal 2: PUBLISH channel1 "message"

Common Redis Errors and Solutions

# Error: "OOM command not allowed when used memory > 'maxmemory'"
# Problem: Redis reached max memory
# Solution:
CONFIG SET maxmemory 4gb
CONFIG SET maxmemory-policy allkeys-lru
FLUSHALL

# Error: "MISCONF Redis is configured to save RDB snapshots"
# Problem: Disk full or permission denied
# Solution:
BGSAVE
# Or disable persistence temporarily
CONFIG SET save ""

# Error: "READONLY You can't write against a read only replica"
# Problem: Connected to slave/replica
# Solution: Connect to master or promote replica

# Error: "ERR command not allowed in loading data mode"
# Problem: Redis is loading from disk
# Solution: Wait for Redis to load data
LASTSAVE
INFO

# Error: "NOSCRIPT No matching script"
# Problem: Script SHA not found
# Solution: Load script again
SCRIPT LOAD "..."
EVALSHA sha1 ...

# Error: "TIMEOUT: Blocking operation timed out"
# Problem: Blocking operation exceeded timeout
# Solution: Check queue size, increase timeout

Performance Monitoring Script

#!/bin/bash
# Redis monitoring script

echo "=== Redis Performance Monitoring ==="
echo ""

# Connected clients
echo "Connected Clients:"
redis-cli INFO clients | grep connected_clients

# Memory usage
echo ""
echo "Memory Usage:"
redis-cli INFO memory | grep used_memory_human

# Keys count
echo ""
echo "Database Statistics:"
redis-cli INFO keyspace

# Slow queries
echo ""
echo "Recent Slow Queries:"
redis-cli SLOWLOG GET 3

# Replication status
echo ""
echo "Replication Status:"
redis-cli INFO replication | grep -E "role:|connected_slaves"

# CPU usage
echo ""
echo "CPU Usage:"
ps aux | grep redis-server | grep -v grep | awk '{print "CPU: " $3 "%", "MEM: " $4 "%"}'


Best Practices

Redis Best Practices

1. Data Structure Selection

# Use hash for objects, not individual strings
# ❌ Bad
SET user:123:name "John"
SET user:123:email "[email protected]"
SET user:123:age 30

# ✅ Good
HSET user:123 name "John" email "[email protected]" age 30

2. Key Naming Convention

# Use consistent naming with colons as separators
user:123              # Single user
user:123:profile      # User profile
session:abc123        # Session
cache:product:456     # Product cache
queue:emails          # Email queue

3. Expiration Strategy

# Always set expiration for cache keys
SET cache_key $data EX 3600

# Use EXAT for specific time
SET cache_key $data EXAT 1704067200

# Set expiration after insertion
SET cache_key $data
EXPIRE cache_key 3600

4. Connection Pooling

# Python example with connection pool
import redis
pool = redis.ConnectionPool(
    host='localhost',
    port=6379,
    max_connections=50
)
r = redis.Redis(connection_pool=pool)

5. Error Handling

# Always handle connection errors
try:
    result = redis.get('key')
except redis.ConnectionError:
    # Fallback to database
    pass
except redis.TimeoutError:
    # Handle timeout
    pass

6. Batch Operations

# Use pipelining for multiple commands
pipe = redis.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.get('key1')
results = pipe.execute()

# Or MGET, MSET for bulk operations
MGET key1 key2 key3
MSET key1 value1 key2 value2

7. Memory Optimization

# Compress large values before storing
import json
import zlib

data = json.dumps(large_dict)
compressed = zlib.compress(data.encode())
redis.set('key', compressed)

# Retrieve and decompress
compressed = redis.get('key')
data = json.loads(zlib.decompress(compressed))

8. Monitoring and Logging

# Enable slow log
CONFIG SET slowlog-log-slower-than 1000

# Monitor periodically
INFO stats
INFO memory
INFO cpu

# Set up alerts for:
# - High memory usage
# - Slow queries
# - Connection spikes
# - Replication lag

9. Security

# Always set password
requirepass "strong_password_with_special_chars"

# Limit network exposure
bind 127.0.0.1 192.168.1.100

# Disable dangerous commands
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""

# Use ACLs (Redis 6+)
ACL SETUSER app_user on >apppassword ~* &* +@all -@admin

# Enable TLS/SSL for remote connections
tls-port 6380
tls-cert-file /path/to/cert.pem
tls-key-file /path/to/key.pem

10. Backup Strategy

# Regular backups
BGSAVE

# Backup script
#!/bin/bash
BACKUP_DIR="/backups/redis"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
redis-cli BGSAVE
cp /var/lib/redis/dump.rdb $BACKUP_DIR/dump_$TIMESTAMP.rdb
# Upload to S3/cloud storage


Conclusion

Redis is a powerful, versatile in-memory data store that excels in various use cases from caching to real-time analytics. Key takeaways:

  1. Choose the right data structure for your use case
  2. Implement proper expiration strategies for cache items
  3. Monitor performance continuously
  4. Plan for persistence based on your requirements
  5. Scale appropriately using replication or clustering
  6. Secure properly with passwords and network restrictions
  7. Backup regularly and test recovery procedures

For more information:

David Cao
David Cao

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

Articles: 547

Leave a Reply

Your email address will not be published. Required fields are marked *