这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
分片计数
新的瓶颈
Redis 方案上线后,系统运行良好。
直到有一天,平台推出了一位知名作者的新文章。
数据飙升:
文章发布时间:20:00
发布后 1 小时:50000 阅读,5000 点赞
发布后 2 小时:100000 阅读,12000 点赞
发布后 3 小时:200000 阅读,25000 点赞
峰值:每秒约 100 个点赞请求!
系统监控:
Redis 状态:
- CPU:45%
- 内存:正常
- QPS:约 8000
单个热门文章:
- article:123:like_count
- 每秒 INCR 操作:约 100 次
- 单 key 竞争严重
虽然 Redis 能扛住,但单个 key 的竞争太严重了!
问题分析
场景:爆款文章
问题:
1. 所有用户点赞同一篇文章
2. 都在操作同一个 Redis key
3. 单个 Redis 实例成为瓶颈
影响:
- 单 key 访问频率高
- 可能导致热 key 问题
- 分布式锁竞争
解决方案:分片计数(Sharded Counter)
分片计数原理
核心思想:
- 将计数器分散到多个 key
- 每个 shard 独立计数
- 查询时合并所有 shard 的值
示意图:
原来:
article:123:like_count = 1000
分片后:
article:123:like_count:0 = 250
article:123:like_count:1 = 250
article:123:like_count:2 = 250
article:123:like_count:3 = 250
总计:1000
实现方案
基础实现
优化:动态分片数量
性能对比
实际效果
性能提升
场景:爆款文章,每秒 100 次点赞
不分片:
- 单 key 竞争严重
- Redis CPU:45%
- 响应时间:波动较大
分片(10 个 shard):
- 分散到 10 个 key
- Redis CPU:15%
- 响应时间:稳定
提升:
- 性能提升 3 倍
- 响应时间更稳定
课后练习
练习 1
分片计数器如何保证数据一致性?
参考答案(3 个标签)
Redis分片一致性
问题分析:
场景:用户点赞
分片后:
- 用户 A 的点赞记录在 shard 0
- 用户 B 的点赞记录在 shard 1
- ...
查询总数:
- 需要合并所有 shard
- 可能存在时间窗口不一致
示例:
T1: 查询 shard 0 → 100
T2: 查询 shard 1 → 100
T3: 用户点赞 shard 0 → 101
T4: 查询 shard 2 → 100
...
T10: 用户点赞 shard 1 → 101
合并结果:
- shard 0: 101(新值)
- shard 1: 100(旧值)
- shard 2: 100
- ...
总计:1001(不准确!)解决方案:
方案 1:使用 Pipeline 原子查询
方案 2:定期合并
方案 3:使用 Lua 脚本
原子操作要点
- 这里关注的是把读取、判断和更新合成一个不可打断的状态变化,而不是记住脚本语法。
练习 2
如何选择合适的分片数量?
参考答案(3 个标签)
分片性能优化架构设计
分片数量选择原则:
因素 1:并发量
- 并发量越大,分片数越多
- 每个 shard 理想 QPS:1000 ~ 5000
因素 2:数据量
- 数据量越大,分片数越多
- 每个 shard 理想数据量:10MB ~ 100MB
因素 3:查询性能
- 分片数越多,查询越慢(需要合并)
- 需要平衡读写性能
因素 4:运维成本
- 分片数越多,运维越复杂计算公式:
建议值:
| 场景 | QPS | 数据量 | 推荐分片数 |
|---|---|---|---|
| 低并发 | < 1000 | < 10MB | 5 ~ 10 |
| 中并发 | 1000 ~ 10000 | 10MB ~ 100MB | 10 ~ 20 |
| 高并发 | 10000 ~ 50000 | 100MB ~ 500MB | 20 ~ 50 |
| 超高并发 | > 50000 | > 500MB | 50 ~ 100 |
练习 3
分片计数器如何支持”点赞用户列表”功能?
参考答案(3 个标签)
Redis分片数据结构
方案:点赞集合也分片
练习 4
分片计数器如何支持”排行榜”功能?
参考答案(3 个标签)
Redis分片排行榜
方案:使用 ZSET 分片
练习 5
分片计数器如何实现”数据迁移”?
参考答案(3 个标签)
数据迁移分片运维
场景:增加分片数量
当前:10 个 shard
目标:20 个 shard
问题:如何迁移数据?方案:在线迁移
思考题
-
如果分片数选择不当,会有什么问题?
-
如何实现”动态分片”,根据负载自动调整分片数量?
-
分片计数器在分布式环境下如何保证一致性?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
