Redis 简介

什么是 Redis?

Redis(远程字典服务器)是一个开源的内存数据结构存储,可以用作数据库、缓存和消息代理。它以其卓越的速度、简单性和多功能性而闻名。

关键特性

  • 内存存储 :数据存储在 RAM 中,实现超快速访问
  • 持久化 :可以将数据持久化到磁盘
  • 数据结构 :支持字符串、列表、集合、有序集合、哈希、流等
  • 原子操作 :所有 Redis 操作都是原子的
  • 发布/订阅消息 :内置的发布/订阅功能
  • Lua 脚本 :执行服务器端脚本以进行复杂操作
  • 复制 :支持主从复制
  • 集群 :通过集群实现水平扩展
  • 单线程 :简化并发模型,行为可预测

常见用途

  • 缓存 :提升应用程序性能
  • 会话存储 :存储用户会话
  • 实时分析 :跟踪指标和计数器
  • 消息队列 :发布-订阅和基于列表的队列
  • 速率限制 :实现速率限制算法
  • 排行榜 :排序集用于排名
  • 地理空间索引 :存储和查询位置数据
  • 实时通知 :推送通知和事件广播

检查 Redis 服务状态(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)

验证 Redis 是否在监听端口

# 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)

检查 Redis 防火墙规则

# 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!

监控 Redis 网络连接

# 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 命令行状态命令

# 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 命令

连接到 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

字符串命令

字符串是 Redis 最基本的数据类型。它们可以存储最多 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

关键命令

# 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

列出命令

列表是有序的字符串集合。非常适合队列和栈。

# 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"

集合命令

集合是无序的唯一字符串集合。非常适合去重和建立关系。

# 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

哈希命令

哈希是字符串字段到字符串值的映射。非常适合存储对象。

# 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

有序集合命令

有序集合是按分数排序的唯一字符串集合。非常适合排行榜。

# 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

过期命令

# 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+

服务器命令

# 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

发布/订阅命令

# 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

流命令

流类似于列表,但具有针对时间序列数据的一些附加功能。

# 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

事务命令

# 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

脚本命令

# 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 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 常见问题

关于 Redis 的常见问题

Q1: Redis 和 Memcached 有什么区别?

A: 主要区别:

特性 Redis Memcached
数据结构 多种类型 仅字符串
持久化 是(RDB,AOF)
复制
事务 是(MULTI/EXEC)
发布/订阅
脚本 Lua 脚本
内存效率 良好 更适合简单缓存
使用案例 复杂、有状态 简单缓存

何时使用 Redis: 需要复杂数据结构、需要持久化、需要事务。 何时使用 Memcached: 简单的键值缓存,分布到多个节点上。

Q2: Redis 持久化是如何工作的?

A: Redis 提供两种持久化机制:

RDB(Redis 数据库):

# 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(只追加文件):

# 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 优点: 紧凑,恢复快速 RDB 缺点: 可能丢失最近数据

AOF 优点: 更安全,数据丢失保护更好 AOF 缺点: 文件更大,速度较慢

Q3:Redis 的驱逐策略是什么?

A: 当 Redis 达到最大内存时,它根据驱逐策略来删除键:

# Configuration
maxmemory 256mb
maxmemory-policy <policy>

可用策略:

  • noeviction:达到最大内存时返回错误(默认)
  • allkeys-lru: 驱逐最久未使用过的键
  • allkeys-lfu: 驱逐最少使用的键
  • volatile-lru: 驱逐有过期时间的最久未使用过的键
  • volatile-lfu: 驱逐有过期时间最少使用的键
  • volatile-ttl: 优先删除 TTL 最短的键
  • volatile-random: 随机删除有过期时间的键
  • allkeys-random: 随机删除键

示例:

CONFIG SET maxmemory-policy allkeys-lru

Q4: 如何使用 Redis 实现缓存?

A: 简单的缓存模式:

# 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: 什么是 Redis 键过期?

