Redis Reference
In-memory key-value store for caching, queues, pub/sub, and session management.
CLI Basics
# Local instance (default port 6379)
redis-cli
# Remote with authentication
redis-cli -h redis.example.com -p 6379 -a 'password'
# Execute single command
redis-cli PING
# PONG
# Select database (0-15, default is 0)
redis-cli -n 1
redis-cli INFO server # version, uptime, config
redis-cli INFO memory # memory usage
redis-cli INFO keyspace # per-database key counts
redis-cli DBSIZE # key count in current db
redis-cli MONITOR # real-time command stream (debug only)
Data Types and Operations
Strings
The most basic type. Used for caching, counters, flags.
redis-cli <<'EOF'
SET session:abc123 '{"user": "evan", "role": "admin"}'
GET session:abc123
# Set with TTL (seconds)
SET cache:device:42 '{"hostname": "sw-core-01"}' EX 3600
# Set only if not exists (distributed lock primitive)
SET lock:deploy nx EX 30
# Atomic increment (counters)
INCR page:views:home
INCRBY api:ratelimit:user42 1
EOF
Hashes
Field-value maps attached to a key. Like a small dictionary per key.
redis-cli <<'EOF'
HSET device:42 hostname "sw-core-01" ip "10.50.1.10" vlan 10
HGET device:42 hostname
HGETALL device:42
HINCRBY device:42 vlan 10
EOF
Hashes are memory-efficient for objects with many fields compared to serializing JSON into a string key.
Lists
Ordered sequences. Used for queues, recent items, timelines.
redis-cli <<'EOF'
LPUSH queue:jobs '{"task": "backup", "target": "db-01"}'
LPUSH queue:jobs '{"task": "scan", "target": "web-01"}'
# Read all items (0 = start, -1 = end)
LRANGE queue:jobs 0 -1
# Pop from right (FIFO queue)
RPOP queue:jobs
# Blocking pop (wait up to 30 seconds for a new item)
BRPOP queue:jobs 30
EOF
Sets
Unordered unique collections. Good for tags, membership, deduplication.
redis-cli <<'EOF'
SADD vlan:10:devices "sw-core-01" "sw-dist-01" "ap-lobby-01"
SADD vlan:20:devices "sw-core-01" "sw-dist-02"
SMEMBERS vlan:10:devices
SISMEMBER vlan:10:devices "sw-core-01"
# Set operations
SINTER vlan:10:devices vlan:20:devices # devices in both VLANs
SDIFF vlan:10:devices vlan:20:devices # devices only in VLAN 10
SUNION vlan:10:devices vlan:20:devices # all devices
EOF
Sorted Sets
Sets with a score for ranking. Leaderboards, priority queues, time-series indices.
redis-cli <<'EOF'
ZADD alerts:severity 1 "info:disk-80" 5 "warn:cpu-90" 10 "crit:mem-95"
# Top 3 by score (ascending)
ZRANGE alerts:severity 0 2 WITHSCORES
# Descending
ZREVRANGE alerts:severity 0 2 WITHSCORES
# By score range
ZRANGEBYSCORE alerts:severity 5 10 WITHSCORES
EOF
Key Management
redis-cli <<'EOF'
# Set TTL on existing key
EXPIRE session:abc123 1800 # 30 minutes
# Check remaining TTL
TTL session:abc123 # seconds remaining, -1 = no expiry, -2 = expired/missing
# Remove TTL (make persistent)
PERSIST session:abc123
# Find keys by pattern (avoid KEYS in production -- blocks the server)
SCAN 0 MATCH "session:*" COUNT 100
# Delete
DEL session:abc123
UNLINK session:abc123 # async delete (non-blocking)
EOF
KEYS * blocks the entire Redis server while scanning. Use SCAN with a cursor in production.
|
Pub/Sub
# Terminal 1: subscribe
redis-cli SUBSCRIBE alerts:network
# Terminal 2: publish
redis-cli PUBLISH alerts:network '{"type": "link_down", "device": "sw-core-01"}'
Pub/Sub is fire-and-forget. If no subscriber is listening, the message is lost. For durable messaging, use Redis Streams or a proper message broker.
Persistence
# Check current persistence config
redis-cli CONFIG GET save # RDB snapshot intervals
redis-cli CONFIG GET appendonly # AOF enabled?
# Manual snapshot
redis-cli BGSAVE
# Manual AOF rewrite (compact the log)
redis-cli BGREWRITEAOF
-
RDB — point-in-time snapshots. Fast recovery, but data since last snapshot is lost on crash.
-
AOF — logs every write. Slower recovery, but minimal data loss (fsync policy dependent).
-
Both together provides best durability with fast recovery.
Python Integration
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# Strings
r.set('session:abc', '{"user": "evan"}', ex=3600)
print(r.get('session:abc'))
# Hashes
r.hset('device:42', mapping={'hostname': 'sw-core-01', 'vlan': '10'})
print(r.hgetall('device:42'))
# Pipeline: batch commands (reduces round-trips)
with r.pipeline() as pipe:
pipe.incr('counter:a')
pipe.incr('counter:b')
pipe.get('counter:a')
results = pipe.execute()