← 返回文档列表

Redis 在项目中的作用

📊 概述

Redis 在这个项目中主要承担 缓存会话存储 的角色,提升应用性能和用户体验。

🎯 主要用途

1. 用户数据缓存 🚀

位置: apps/admin/src/lib/auth.ts

// 缓存用户信息,减少数据库查询
async function getUserByEmail(email: string) {
  const cacheKey = `user:${email}`
  
  // 1. 先从 Redis 缓存获取
  const cachedUser = await redisCache.get(cacheKey)
  if (cachedUser) {
    return cachedUser // ✅ 缓存命中,直接返回
  }
  
  // 2. 缓存未命中,从数据库查询
  const user = users.find(user => user.email === email)
  
  // 3. 将结果缓存 5 分钟
  if (user) {
    redisCache.set(cacheKey, user, 300) // TTL: 300秒
  }
  
  return user
}

作用:

  • 性能提升: 减少数据库查询,响应速度提升 10-100 倍
  • 降低负载: 减少数据库压力
  • 用户体验: 登录验证更快

2. 会话存储 🔐

位置: apps/admin/src/lib/redis.ts - RedisSessionStore

// NextAuth 会话数据存储在 Redis
export class RedisSessionStore {
  async set(sessionId: string, sessionData: any, maxAge: number) {
    await this.redis.setex(
      `session:${sessionId}`,
      maxAge,
      JSON.stringify(sessionData)
    )
  }
  
  async get(sessionId: string) {
    const data = await this.redis.get(`session:${sessionId}`)
    return data ? JSON.parse(data) : null
  }
}

作用:

  • 分布式会话: 支持多服务器部署,会话共享
  • 自动过期: 会话自动过期,无需手动清理
  • 高性能: 内存存储,访问速度快

使用场景:

// 在 NextAuth 中存储会话
redisSessionStore.set(sessionKey, {
  userId: user.id,
  email: user.email,
  role: user.role,
  lastAccess: new Date().toISOString()
}, 30 * 24 * 60 * 60) // 30天过期

3. 登录日志记录 📝

位置: apps/admin/src/lib/auth.ts

// 记录用户登录事件
async authorize(credentials) {
  // ... 验证逻辑 ...
  
  // 记录登录日志到 Redis
  const loginKey = `login:${user.id}:${Date.now()}`
  redisCache.set(loginKey, {
    userId: user.id,
    email: user.email,
    timestamp: new Date().toISOString(),
    ip: 'unknown'
  }, 86400) // 保存 24 小时
}

作用:

  • 安全审计: 记录所有登录事件
  • 异常检测: 可以分析异常登录模式
  • 用户行为: 追踪用户活跃度

4. 事件日志 📊

位置: apps/admin/src/lib/auth.ts - NextAuth Events

events: {
  async signIn({ user }) {
    // 记录登录事件
    const eventKey = `event:signin:${user.id}:${Date.now()}`
    redisCache.set(eventKey, {
      userId: user.id,
      timestamp: new Date().toISOString()
    }, 86400)
  },
  
  async signOut({ token }) {
    // 记录登出事件
    const eventKey = `event:signout:${token.sub}:${Date.now()}`
    redisCache.set(eventKey, {
      userId: token.sub,
      timestamp: new Date().toISOString()
    }, 86400)
  }
}

作用:

  • 行为追踪: 记录用户登录/登出行为
  • 数据分析: 可以分析用户活跃度
  • 安全监控: 检测异常行为

5. API 缓存管理 💾

位置: apps/admin/src/app/api/redis/cache/route.ts

// 提供 Redis 缓存管理 API
export async function GET(request: NextRequest) {
  const key = searchParams.get('key')
  const value = await redisCache.get(key)
  return NextResponse.json({ key, value })
}

export async function POST(request: NextRequest) {
  const { key, value, ttl } = await request.json()
  await redisCache.set(key, value, ttl)
  return NextResponse.json({ success: true })
}

