# 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
# 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)
# 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 iflimit 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-timecommand monitoring MONITOR # Get stats INFO stats # Check Redis memory usage INFO memory | grep used_memory_human
# Set password requirepass "your_secure_password" # Or setincommand 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
# 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 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
# Use hashfor 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)
# 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