System Design FAQ
REST API设计
REST(Representational State Transfer) 是一种软件架构风格,不是协议。REST API 是基于 HTTP 协议的一种接口设计方式,它强调资源的表示和状态转移。
- 资源(Resource):系统中的实体,如
users
、orders
、products
。 - URI(统一资源标识符):资源的唯一地址,例如
/users/123
表示 ID 为 123 的用户。 - HTTP 方法:用于操作资源的动作(见下表)。
操作类型 | HTTP 方法 | 示例 URI | 意义 |
---|---|---|---|
查询资源 | GET | /users/1 | 获取 ID=1 的用户 |
创建资源 | POST | /users | 创建一个新用户 |
更新资源 | PUT 或 PATCH | /users/1 | 更新 ID=1 的用户 |
删除资源 | DELETE | /users/1 | 删除 ID=1 的用户 |
著名产品
- GitHub API https://docs.github.com/en/rest
- Twitter API V2 https://developer.twitter.com/en/docs/twitter-api
RAG有什么组件
- 知识库:相关文本、语音等数据,为用户查询提供上下文支持。
- Embedding模型:将用户输入及知识库内容转换为向量,以便进行相似度匹配。
- 向量数据库:存储知识库内容的向量表示,并根据查询计算相似度,检索相关内容。
- LLM:结合用户输入和检索到的内容,生成最终的回答。
网络连接
网络协议
HTTP,SSE(server-side-event)和websocket有何区别
-
HTTP 应用层基础协议
-
客户端主动发起请求,服务端响应;不具备推送能力(除非借助其他机制)
-
应用:网页加载、API 调用
-
-
SSE(server-side-event)服务端推送
- pros: 基于HTTP,比WebSocket部署简单
- cons:
- 只能服务端推客户端,不能双向通信
- 仅支持文本、部分浏览器不支持、无法用于双向通信
- 应用:服务器状态监控、日志流推送
-
websocket 全双工通信;基于HTTP建立后升级为持久的全双工连接(ws:// 或 wss://)
- pros: 双向通信、低延迟、实时性强
- cons: 需特殊服务支持,对服务器并发连接压力大
- 应用:在线游戏、股票行情、IM聊天系统
轮询通信“范式”
polling、long-polling
- polling,客户端每次都要发起一个http请求
- pros: 实现简单,兼容性强
- cons: 频繁请求浪费资源,延迟高
- 应用:每5秒请求一次“是否有新消息?”
- long-polling,请求后服务端“挂起”,有更新才返回响应,可以借助http keepactive实现长连接
- pros: 减少请求频率,相比普通轮询更实时
- cons:实现稍复杂,占用连接资源
- 应用:聊天应用、通知系统(早期Facebook)
构建 ChatGPT 类对话系统:WebSocket
目标 | 推荐方案 | 说明 |
---|---|---|
构建 ChatGPT 风格的对话系统 | WebSocket + GPT API | 支持双向通信和 token 流式输出 |
构建只读通知流 / 输出流 | SSE + text/event-stream | 更轻量,部署简单 |
无需实时通信的传统交互系统 | 普通 HTTP / Polling | 开发简单 |
NoSQL与RDB
类型 | 名称 | 代表产品 | 数据结构 | 典型特点 | 应用场景 |
---|---|---|---|---|---|
RDB | Relational DB(关系型数据库) | MySQL, PostgreSQL, Oracle | 表格、行列 | 强事务(ACID)、结构固定、SQL查询 | 金融、电商、传统管理系统 |
NoSQL | Not Only SQL(非关系型数据库) | MongoDB, Cassandra, HBase | 文档、键值、图、列族等 | 弱事务、灵活结构、易扩展 | 社交、IoT、大数据场景 |
Redis | Remote Dictionary Server | Redis(Key-Value 型 NoSQL 数据库) | 键值(Key-Value),支持多种结构 | 高速内存存取、支持持久化 | 缓存、排行榜、消息队列、在线状态 |
Redis 本质上是一个高性能的 Key-Value 型 NoSQL 数据库,常被归类为 内存型 NoSQL 数据库。
索引对比
特性 | MySQL(RDB) | MongoDB(NoSQL) | Redis(KV NoSQL) |
---|---|---|---|
数据结构 | 表格(行列) | 文档(JSON/BSON) | Key-Value(多结构) |
索引机制 | B+ Tree / FULLTEXT / SPATIAL | 单字段、多键、文本、TTL、地理 | 无传统索引,靠 Key 快速定位 |
支持复杂查询 | ✅ JOIN、子查询、多表 | ❌ 不支持 JOIN,仅支持聚合管道 | ❌ 不支持 |
性能 | 高并发读写中等,适合事务型应用 | 写入快,扩展性强,灵活性好 | 内存级极快,适合缓存和排行榜等 |
索引维护成本 | 高(必须设计良好) | 中等(按需建索引) | 低(手动结构组织) |
LLM Service Latency估计
假设我们的AI服务用户在cn,服务在sg,chatgpt的服务在us
- cn用户到sg服务的延时:约100ms
- sg服务到chatgpt服务的延时:200ms
- chatgpt llm的ttft延时:300ms
总延时:600ms
假设我们的AI服务用户在cn,服务在hk,chatgpt的服务在hk
- cn用户到hk服务的延时:约50ms
- hk服务到hk chatgpt服务的延时:10ms
- chatgpt llm的ttft延时:300ms
总延时:350ms
异步IO
阻塞、同步异步定义
定义 | 意思 | 示例 |
---|---|---|
阻塞 I/O | 等待结果时,程序卡住 | requests.get() |
非阻塞 I/O | 等待期间不阻塞线程,可做别的事 | await session.get() |
同步 | 按顺序执行 | 一条一条地跑 |
异步 | 多任务同时进行,协程调度 | async def , await |
现实世界的 IO 阻塞场景总结
场景 | 是否 IO 阻塞 | 举例 |
---|---|---|
网络请求 | 是 | requests.get(url) |
文件读取 | 是 | open('file.txt').read() |
数据库查询 | 是 | cursor.execute("SELECT ...") |
用户输入 | 是 | input() |
await + asyncio | 否 | await session.get(url) |