Developing with Redis by doanchienthangdev/omgkit
npx skills add https://github.com/doanchienthangdev/omgkit --skill 'Developing with Redis'import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
maxRetriesPerRequest: 3,
});
// Basic caching
await redis.setex('user:123', 3600, JSON.stringify(userData));
const cached = await redis.get('user:123');
| 功能 | 描述 | 指南 |
|---|---|---|
| 缓存 | 带 TTL 的高速键值存储 | 使用 setex 实现自动过期,get 用于检索 |
| 会话存储 | 分布式会话管理 | 使用用户 ID 索引存储会话以支持多设备 |
| 速率限制 | 使用滑动窗口进行请求节流 | 使用有序集合或令牌桶算法 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 发布/订阅 | 服务间的实时消息传递 | 将订阅者连接与发布者分离 |
| 流 | 事件溯源和消息队列 | 使用消费者组实现可靠的消息处理 |
| 数据结构 | 列表、集合、有序集合、哈希 | 根据访问模式选择数据结构 |
async function getOrSet<T>(key: string, factory: () => Promise<T>, ttl = 3600): Promise<T> {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const value = await factory();
await redis.setex(key, ttl, JSON.stringify(value));
return value;
}
async function checkRateLimit(key: string, limit: number, windowSec: number): Promise<boolean> {
const now = Date.now();
const windowStart = now - windowSec * 1000;
const pipeline = redis.pipeline();
pipeline.zremrangebyscore(key, '-inf', windowStart);
pipeline.zadd(key, now, `${now}:${Math.random()}`);
pipeline.zcard(key);
pipeline.expire(key, windowSec);
const results = await pipeline.exec();
const count = results?.[2]?.[1] as number;
return count <= limit;
}
async function acquireLock(key: string, ttlMs = 10000): Promise<string | null> {
const lockId = crypto.randomUUID();
const acquired = await redis.set(`lock:${key}`, lockId, 'PX', ttlMs, 'NX');
return acquired === 'OK' ? lockId : null;
}
async function releaseLock(key: string, lockId: string): Promise<boolean> {
const script = `if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end`;
return (await redis.eval(script, 1, `lock:${key}`, lockId)) === 1;
}
| 应做 | 避免 |
|---|---|
| 为所有缓存键设置 TTL | 存储大于 100KB 的对象 |
| 使用管道进行批量操作 | 在生产环境中使用 KEYS 命令 |
| 实现连接池 | 忽略内存限制和驱逐策略 |
| 使用 Lua 脚本实现原子操作 | 将 Redis 用作主数据库 |
| 为键添加前缀以实现命名空间隔离 | 在长时间运行的操作上阻塞 |
使用 INFO memory 监控内存 | 存储未加密的敏感数据 |
| 设置 Redis Sentinel 以实现高可用性 | 跳过连接错误处理 |
每周安装量
0
代码仓库
GitHub 星标数
3
首次出现
1970年1月1日
安全审计
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379'),
maxRetriesPerRequest: 3,
});
// Basic caching
await redis.setex('user:123', 3600, JSON.stringify(userData));
const cached = await redis.get('user:123');
| Feature | Description | Guide |
|---|---|---|
| Caching | High-speed key-value storage with TTL | Use setex for auto-expiration, get for retrieval |
| Session Storage | Distributed session management | Store sessions with user ID index for multi-device |
| Rate Limiting | Request throttling with sliding windows | Use sorted sets or token bucket algorithms |
| Pub/Sub | Real-time messaging between services | Separate subscriber connections from publishers |
| Streams | Event sourcing and message queues | Consumer groups for reliable message processing |
| Data Structures | Lists, sets, sorted sets, hashes | Choose structure based on access patterns |
async function getOrSet<T>(key: string, factory: () => Promise<T>, ttl = 3600): Promise<T> {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const value = await factory();
await redis.setex(key, ttl, JSON.stringify(value));
return value;
}
async function checkRateLimit(key: string, limit: number, windowSec: number): Promise<boolean> {
const now = Date.now();
const windowStart = now - windowSec * 1000;
const pipeline = redis.pipeline();
pipeline.zremrangebyscore(key, '-inf', windowStart);
pipeline.zadd(key, now, `${now}:${Math.random()}`);
pipeline.zcard(key);
pipeline.expire(key, windowSec);
const results = await pipeline.exec();
const count = results?.[2]?.[1] as number;
return count <= limit;
}
async function acquireLock(key: string, ttlMs = 10000): Promise<string | null> {
const lockId = crypto.randomUUID();
const acquired = await redis.set(`lock:${key}`, lockId, 'PX', ttlMs, 'NX');
return acquired === 'OK' ? lockId : null;
}
async function releaseLock(key: string, lockId: string): Promise<boolean> {
const script = `if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end`;
return (await redis.eval(script, 1, `lock:${key}`, lockId)) === 1;
}
| Do | Avoid |
|---|---|
| Set TTL on all cache keys | Storing objects larger than 100KB |
| Use pipelines for batch operations | Using KEYS command in production |
| Implement connection pooling | Ignoring memory limits and eviction |
| Use Lua scripts for atomic operations | Using Redis as primary database |
| Add key prefixes for namespacing | Blocking on long-running operations |
Monitor memory with INFO memory | Storing sensitive data unencrypted |
| Set up Redis Sentinel for HA | Skipping connection error handling |
Weekly Installs
0
Repository
GitHub Stars
3
First Seen
Jan 1, 1970
Security Audits
GSAP React 动画库使用指南:useGSAP Hook 与最佳实践
2,400 周安装
前端动画设计指南:提升用户体验的微交互与动效策略
38,600 周安装
跨平台设计适配指南:移动端、桌面端、平板、打印及邮件适配策略与实施方法
38,800 周安装
前端打磨(Polish)终极指南:提升产品细节与用户体验的系统化检查清单
39,900 周安装
Web应用测试指南:使用Python Playwright自动化测试本地Web应用
39,500 周安装
Azure Cloud Migrate:AWS Lambda到Azure Functions迁移工具 - 微软官方评估与代码迁移
38,700 周安装
Excel财务建模规范与xlsx文件处理指南:专业格式、零错误公式与数据分析
42,900 周安装