# Redis

Monetarie PIX 中 Redis 7 的配置，用于速率限制、Token 黑名单、幂等性和会话缓存。

## 前提条件

- Redis 7.x 已安装并可访问
- 后端 pods 到 Redis 的网络连接
- 了解 Redis 数据结构的基本知识

## 使用场景

| 功能 | 键模式 | TTL | 数据类型 |
|------|--------|-----|----------|
| 速率限制 | `rate_limit:{ip}:{path}` | 15 分钟 | String (计数器) |
| Token 黑名单 | `blacklist:{jti}` | JWT 剩余 TTL | String |
| 幂等性 | `idempotency:{user_id}:{key}` | 24 小时 | String (JSON) |
| 会话缓存 | `session:{token}` | 可配置 | Hash |
| RBAC 缓存 | ETS (非 Redis) | 5 分钟 | -- |

## 配置

### 环境变量

```bash
REDIS_HOST=10.140.240.4
REDIS_PORT=6379
```

### 连接池

`Shared.Redis.Connection` GenServer 管理一个 10 连接的连接池：

```elixir
# Shared.Application 监督树
{Shared.Redis.Connection, [
  host: System.get_env("REDIS_HOST", "localhost"),
  port: String.to_integer(System.get_env("REDIS_PORT", "6379"))
]}
```

Redis 操作有 5 秒超时，以防止网络问题时阻塞。

## 速率限制

登录速率限制使用 Redis 令牌桶算法：

- **限制**：每个 IP 每 15 分钟 10 次尝试
- **路径**：`/api/v1/auth/login`、`/api/v1/auth/mfa/verify`
- **响应**：HTTP 429 带 `Retry-After` 头

```
SET rate_limit:192.168.1.1:/api/v1/auth/login 1 EX 900 NX
INCR rate_limit:192.168.1.1:/api/v1/auth/login
```

## Token 黑名单

当用户注销时，其 JWT 被列入黑名单直到自然过期：

```
SET blacklist:{jti} 1 EX {remaining_ttl}
```

`JWTAuth` 插件在每个认证请求上检查黑名单：

```
EXISTS blacklist:{jti}
```

## 幂等性

`Shared.Plugs.Idempotency` 插件防止重复支付处理：

```
SET idempotency:{user_id}:{idempotency_key} {response_json} EX 86400 NX
```

- 键：请求体 + 用户 ID + 幂等性头的 SHA-256
- 原子 `SET NX` 防止 TOCTOU 竞态条件
- 最大请求体大小：64 KB
- TTL：24 小时

## Redis 服务器配置（生产环境）

```conf
# redis.conf
maxmemory 4gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
appendonly yes
appendfsync everysec
```

### Sentinel 配置（高可用）

```conf
# sentinel.conf
sentinel monitor monetarie-pix 10.0.1.10 6379 2
sentinel down-after-milliseconds monetarie-pix 5000
sentinel failover-timeout monetarie-pix 60000
```

## 监控

需要监控的关键 Redis 指标：

| 指标 | 阈值 | 操作 |
|------|------|------|
| `used_memory` | > 80% maxmemory | 扩容或增加 maxmemory |
| `connected_clients` | > 500 | 检查连接泄漏 |
| `keyspace_misses` | 高比率 | 检查缓存策略 |
| `blocked_clients` | > 0 持续 | 调查阻塞操作 |

```bash
# 检查 Redis 状态
redis-cli INFO stats
redis-cli INFO memory
redis-cli DBSIZE
```

## 预期结果

配置 Redis 后：

- 每个后端 pod 建立 10 连接的连接池
- 登录端点上的速率限制已激活
- 注销时 Token 黑名单正常工作
- 幂等性防止重复支付
- 所有 Redis 操作在 5 秒超时内完成
