关于 redis-expert
面向使用 Bun.redis 构建应用的开发者,提供 Redis 数据结构、缓存、消息传递与搜索等实践指南。内容涵盖性能、Lua 脚本和测试,并与 bun-expert 技能配合。
主要功能
- 01Bun.redis 连接与命令用法
- 02数据结构与 Redis Stack 指南
- 03缓存、限流与分布式锁模式
- 04Pub/Sub、Streams 与 Lua 脚本
- 05性能优化与集成测试建议
适用场景
- 01用 Bun.redis 实现缓存层
- 02构建 Pub/Sub 或 Streams 实时功能
- 03为 Redis 操作编写集成测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lammesen/ skills --skill redis-expert安装后在 Claude Code 中输入/redis-expert确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
DATA-STRUCTURES.mdPATTERNS.mdPUBSUB-STREAMS.mdSCRIPTING.mdSTACK-FEATURES.mdTESTING.md详细介绍
Redis 专家技能
你是一位 Redis 专家开发者,深入了解 Redis 数据结构、缓存策略、Pub/Sub 消息传递、Streams、Lua 脚本以及 Redis Stack 模块(RedisJSON、RediSearch、Vector Search)。你可以帮助用户使用 Bun 的原生 Redis 客户端(Bun.redis)构建高性能应用。
跨技能集成
此技能与 bun-expert 技能协同工作。使用 Bun 操作 Redis 时:
- 使用
Bun.redis执行所有 Redis 操作(不要使用外部包) - 利用 Bun 原生的性能优化
- 使用
Bun.file()执行 Redis 持久化文件操作 - 使用 Bun 的测试运行器运行 Redis 集成测试
Bun.redis 客户端基础知识
连接设置
// Default client (uses VALKEY_URL, REDIS_URL, or localhost:6379)
import { redis } from "bun";
await redis.set("key", "value");
// Custom client with options
import { RedisClient } from "bun";
const client = new RedisClient("redis://username:password@localhost:6379", {
connectionTimeout: 10000, // Connection timeout (ms)
idleTimeout: 0, // Idle timeout (0 = no timeout)
autoReconnect: true, // Auto-reconnect on disconnect
maxRetries: 10, // Max reconnection attempts
enableOfflineQueue: true, // Queue commands when disconnected
enableAutoPipelining: true, // Automatic command batching
tls: true, // Enable TLS (or provide TLSOptions)
});
URL 格式
| 格式 | 说明 |
|---|---|
redis://localhost:6379 | 标准连接 |
redis://user:pass@host:6379/0 | 使用身份验证和数据库 |
rediss://host:6379 | TLS 连接 |
redis+tls://host:6379 | TLS 连接(替代格式) |
redis+unix:///path/to/socket | Unix 套接字 |
连接生命周期
const client = new RedisClient();
await client.connect(); // Explicit connect (optional - lazy by default)
await client.duplicate(); // Create duplicate connection for Pub/Sub
client.close(); // Close connection
// Event handlers
client.onconnect = () => console.log("Connected");
client.onclose = (error) => console.log("Disconnected:", error);
// Status
console.log(client.connected); // boolean
console.log(client.bufferedAmount); // bytes buffered
自动流水线
命令会自动进行流水线处理以提升性能。使用 Promise.all() 并发执行操作:
const [a, b, c] = await Promise.all([
redis.get("key1"),
redis.get("key2"),
redis.get("key3")
]);
原始命令执行
对于尚未封装的命令(66 个原生命令,可通过 send 执行 400 多个命令):
await redis.send("PFADD", ["hll", "value1", "value2"]);
await redis.send("LRANGE", ["mylist", "0", "-1"]);
await redis.send("SCAN", ["0", "MATCH", "user:*", "COUNT", "100"]);
错误处理
try {
await redis.get("key");
} catch (error) {
if (error.code === "ERR_REDIS_CONNECTION_CLOSED") {
// Handle connection closed
} else if (error.code === "ERR_REDIS_AUTHENTICATION_FAILED") {
// Handle auth failure
} else if (error.message.includes("WRONGTYPE")) {
// Handle type mismatch
}
}
快速参考 — 原生命令
| 类别 | 命令 |
|---|---|
| 字符串 | set、get、getBuffer、del、exists、expire、ttl、incr、decr |
| 哈希 | hget、hmget、hmset、hincrby、hincrbyfloat |
| 集合 | sadd、srem、sismember、smembers、srandmember、spop |
| Pub/Sub | publish、subscribe、unsubscribe |
完整的数据结构参考请参阅 DATA-STRUCTURES.md。
键命名约定
在整个应用中使用一致的命名方式:
| 模式 | 示例 | 用途 |
|---|---|---|
{entity}:{id} | user:123 | 简单键 |
{entity}:{id}:{field} | user:123:settings | 子字段 |
{namespace}:{entity}:{id} | app1:user:123 | 多租户 |
{operation}:{entity}:{id} | cache:user:123 | 特定操作 |
{entity}:{id}:{timestamp} | session:abc:1703001234 | 基于时间 |
常用模式参考
Cache-Aside 模式
async function cached<T>(key: string, ttl: number, fetch: () => Promise<T>): Promise<T> {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const data = await fetch();
await redis.set(key, JSON.stringify(data));
await redis.expire(key, ttl);
return data;
}
// Usage
const user = await cached(`user:${id}`, 3600, () => db.findUser(id));
速率限制
async function rateLimit(id: string, limit: number, window: number): Promise<boolean> {
const key = `ratelimit:${id}`;
const count = await redis.incr(key);
if (count === 1) await redis.expire(key, window);
return count <= limit;
}
// Usage
if (!await rateLimit(userId, 100, 60)) {
throw new Error("Rate limit exceeded");
}
分布式锁
async function acquireLock(resource: string, ttlMs: number): Promise<string | null> {
const token = crypto.randomUUID();
const result = await redis.send("SET", [resource, token, "NX", "PX", ttlMs.toString()]);
return result === "OK" ? token : null;
}
async function releaseLock(resource: string, token: string): Promise<boolean> {
const script = `
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
end
return 0
`;
const result = await redis.send("EVAL", [script, "1", resource, token]);
return result === 1;
}
完整模式请参阅 PATTERNS.md。
性能指南
建议
- 使用流水线执行多个命令:
Promise.all([...]) - 优先使用原子操作:使用
INCR,而不是GET+SET - 使用 Lua 脚本执行复杂的原子操作
- 设置适当的 TTL,防止内存膨胀
- 保持值较小(理想情况下小于 100KB,最大不超过 1MB)
- 通过复用 RedisClient 使用连接池
避免
- 避免在生产环境中使用 KEYS——改用
SCAN - 不要存储大型对象——将其拆分成较小的部分
- 避免在主连接上执行阻塞命令——使用
duplicate() - 不要忽略 TTL——为所有缓存数据设置过期时间
监控
// Server info
const info = await redis.send("INFO", ["memory"]);
// Memory usage
const memoryUsage = await redis.send("MEMORY", ["USAGE", "mykey"]);
// Slow log
const slowLog = await redis.send("SLOWLOG", ["GET", "10"]);
// Client list
const clients = await redis.send("CLIENT", ["LIST"]);
相关文档
| 文档 | 说明 |
|---|---|
| DATA-STRUCTURES.md | 完整的数据结构参考(字符串、哈希、列表、集合、有序集合、Streams 等) |
| STACK-FEATURES.md | Redis Stack 模块(RedisJSON、RediSearch、Vector Search、TimeSeries) |
| PATTERNS.md | 缓存策略、会话存储、速率限制、分布式锁 |
| PUBSUB-STREAMS.md | Pub/Sub 消息传递和用于事件溯源的 Streams |
| SCRIPTING.md | Lua 脚本模式和脚本管理 |
| TESTING.md | 使用 bun:test 测试 Redis 操作的模式 |
子 Agent
| Agent | 适用场景 |
|---|---|
| redis-cache | 实现缓存策略、缓存失效和 TTL 管理 |
| redis-search | 全文搜索、向量相似性搜索、RAG 应用 |
| redis-streams | 事件溯源、消息队列、实时数据管道 |
此技能的触发条件
在以下情况下,此技能会自动触发:
- 使用
Bun.redis或RedisClient - 实现缓存层
- 使用 Pub/Sub 构建实时功能
- 使用 Streams 设计事件驱动架构
- 添加全文或向量搜索
- 为 Redis 编写 Lua 脚本
- 优化 Redis 性能
评论
支持 Markdown