完整架构

架构演进回顾

让我们回顾一下整个系统的架构演进历程。

阶段 1:最简单的数据库方案
- 两张表:articles、article_likes
- 简单的增删改查
- 适合:< 1000 用户

阶段 2:Redis 缓存优化
- Redis 计数器
- 数据持久化
- 缓存一致性
- 适合:< 10,000 用户

阶段 3:高并发优化
- 分片计数
- 本地缓存
- 合并写入
- 适合:< 100,000 用户

阶段 4:分布式系统
- 分布式锁
- Lua 脚本
- Redlock
- 适合:> 100,000 用户

完整架构图

整体架构

┌─────────────────────────────────────────────────────────────┐
│                         用户层                              │
│  Web 浏览器  │  iOS App  │  Android App  │  小程序         │
└──────────────────────┬──────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                      CDN 层                                 │
│  静态资源  │  图片  │  视频  │  CSS/JS                        │
└──────────────────────┬──────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                    负载均衡层                               │
│           Nginx / HAProxy / AWS ALB                        │
└──────────────────────┬──────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                   应用服务器层 (无状态)                       │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐        │
│  │  实例 1      │  │  实例 2      │  │  实例 3      │  ...  │
│  │  本地缓存    │  │  本地缓存    │  │  本地缓存    │       │
│  │  限流器      │  │  限流器      │  │  限流器      │       │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘        │
└─────────┼────────────────┼────────────────┼──────────────────────┘
          │                │                │
          ▼                ▼                ▼
┌─────────────────────────────────────────────────────────────┐
│                     Redis 集群                              │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                       │
│  │ Redis-1 │  │ Redis-2 │  │ Redis-3 │  Sentinel            │
│  │ 主节点  │  │ 从节点  │  │ 从节点  │  (高可用)            │
│  └────┬────┘  └────┬────┘  └────┬────┘                       │
│       │            │            │                            │
│  ┌───┴────┐      │            │                            │
│  │ 持久化 │      │            │                            │
│  │ RDB    │      │            │                            │
│  │ AOF    │      │            │                            │
│  └────────┘      │            │                            │
│                 │            │                            │
│  ┌──────────────┴────────────────────────────┐            │
│  │         消息队列 (Redis Stream)      │            │
│  │  合并写入  │  Feed 流通知  │  排行榜更新  │            │
│  └────────────────────────────────────────┘            │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                    数据库集群                              │
│  ┌──────────────┐  ┌──────────────┐                        │
│  │  Master      │  │  Slave       │                        │
│  │  (写操作)    │  │  (读操作)    │                        │
│  └──────┬───────┘  └──────┬───────┘                        │
│         │                │                                │
│  ┌──────┴────────────────┴──────┐                        │
│  │  监控 & 备份            │                        │
│  └─────────────────────────┘                        │
└─────────────────────────────────────────────────────────────┘

数据流图

点赞流程:

用户 → 负载均衡 → 应用服务器

1. 检查本地缓存

2. 检查 Redis
  ├─ 命中 → 立即返回
  └─ 未命中 → 查询数据库

3. 更新 Redis 计数器

4. 添加到写回队列

5. 异步写入数据库

6. 发布更新通知

返回给用户

部署架构

生产环境部署:

┌─────────────────────────────────────────────────┐
│  Web 层 (3 节点)                                  │
│  - Nginx (负载均衡)                            │
│  - Web 应用 (6 实例)                            │
│  - 静态资源 (CDN)                               │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  应用层 (可扩展)                                  │
│  - 应用服务器 (3+ 实例)                        │
│  - 每个实例 4 核 8GB                            │
│  - 本地缓存 (100MB)                             │
│  - 连接池管理                                   │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  Redis 层 (主从 + Sentinel)                       │
│  - Master: 2 核 4GB                             │
│  - Slave: 2 核 4GB (2 个)                        │
│  - 持久化: RDB + AOF                            │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│  数据库层 (主从)                                  │
│  - Master: 4 核 8GB                             │
│  - Slave: 4 核 8GB (2 个)                        │
│  - 定期备份                                    │
└─────────────────────────────────────────────────┘

技术选型总结

存储层选择

技术用途原因
MySQL主数据存储事务支持,成熟稳定
Redis缓存/计数高性能,原子操作
Redis Stream消息队列轻量级,持久化

并发控制

方案应用场景
原子更新简单计数
分布式锁关键操作
Lua 脚本复杂原子操作
Redlock分布式锁