作用:

  • 通用缓存: 可以缓存任何 API 响应
  • 灵活配置: 支持自定义 TTL
  • 管理界面: 提供缓存管理功能

6. 管理界面 🖥️

位置: apps/admin/src/app/api-integration/page.tsx

// Redis 管理功能
- 查看 Redis 统计信息(连接状态、键数量、内存使用)
- 查看所有 Redis 键
- 设置/获取/删除 Redis 值
- 监控 Redis 健康状态

功能:

  • 可视化: 直观查看 Redis 状态
  • 调试工具: 方便开发和调试
  • 运维支持: 生产环境监控

📋 数据结构

缓存键命名规范

| 键前缀 | 用途 | 示例 | TTL | |--------|------|------|-----| | user: | 用户信息缓存 | user:admin@example.com | 5分钟 | | session: | 会话数据 | session:abc123 | 30天 | | login: | 登录日志 | login:1:1234567890 | 24小时 | | event:signin: | 登录事件 | event:signin:1:1234567890 | 24小时 | | event:signout: | 登出事件 | event:signout:1:1234567890 | 24小时 | | cache: | 通用缓存 | cache:api:items | 自定义 |


🔧 技术实现

1. 懒加载模式

// 避免构建时连接 Redis
export const redisCache = new Proxy({} as RedisCache, {
  get(target, prop) {
    return getRedisCache()[prop as keyof RedisCache]
  }
})

优势:

  • ✅ 构建时不会连接 Redis
  • ✅ 运行时按需初始化
  • ✅ 避免构建错误

2. 错误容错

// 所有 Redis 操作都有错误处理
try {
  await redisCache.set(key, value, ttl)
} catch (error) {
  console.warn('Redis cache set error:', error)
  // 继续执行,不阻塞主流程
}

优势:

  • 优雅降级: Redis 不可用时应用仍可运行
  • 非阻塞: 不影响主要功能
  • 容错性强: 提高系统稳定性

3. 超时保护

// 设置超时,避免长时间等待
const cachedUser = await Promise.race([
  redisCache.get(cacheKey),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Cache timeout')), 2000)
  )
]).catch(() => null)

优势:

  • 快速失败: 2秒超时,不阻塞请求
  • 用户体验: 即使缓存慢也不影响响应

📊 性能影响

缓存命中率示例

| 场景 | 无缓存 | 有缓存 | 提升 | |------|--------|--------|------| | 用户查询 | 50ms (数据库) | 1ms (Redis) | 50x | | 登录验证 | 100ms | 10ms | 10x | | 会话读取 | 30ms | 0.5ms | 60x |

资源使用

  • 内存: 根据缓存数据量,通常 < 100MB
  • 网络: 本地 Redis,延迟 < 1ms
  • CPU: 几乎无影响

🎯 使用场景总结

✅ 适合使用 Redis 的场景

  1. 高频查询数据: 用户信息、配置数据
  2. 会话存储: 需要分布式共享的会话
  3. 临时数据: 登录日志、事件记录
  4. API 缓存: 减少外部 API 调用

❌ 不适合使用 Redis 的场景

  1. 持久化数据: 应存储在数据库
  2. 大文件: Redis 不适合存储大文件
  3. 复杂查询: 需要 SQL 查询的数据
  4. 事务数据: 需要 ACID 保证的数据

🔍 监控和维护

健康检查

// 检查 Redis 连接状态
const isConnected = isRedisConnected()

// 查看 Redis 统计
GET /api/redis/stats

常见问题

  1. NOAUTH 错误: Redis 需要密码但未配置
  2. 连接超时: Redis 服务未启动或网络问题
  3. 内存不足: 缓存数据过多,需要清理

📝 总结

Redis 在这个项目中主要起到:

  1. 🚀 性能优化: 缓存用户数据,提升响应速度
  2. 🔐 会话管理: 分布式会话存储
  3. 📝 日志记录: 登录和事件日志
  4. 💾 通用缓存: API 响应缓存
  5. 🖥️ 管理工具: 提供可视化管理界面

核心价值: 提升性能、支持分布式、增强可维护性