分片计数

新的瓶颈

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< 10MB5 ~ 10
中并发1000 ~ 1000010MB ~ 100MB10 ~ 20
高并发10000 ~ 50000100MB ~ 500MB20 ~ 50
超高并发> 50000> 500MB50 ~ 100

练习 3

分片计数器如何支持”点赞用户列表”功能?

参考答案(3 个标签)
Redis分片数据结构

方案:点赞集合也分片

练习 4

分片计数器如何支持”排行榜”功能?

参考答案(3 个标签)
Redis分片排行榜

方案:使用 ZSET 分片

练习 5

分片计数器如何实现”数据迁移”?

参考答案(3 个标签)
数据迁移分片运维

场景:增加分片数量

当前:10 个 shard
目标:20 个 shard

问题:如何迁移数据?

方案:在线迁移

思考题

  1. 如果分片数选择不当,会有什么问题?

  2. 如何实现”动态分片”,根据负载自动调整分片数量?

  3. 分片计数器在分布式环境下如何保证一致性?

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