在高并发系统中,MySQL 热点数据(如秒杀商品、明星用户等)容易成为性能瓶颈,解决方案之一是通过 二级归集库 + 一致性哈希 进行热点数据的拆分与压力隔离。
1. 什么是热点数据
热点数据指被频繁访问的数据,比如:
● 秒杀/抢购商品的库存信息
● 大 V 用户的信息(粉丝数、浏览量)
● 活动期间的统计数据
这些数据若集中在某个库或某张表上,会导致:
● 主库压力大,读写性能下降
● 锁竞争严重,影响业务流程
● 无法水平扩展
2. 二级归集库(辅库)
概念:
将 热点数据单独归集 到多个库表中,解耦主业务库读写压力。
常见策略:
数据类型 一级库 二级归集库(热点库)
用户表 user_main user_hot_x
(分库分表)
商品表 product_main product_hot_x
评论、点赞 comment_main comment_hot_x
好处:
● 热点数据独立存储
● 可单独加缓存、分库分表、冷热数据拆分
● 降低主库索引压力
3. 一致性哈希 + 分库分表
为什么要一致性哈希
为了将热点数据分布到多个二级库表,一致性哈希 是较优方案(相比取模):
● 新增/减少节点影响较小
● 支持动态扩容
● 支持热点分散(每个热点走不同 hash)
使用方式:
public class ConsistentHash {
private final SortedMap<Integer, String> hashCircle = new TreeMap<>();
private final int VIRTUAL_NODES = 100;
public ConsistentHash(List<String> nodes) {
for (String node : nodes) {
for (int i = 0; i < VIRTUAL_NODES; i++) {
int hash = getHash(node + i);
hashCircle.put(hash, node);
}
}
}
public String getNode(String key) {
int hash = getHash(key);
if (!hashCircle.containsKey(hash)) {
SortedMap<Integer, String> tailMap = hashCircle.tailMap(hash);
hash = tailMap.isEmpty() ? hashCircle.firstKey() : tailMap.firstKey();
}
return hashCircle.get(hash);
}
private int getHash(String key) {
return key.hashCode() & 0x7fffffff;
}
}
示例场景:
将大 V 用户按 userId 路由到如下热点表:
user_hot_0
user_hot_1
user_hot_2
…
user_hot_n
4. 系统架构图(示意)
请求层
↓
一致性哈希路由
↓
±-----------+
| |
user_hot_0 user_hot_1 … user_hot_n (热点库,读写均衡)
↑ ↑
| |
±—> 缓存(如 Redis、Guava)
5. 热点写操作流程(举例:点赞)
- 客户端点赞接口调用
- 根据 userId 一致性哈希定位表 like_hot_3
- 更新 like_hot_3 表中记录
- 同步更新缓存 user🔢likeCount
- 主库异步归并(如夜间定时同步热点数据回主库)
- 冷热数据归档策略(定时任务)
// 定时任务将热点库数据同步回主库
@Scheduled(cron = "0 0 3 * * ?")
public void syncHotDataToMain() {
for (int i = 0; i < N; i++) {
String tableName = "user_hot_" + i;
List<HotUserData> data = hotRepo.findAll(tableName);
mainRepo.batchMerge(data);
hotRepo.clear(tableName);
}
}
7. 优势总结
技术 优势
二级归集库 热点数据独立处理,减少主库压力
一致性哈希 分布均衡、支持扩容
缓存前置(Redis) 快速响应热点请求,减轻 DB 压力
异步归档 实现主数据和热点数据的最终一致性
8. 场景拓展
● 电商:SKU 库存、订单状态
● 社交:用户热度、评论点赞
● 视频平台:视频浏览数、弹幕量
● 大数据采集:热点设备/热点区域采样频繁
604

被折叠的 条评论
为什么被折叠?



