配置 SSOT(TOML + .env) 统一错误契约 Auth 与事务边界 Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client 可观测性(OpenTelemetry + LGTM)
2.0 KiB
2.0 KiB
title, impact, impactDescription, tags, description, alwaysApply
| title | impact | impactDescription | tags | description | alwaysApply |
|---|---|---|---|---|---|
| Avoid Slow Commands in Production | HIGH | Prevents Redis from becoming unresponsive | slow-commands, keys, scan, performance | Avoid Slow Commands in Production | true |
Avoid Slow Commands in Production
Some Redis commands are slow because they scan large datasets. Use incremental alternatives to avoid blocking the server.
| Avoid | Use Instead |
|---|---|
KEYS * |
SCAN with cursor |
SMEMBERS on large sets |
SSCAN |
HGETALL on large hashes |
HSCAN |
LRANGE 0 -1 on large lists |
Paginate with LRANGE 0 100 |
Correct: Use SCAN for iteration.
Python (redis-py):
# Good: Non-blocking iteration
cursor = 0
while True:
cursor, keys = redis.scan(cursor, match="user:*", count=100)
for key in keys:
process(key)
if cursor == 0:
break
Java (Jedis):
import redis.clients.jedis.ScanIteration;
import redis.clients.jedis.UnifiedJedis;
import java.util.List;
try (UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379")) {
// ScanIteration manages the cursor automatically
ScanIteration scan = jedis.scanIteration(10, "user:*", "hash");
while (!scan.isIterationCompleted()) {
List<String> result = scan.nextBatch().getResult();
for (String key : result) {
process(key);
}
}
}
Incorrect: Using KEYS in production.
Python (redis-py):
# Bad: Scans all keys, slow on large datasets
keys = redis.keys("user:*")
Java (Jedis):
// Bad: Scans all keys, blocks the server
Set<String> result = jedis.keys("*");
Note: Truly blocking commands (like BLPOP, BRPOP, BLMOVE) that wait indefinitely for data are appropriate for some use cases like job queues, but should be used with timeouts.
# Blocking pop with timeout - appropriate for queue consumers
result = redis.blpop("task_queue", timeout=5)
Reference: Redis SCAN