vault backup: 2026-06-12 15:36:35

This commit is contained in:
hhs
2026-06-12 15:36:35 +08:00
parent acd581bd12
commit 54a57d3b60
3 changed files with 356 additions and 0 deletions

View File

@@ -79,6 +79,7 @@ graph TB
| 语言 | **Go** | 高并发 goroutine 模型,适合长连接管理 |
| WebSocket | **gorilla/websocket** | Go 生态最成熟的 WebSocket 库 |
| 会话存储 | **Redis** | 高速 KV 存储,适合会话状态和上下文缓存 |
| 持久化存储 | **PostgreSQL** | 对话历史、用量统计、用户偏好MVP 阶段可选) |
| 配置管理 | **Viper** | 支持多格式配置,环境变量覆盖 |
| 日志 | **Zap** | 高性能结构化日志 |
@@ -279,6 +280,109 @@ graph LR
> [!tip] WebSocket 与负载均衡
> WebSocket 是长连接Nginx 需要配置 `proxy_set_header Upgrade` 和 `ip_hash` 或 sticky session确保同一用户的请求始终路由到同一个 Gateway 实例。
### 存储与持久化策略
当前架构使用 Redis 做会话存储,但 Redis 是**内存数据库**,默认不做持久化——服务重启数据即丢。是否需要持久化,取决于业务阶段:
#### 分阶段策略
```mermaid
graph LR
A["MVP 阶段"] -->|"Redis 内存存储"| B["快速验证"]
C["上线阶段"] -->|"Redis + PostgreSQL"| D["持久化对话与用量"]
E["规模化阶段"] -->|"Redis + PG + 对象存储"| F["完整数据体系"]
```
| 阶段 | 存储方案 | 持久化内容 | 理由 |
|------|---------|-----------|------|
| **MVP** | Redis only | 无 | 快速验证核心功能,重启丢数据可接受 |
| **上线** | Redis + **PostgreSQL** | 对话历史、用户偏好、用量统计 | 用户需要查看历史,运营需要成本数据 |
| **规模化** | Redis + PG + **对象存储** | 图像帧、音频片段归档 | 大文件不适合存关系库 |
#### 需要持久化的数据
| 数据类型 | 写入频率 | 查询模式 | 推荐存储 |
|---------|---------|---------|---------|
| 对话历史(文本) | 每轮对话 | 按用户+时间范围查询 | PostgreSQL |
| 用量统计tokens/成本) | 每次 API 调用 | 聚合统计(日/周/月) | PostgreSQL |
| 用户偏好(语言/声音) | 低频 | 按 user_id 查询 | PostgreSQL |
| 实时会话状态 | 高频读写 | 按 session_id 查询 | Redis不变 |
| 关键帧图像 | 按需 | 按对话 ID 关联 | 对象存储S3/MinIO |
#### PostgreSQL 表设计要点
```sql
-- 对话会话表
CREATE TABLE sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 对话消息表
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
session_id UUID REFERENCES sessions(id),
role VARCHAR(16) NOT NULL, -- "user" | "assistant"
content TEXT NOT NULL,
image_url TEXT, -- 关联的关键帧(可选)
tokens_used INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now()
);
-- 用量统计表(按天聚合,方便成本分析)
CREATE TABLE usage_daily (
user_id UUID NOT NULL,
date DATE NOT NULL,
llm_tokens BIGINT DEFAULT 0,
stt_seconds REAL DEFAULT 0,
tts_chars INTEGER DEFAULT 0,
estimated_cost NUMERIC(10,4) DEFAULT 0,
PRIMARY KEY (user_id, date)
);
```
> [!info] 为什么选 PostgreSQL 而不是 MySQL
> PostgreSQL 对 JSON 类型支持更好(对话上下文可直接存 JSONB且有 `gen_random_uuid()` 等原生函数,更适合这类 AI 应用场景。当然,如果团队更熟悉 MySQL替换成本也很低。
#### 更新后的存储层架构
```mermaid
graph TD
subgraph App["Go Gateway"]
SM["Session Manager"]
HM["History Manager"]
UM["Usage Monitor"]
end
subgraph Cache["热数据 - Redis"]
SESSION["会话状态"]
CTX["对话上下文窗口"]
end
subgraph DB["冷数据 - PostgreSQL"]
HISTORY["对话历史"]
USAGE["用量统计"]
PREFS["用户偏好"]
end
subgraph OSS["大文件 - 对象存储"]
IMG["关键帧图像"]
AUDIO["音频片段"]
end
SM --> SESSION
SM --> CTX
HM --> HISTORY
HM --> IMG
UM --> USAGE
SM --> PREFS
```
> [!question] 思考
> Redis 存"热数据"当前对话上下文PostgreSQL 存"冷数据"(历史记录)——这就是经典的**冷热分离**策略。实时对话走 Redis 微秒级读写,历史查询走 PostgreSQL互不干扰。
## 关联笔记
- [[视觉理解]]
@@ -286,3 +390,4 @@ graph LR
- [[成本控制]]
- [[用户故事]]
- [[项目架构与技术栈/技术名词解释]]
- [[持久化技术选型]]