性能优化

优化技术效果
Redis 缓存性能提升 100 倍
本地缓存性能提升 10 倍
分片计数性能提升 3 倍
合并写入性能提升 25 倍
Pipeline网络往返减少 10 倍

容量规划

性能指标

目标性能:
- 支持 100 万注册用户
- 支持 10 万日活用户
- 支持 10,000 并发点赞
- 平均响应时间 < 100ms

资源需求:
- Web 服务器:6 实例 × 4 核 8GB = 24 核 48GB
- Redis:3 实例 × 2 核 4GB = 6 核 12GB
- 数据库:1 主 2 从 × 4 核 8GB = 12 核 24GB

总资源:42 核 84GB

存储容量

Redis 存储规划:

点赞计数器:
- 100 万文章 × 100 bytes = 100 MB

点赞用户集合:
- 100 万文章 × 50 个用户 × 8 bytes = 40 GB

用户点赞列表:
- 10 万用户 × 100 篇文章 × 8 bytes = 80 MB

Feed 流数据:
- 10 万用户 × 1000 条记录 × 16 bytes = 1.6 GB

总计:约 42 GB

数据库存储规划:

文章表:100 万 × 1 KB = 1 GB
点赞表:5000 万 × 50 bytes = 2.5 GB
用户表:100 万 × 200 bytes = 200 MB

总计:约 3.7 GB

监控告警

关键指标

业务指标:
- 日活用户数
- 日均点赞数
- 热门文章 Top 10
- 排行榜变化

性能指标:
- 响应时间 (P50, P95, P99)
- QPS (每秒请求数)
- 错误率
- 缓存命中率

资源指标:
- CPU 使用率
- 内存使用率
- 网络流量
- 磁盘 IO

告警规则

严重告警 (立即处理):
- 错误率 > 1%
- P99 响应时间 > 1s
- Redis 宕机
- 数据库主从断开

重要告警 (1 小时内处理):
- 错误率 > 0.5%
- P95 响应时间 > 500ms
- 缓存命中率 < 80%
- 数据库 CPU > 70%

一般告警 (24 小时内处理):
- 缓存命中率 < 90%
- 数据库 CPU > 50%
- 内存使用 > 80%

课后练习

练习 1

如何设计一个支持”多租户”的计数系统?

参考答案(3 个标签)
多租户系统设计架构

方案:数据隔离

方案 1:Redis Key 前缀隔离

tenant:{tenant_id}:article:{article_id}:like_count

优点:
- 实现简单
- 天然隔离

缺点:
- Key 变长
- 管理复杂

方案 2:分片隔离

按 tenant_id 分片到不同的 Redis 实例

优点:
- 完全隔离
- 独立资源

缺点:
- 成本高
- 资源浪费

方案 3:逻辑隔离

同一个 Redis,通过应用层隔离

优点:
- 成本低
- 灵活

缺点:
- 需要严格权限控制

练习 2

如何设计”跨地域”的计数系统?

参考答案(3 个标签)
跨地域系统设计架构

方案:多地域部署

架构:

中国区域:
- 应用服务器 × 3
- Redis 集群 × 1
- 数据库 × 1

美国区域:
- 应用服务器 × 3
- Redis 集群 × 1
- 数据库 × 1

数据同步:
- 主库:中国
- 从库:美国
- 异步复制

挑战:
1. 数据一致性(最终一致)
2. 延迟问题
3. 跨地域查询优化

练习 3

如何实现”降级策略”?

参考答案(3 个标签)
降级高可用系统设计

分级降级策略

练习 4

如何设计”灰度发布”方案?

参考答案(3 个标签)
灰度发布DevOps部署

方案:蓝绿部署

架构:
- 蓝环境:旧版本
- 绿环境:新版本
- 负载均衡:切换流量

流程:
1. 部署新版本到绿环境
2. 新版本自检通过
3. 切换 10% 流量到绿环境
4. 观察 1 小时,无问题
5. 逐步增加流量:25% → 50% → 100%
6. 蓝环境下线
7. 绿环境成为新的蓝环境

练习 5

如何进行”容量规划”?

参考答案(3 个标签)
容量规划性能测试架构设计

容量规划方法

思考题

  1. 如果需要支持”视频点赞”,架构需要如何调整?

  2. 如何设计一个”通用的计数系统”,可以支持多种业务场景?

  3. 如何实现”计数系统”的 A/B 测试?

💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。