Redis Production-Grade Configuration and Operations Guide

Overview

Redis is a blazing-fast in-memory key-value store widely used as a cache, real-time message broker, session store, and persistent database. For production use, Redis requires careful configuration to ensure stability, performance, and security across different use cases.

This blog provides a comprehensive guide to deploying Redis in production, including configurations, operational best practices, troubleshooting, and commands.


Use Case-Based Configuration

1. Redis as a Celery Message Broker

Purpose: Fast, ephemeral task queue backend

Configuration:

save “”                     # Disable RDB
appendonly no               # Disable AOF
maxmemory 0                 # Use full memory
maxmemory-policy noeviction

Systemd Service Suggestions:

Restart=always
RestartSec=5
LimitNOFILE=65535

Commands:

redis-cli CONFIG SET save “”
redis-cli CONFIG SET appendonly no

2. Redis as a Persistent Cache

Purpose: Durable in-memory storage with backup

Configuration:

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

Memory Policy:

maxmemory 2gb
maxmemory-policy allkeys-lru

3. Redis as a Pub/Sub System

Purpose: Low-latency messaging (chat apps, real-time notifications)

Configuration:

save “”
appendonly no
tcp-keepalive 60

Security Best Practices

# Authentication
requirepass YourStrongPassword

# Binding
bind 127.0.0.1 ::1

# Rename risky commands
rename-command FLUSHALL “”
rename-command FLUSHDB “”
rename-command CONFIG “”
rename-command SHUTDOWN “”

# Protected mode
protected-mode yes

Persistence Options

TypeUse CaseConfigurationNotes
RDBSnapshot backupssave 900 1Compact, efficient
AOFFull durabilityappendonly yesLogs every write
HybridRDB + AOFBoth enabledRecommended in Redis 7+

Enhanced Options:

rdb-save-incremental-fsync yes
aof-use-rdb-preamble yes

High Availability & Scalability

Redis Replication

# Replica setup

replicaof 192.168.1.100 6379

  • One master, many read-only replicas

Redis Sentinel

redis-sentinel /etc/redis/sentinel.conf

  • Monitor, alert, and auto-failover

Redis Cluster

redis-cli –cluster create <nodes> –cluster-replicas 1

  • Sharded, scalable Redis with data partitioning

Systemd Redis Service Template

[Unit]
Description=Advanced key-value store
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
PIDFile=/run/redis/redis-server.pid
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=2755
UMask=007
PrivateTmp=yes
LimitNOFILE=65535
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWritePaths=-/var/lib/redis
ReadWritePaths=-/var/log/redis
ReadWritePaths=-/var/run/redis
NoNewPrivileges=true
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
ProtectSystem=true
ReadWriteDirectories=-/etc/redis

[Install]
WantedBy=multi-user.target
Alias=redis.service

OS-Level Tuning and Kernel Settings

Set Overcommit Memory (important for RDB persistence):

echo “vm.overcommit_memory=1” >> /etc/sysctl.conf
sysctl -p
  • Ensures Linux doesn’t refuse memory allocations during fork(), required by RDB snapshots.

Transparent Huge Pages (THP) should be disabled:

echo never > /sys/kernel/mm/transparent_hugepage/enabled

Add to /etc/rc.local or system startup script for persistence.


Redis RDB/AOF Path Management

To Set or Confirm RDB Save Path:

In redis.conf:

dir /var/lib/redis

Via command:

redis-cli CONFIG SET dir /var/lib/redis

To check current:

redis-cli CONFIG GET dir

Same applies for AOF if enabled.


Benchmarking Redis

redis-benchmark -q -n 100000 -c 50 -P 10

Troubleshooting Redis

Memory Bloat

redis-cli INFO memory
  • Set maxmemory
  • Use eviction: allkeys-lru

OOM Kill

dmesg | grep -i kill
  • Add swap: fallocate -l 2G /swapfile

RDB/AOF Failures

tail -n 50 /var/log/redis/redis-server.log
  • Check disk
  • Ensure Redis user has write permissions

Operational Commands Cheat Sheet

PurposeCommand
Check memory usageredis-cli INFO memory
List active clientsredis-cli CLIENT LIST
Live commands monitorredis-cli MONITOR
Flush database (with caution)redis-cli FLUSHALL
Disable RDB & AOF (temporary)CONFIG SET save “” & CONFIG SET appendonly no
Rewrite config safelyredis-cli CONFIG REWRITE
Slow query logredis-cli slowlog get
Uptime statusredis-cli INFO server
Commands per second`redis-cli INFO statsgrep instantaneous_ops_per_sec`
Show configured save pathsredis-cli CONFIG GET dir

Sample redis.conf (Production)

bind 127.0.0.1
port 6379
daemonize yes
supervised systemd
logfile “/var/log/redis/redis-server.log”

# Memory
maxmemory 4gb
maxmemory-policy allkeys-lru

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

# Security
requirepass MyStrongPassword
rename-command FLUSHALL “”

# Networking
tcp-keepalive 60
timeout 0

Dockerfile for Redis (Production-Grade)

dockerfile

FROM redis:7.2-alpine

# Add custom config if needed
COPY redis.conf /usr/local/etc/redis/redis.conf

# Set working directory for data persistence
RUN mkdir -p /data && chown redis:redis /data

# Expose Redis port
EXPOSE 6379

# Entry command
CMD [“redis-server”, “/usr/local/etc/redis/redis.conf”]

Use a redis.conf that includes:

  • requirepass
  • appendonly yes
  • dir /data
  • maxmemory + maxmemory-policy

Kubernetes Redis Production StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  labels:
    app: redis
spec:
  serviceName: “redis”
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      – name: redis
        image: redis:7.2-alpine
        command: [“redis-server”, “/data/redis.conf”]
        ports:
        – containerPort: 6379
        volumeMounts:
        – name: redis-data
          mountPath: /data
        resources:
          requests:
            memory: “256Mi”
            cpu: “250m”
          limits:
            memory: “1Gi”
            cpu: “1”
        livenessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 15
          periodSeconds: 20
        readinessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 5
          periodSeconds: 10
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
  volumeClaimTemplates:
  – metadata:
      name: redis-data
    spec:
      accessModes: [“ReadWriteOnce”]
      resources:
        requests:
          storage: 5Gi

Tips:

  • Use a ConfigMap or mount a redis.conf file to /data/redis.conf.
  • Set requirepass, disable FLUSHALL, and configure persistence if needed.
  • For HA, use Redis Sentinel or cluster mode with headless services.

Final Recommendations

  • Disable persistence when Redis is used purely as a transient broker.
  • Set memory caps and policies to avoid system crashes.
  • Use Sentinel or clustering for high availability.
  • Monitor Redis constantly: use Redis INFO, slow logs, and metrics.
  • Backup configs and RDB/AOF files periodically if persistence is on.
  • Harden security with password, firewalls, and renamed commands.
  • Adjust kernel parameters like vm.overcommit_memory to avoid fork issues.
  • Use CONFIG SET dir to ensure your RDB or AOF directory is correct and writable.

Leave a Reply

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