超大 hash 怎么分桶拆分
超大哈希的拆分方式是按取模分桶:把字段散列到 N 个子哈希(如 user:tag:1001:0 到 user:tag:1001:N-1),单字段操作仍然是常数时间,但单键规模被限制在可控范围。分桶后还便于分批迁移,字段数量较少时也更容易命中紧凑编码,进一步降低内存。
基本信息
| 分桶键 | biz:key:<id>:<shard> |
|---|---|
| 桶数 | 按单桶目标元素量反推 |
| 分桶函数 | 客户端用固定哈希取模,必须保持稳定 |
| 收益 | 缩小单键、控制单次操作规模 |
| 代价 | 键数量与相关开销增加,读取前要先算桶 |
拆分前后的差异
| 维度 | 单一大哈希 | 分桶后 |
|---|---|---|
| 单键规模 | 随字段数线性增长 | 限制在单桶目标量以内 |
| 读单字段 | 一次 HGET | 先算桶再 HGET,多一步计算 |
| 全量读取 | HGETALL 一次返回全部 | 需遍历所有桶再合并 |
| 迁移与扩容 | 整键搬迁,成本集中 | 可按桶分批迁移 |
| 内存开销 | 键与结构开销最小 | 键数量增加,字典与过期表开销上升 |
示例
示例
HSET user:tag:1001:3 tag:88 1 # 按分桶写入
HGET user:tag:1001:3 tag:88
HLEN user:tag:1001:3 # 核对单桶元素量
redis-cli --scan --pattern 'user:tag:1001:*' | wc -l # 核对桶数量
redis-cli MEMORY USAGE user:tag:1001:3 # 对比拆分前后单键开销典型使用场景
- 大哈希治理:把单键元素量压到可控范围
- 分批迁移:按桶逐步搬迁,降低单次操作影响
- 命中紧凑编码:元素少的结构更容易使用紧凑编码
- 控制单次操作规模:避免一次读写返回过多字段
- 集群倾斜处理:把热点键拆开,缓解单槽压力
查询需要先算桶再落到具体键,务必在客户端封装统一入口,避免分桶逻辑散落在各处业务代码里。
桶数通常在个位到十几之间,先按单桶目标元素量估算,再用实测内存与延迟做微调。
分桶函数一旦上线必须保持稳定:变更分片规则等于全量数据迁移,需要双写与数据校验方案配套。