Files
life-echo/api/.agents/skills/redis-development/rules/conn-blocking.md
Sully 53e0065e3e refactor(api): TOML 配置 SSOT、统一错误契约、Auth/事务加固与可观测性 (#33)
配置 SSOT(TOML + .env)
统一错误契约
Auth 与事务边界
Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client
可观测性(OpenTelemetry + LGTM)
2026-05-22 13:44:50 +08:00

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