A: Redis 的键可以在指定时间后自动过期:

# 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:如何使用 Redis 实现会话存储?

A: 简单的会话存储模式:

# Store session
HSET session:user123 username "john" email "john@example.com" 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":"john@example.com"}' EX 86400

Q7:什么是 Redis 复制?

A: 主从复制以实现高可用性:

从机配置:

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

# Verify replication
INFO replication

手动复制:

# Connect to slave Redis CLI
SLAVEOF master_host master_port

# Or
REPLICAOF master_host master_port

# Stop replication
SLAVEOF NO ONE

Q8: 什么是 Redis Cluster?

A: 通过分区实现水平扩展:

# 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: 如何使用 Redis 实现速率限制器?

A: 简单的滑动窗口速率限制器:

# 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: SAVE 和 BGSAVE 有什么区别?

A:

  • SAVE:在保存到磁盘时阻止所有客户端(同步)
  • BGSAVE:在后台保存,客户端可以继续(异步)
# Use BGSAVE in production to avoid blocking
BGSAVE

# Check save status
LASTSAVE

Q11: 我该如何监控 Redis 性能?

A: 使用监控工具和命令:

# 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: Redis 中的 Lua 脚本是什么?

A: 在 Redis 服务器上原子地执行脚本:

# 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: 如何处理 Redis 的高可用性?

A: 使用 Redis Sentinel 实现自动故障转移:

# 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:如何进行备份和恢复?

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:Redis 常见的安全问题有哪些?

A: 安全注意事项:

# 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 配置

Redis 配置文件和参数

主配置文件:/etc/redis/redis.conf

1. 网络配置

# 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. 通用配置

# 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. 快照(RDB)配置

# 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(仅追加文件)配置

# 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. 内存管理

# 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 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. 安全配置

# 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. 客户端配置

# Max number of connected clients
maxclients 10000

# Client tracking
tracking-info-threshold 100

9. 发布/订阅配置

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

10. 集群配置

# 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 threshold (microseconds)
slowlog-log-slower-than 10000

# Slow log max length
slowlog-max-len 128

12. 事件通知配置

# Enable keyspace notifications
notify-keyspace-events ""

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

13. 高级配置

# 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 脚本配置

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

# Enable Lua debugging
ldb-sync-mode no

示例完整配置

# 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

解决 Redis 问题

Redis 全面故障排除指南

第一步:验证 Redis 是否正在运行

# 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

故障排除:

# 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

第二步:检查连接问题

# 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

常见问题:

# 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"

步骤 3:内存问题

# 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

解决高内存问题:

# 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

步骤 4:性能问题

# 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)

优化技巧:

# 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

第5步:持久化问题

# 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

故障排除:持久化

# 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

第六步:复制问题

# 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

复制故障排除:

# 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

第七步:集群问题

# 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

第八步:发布/订阅问题

# 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"

常见的 Redis 错误及解决方案

# 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

性能监控脚本

#!/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 "%"}'

最佳实践

Redis 最佳实践

1. 数据结构选择

# Use hash for objects, not individual strings
# ❌ Bad
SET user:123:name "John"
SET user:123:email "john@example.com"
SET user:123:age 30

# ✅ Good
HSET user:123 name "John" email "john@example.com" age 30

2. 键命名规范

# 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. 过期策略

# 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. 连接池

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

5. 错误处理

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

6. 批量操作

# 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. 内存优化

# 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. 监控和日志记录

# 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. 安全

# 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. 备份策略

# 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

结论

Redis 是一个强大、多功能的内存数据存储,在各种用例中表现出色,从缓存到实时分析。关键要点:

  1. 为您的用例选择合适的数据结构
  2. 为缓存项实施适当的过期策略
  3. 持续监控性能
  4. 根据您的需求制定持久化计划
  5. 使用复制或集群进行适当扩展
  6. 通过密码和网络限制进行妥善安全设置
  7. 定期备份并测试恢复程序

更多信息: